import { __awaiter, __generator } from "tslib";
import * as loader from '../../../lib/load-script';
import { remoteLoader } from '..';
var pluginFactory = jest.fn();
describe('Remote Loader', function () {
    var window = global.window;
    beforeEach(function () {
        jest.resetAllMocks();
        jest.spyOn(console, 'warn').mockImplementation();
        // @ts-expect-error skipping the actual script injection part
        jest.spyOn(loader, 'loadScript').mockImplementation(function () {
            window.testPlugin = pluginFactory;
            return Promise.resolve(true);
        });
    });
    it('should attempt to load a script from the url of each remotePlugin', function () { return __awaiter(void 0, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, remoteLoader({
                        integrations: {},
                        remotePlugins: [
                            {
                                url: 'cdn/path/to/file.js',
                                libraryName: 'testPlugin',
                                settings: {},
                            },
                        ],
                    })];
                case 1:
                    _a.sent();
                    expect(loader.loadScript).toHaveBeenCalledWith('cdn/path/to/file.js');
                    return [2 /*return*/];
            }
        });
    }); });
    it('should attempt calling the library', function () { return __awaiter(void 0, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, remoteLoader({
                        integrations: {},
                        remotePlugins: [
                            {
                                url: 'cdn/path/to/file.js',
                                libraryName: 'testPlugin',
                                settings: {
                                    name: 'Charlie Brown',
                                },
                            },
                        ],
                    })];
                case 1:
                    _a.sent();
                    expect(pluginFactory).toHaveBeenCalledTimes(1);
                    expect(pluginFactory).toHaveBeenCalledWith(expect.objectContaining({
                        name: 'Charlie Brown',
                    }));
                    return [2 /*return*/];
            }
        });
    }); });
    it('should skip remote plugins that arent callable functions', function () { return __awaiter(void 0, void 0, void 0, function () {
        var plugins;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, remoteLoader({
                        integrations: {},
                        remotePlugins: [
                            {
                                url: 'cdn/path/to/file.js',
                                libraryName: 'this wont resolve',
                                settings: {},
                            },
                        ],
                    })];
                case 1:
                    plugins = _a.sent();
                    expect(pluginFactory).not.toHaveBeenCalled();
                    expect(plugins).toHaveLength(0);
                    return [2 /*return*/];
            }
        });
    }); });
    it('should return all plugins resolved remotely', function () { return __awaiter(void 0, void 0, void 0, function () {
        var one, two, three, multiPluginFactory, singlePluginFactory, plugins;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    one = {
                        name: 'one',
                        version: '1.0.0',
                        type: 'before',
                        load: function () { },
                        isLoaded: function () { return true; },
                    };
                    two = {
                        name: 'two',
                        version: '1.0.0',
                        type: 'before',
                        load: function () { },
                        isLoaded: function () { return true; },
                    };
                    three = {
                        name: 'three',
                        version: '1.0.0',
                        type: 'enrichment',
                        load: function () { },
                        isLoaded: function () { return true; },
                    };
                    multiPluginFactory = jest.fn().mockImplementation(function () { return [one, two]; });
                    singlePluginFactory = jest.fn().mockImplementation(function () { return three; });
                    // @ts-expect-error not gonna return a script tag sorry
                    jest.spyOn(loader, 'loadScript').mockImplementation(function (url) {
                        if (url === 'multiple-plugins.js') {
                            window['multiple-plugins'] = multiPluginFactory;
                        }
                        else {
                            window['single-plugin'] = singlePluginFactory;
                        }
                        return Promise.resolve(true);
                    });
                    return [4 /*yield*/, remoteLoader({
                            integrations: {},
                            remotePlugins: [
                                {
                                    url: 'multiple-plugins.js',
                                    libraryName: 'multiple-plugins',
                                    settings: { foo: true },
                                },
                                {
                                    url: 'single-plugin.js',
                                    libraryName: 'single-plugin',
                                    settings: { bar: false },
                                },
                            ],
                        })];
                case 1:
                    plugins = _a.sent();
                    expect(plugins).toHaveLength(3);
                    expect(plugins).toEqual(expect.arrayContaining([one, two, three]));
                    expect(multiPluginFactory).toHaveBeenCalledWith({ foo: true });
                    expect(singlePluginFactory).toHaveBeenCalledWith({ bar: false });
                    return [2 /*return*/];
            }
        });
    }); });
    it('should ignore plugins that fail to initialize', function () { return __awaiter(void 0, void 0, void 0, function () {
        var plugins;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    // @ts-expect-error not gonna return a script tag sorry
                    jest.spyOn(loader, 'loadScript').mockImplementation(function (url) {
                        window['flaky'] = function () {
                            throw Error('aaay');
                        };
                        window['asyncFlaky'] = function () { return __awaiter(void 0, void 0, void 0, function () {
                            return __generator(this, function (_a) {
                                throw Error('aaay');
                            });
                        }); };
                        return Promise.resolve(true);
                    });
                    return [4 /*yield*/, remoteLoader({
                            integrations: {},
                            remotePlugins: [
                                {
                                    url: 'cdn/path/to/flaky.js',
                                    libraryName: 'flaky',
                                    settings: {},
                                },
                                {
                                    url: 'cdn/path/to/asyncFlaky.js',
                                    libraryName: 'asyncFlaky',
                                    settings: {},
                                },
                            ],
                        })];
                case 1:
                    plugins = _a.sent();
                    expect(pluginFactory).not.toHaveBeenCalled();
                    expect(plugins).toHaveLength(0);
                    expect(console.warn).toHaveBeenCalledTimes(2);
                    return [2 /*return*/];
            }
        });
    }); });
    it('ignores invalid plugins', function () { return __awaiter(void 0, void 0, void 0, function () {
        var invalidPlugin, validPlugin, plugins;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    invalidPlugin = {
                        name: 'invalid',
                        version: '1.0.0',
                    };
                    validPlugin = {
                        name: 'valid',
                        version: '1.0.0',
                        type: 'enrichment',
                        load: function () { },
                        isLoaded: function () { return true; },
                    };
                    // @ts-expect-error not gonna return a script tag sorry
                    jest.spyOn(loader, 'loadScript').mockImplementation(function (url) {
                        if (url === 'valid') {
                            window['valid'] = jest.fn().mockImplementation(function () { return validPlugin; });
                        }
                        else {
                            window['invalid'] = jest.fn().mockImplementation(function () { return invalidPlugin; });
                        }
                        return Promise.resolve(true);
                    });
                    return [4 /*yield*/, remoteLoader({
                            integrations: {},
                            remotePlugins: [
                                {
                                    url: 'valid',
                                    libraryName: 'valid',
                                    settings: { foo: true },
                                },
                                {
                                    url: 'invalid',
                                    libraryName: 'invalid',
                                    settings: { bar: false },
                                },
                            ],
                        })];
                case 1:
                    plugins = _a.sent();
                    expect(plugins).toHaveLength(1);
                    expect(plugins).toEqual(expect.arrayContaining([validPlugin]));
                    expect(console.warn).toHaveBeenCalledTimes(1);
                    return [2 /*return*/];
            }
        });
    }); });
});
//# sourceMappingURL=index.test.js.map