import { __awaiter, __generator } from "tslib";
import jsdom, { JSDOM } from 'jsdom';
import { mocked } from 'ts-jest/utils';
import unfetch from 'unfetch';
import { onCSPError } from '../lib/csp-detection';
import { pWhile } from '../lib/p-while';
import { snippet } from '../tester/__fixtures__/segment-snippet';
var cdnResponse = {
    integrations: {
        Zapier: {
            type: 'server',
        },
        'Amazon S3': {},
        Amplitude: {
            type: 'browser',
        },
        Segmentio: {
            type: 'browser',
        },
        Iterable: {
            type: 'browser',
            name: 'Iterable',
        },
    },
};
var fetchSettings = Promise.resolve({
    json: function () { return Promise.resolve(cdnResponse); },
});
jest.mock('unfetch', function () {
    return jest.fn();
});
describe('CSP Detection', function () {
    var segmentDotCom = "zaySL4FGIiLsxt3I7omU5uLxXqxaBMPh";
    var jsd;
    var windowSpy;
    var documentSpy;
    var getClassic = function () {
        return Array.from(document.scripts).find(function (s) { var _a; return (_a = s.getAttribute('src')) === null || _a === void 0 ? void 0 : _a.includes('classic'); });
    };
    beforeEach(function () {
        jest.restoreAllMocks();
        jest.resetAllMocks();
        jest.spyOn(console, 'warn').mockImplementationOnce(function () { });
        // @ts-ignore ignore Response required fields
        mocked(unfetch).mockImplementation(function () { return fetchSettings; });
        var html = ("\n    <!DOCTYPE html>\n      <head>\n        <script>\n          " + snippet(segmentDotCom, true) + "\n        </script>\n      </head>\n      <body>\n      </body>\n    </html>\n    ").trim();
        var virtualConsole = new jsdom.VirtualConsole();
        jsd = new JSDOM(html, {
            runScripts: 'dangerously',
            resources: 'usable',
            url: 'https://segment.com',
            virtualConsole: virtualConsole,
        });
        windowSpy = jest.spyOn(global, 'window', 'get');
        documentSpy = jest.spyOn(global, 'document', 'get');
        jest.spyOn(console, 'warn').mockImplementationOnce(function () { });
        windowSpy.mockImplementation(function () {
            return jsd.window;
        });
        documentSpy.mockImplementation(function () { return jsd.window.document; });
    });
    it('reverts to ajs classic in case of CSP errors', function () { return __awaiter(void 0, void 0, void 0, function () {
        var handlers;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    jest.spyOn(console, 'error').mockImplementationOnce(function () { });
                    handlers = {};
                    jest
                        .spyOn(global.document, 'addEventListener')
                        .mockImplementationOnce(function (e, handler) {
                        handlers[e] = (handlers[e] || []).concat(handler);
                    });
                    return [4 /*yield*/, import('../standalone')];
                case 1:
                    _a.sent();
                    handlers['securitypolicyviolation'].forEach(function (handler) {
                        handler({
                            // @ts-ignore
                            blockedURI: 'cdn.segment.com',
                        });
                    });
                    return [4 /*yield*/, pWhile(function () { return getClassic() === undefined; }, function () { })];
                case 2:
                    _a.sent();
                    expect(getClassic()).toMatchInlineSnapshot("\n      <script\n        src=\"https://cdn.foo.com/analytics.js/v1/zaySL4FGIiLsxt3I7omU5uLxXqxaBMPh/analytics.classic.js\"\n        status=\"loading\"\n        type=\"text/javascript\"\n      />\n    ");
                    return [2 /*return*/];
            }
        });
    }); });
    it('does not revert to classic when CSP error is report only', function () { return __awaiter(void 0, void 0, void 0, function () {
        var ogScripts, warnSpy;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    ogScripts = Array.from(document.scripts);
                    warnSpy = jest.spyOn(console, 'warn');
                    return [4 /*yield*/, onCSPError({
                            blockedURI: 'cdn.segment.com',
                            disposition: 'report',
                        })];
                case 1:
                    _a.sent();
                    expect(warnSpy).not.toHaveBeenCalled();
                    expect(Array.from(document.scripts)).toEqual(ogScripts);
                    return [2 /*return*/];
            }
        });
    }); });
});
//# sourceMappingURL=csp-detection.test.js.map