import { __assign, __awaiter, __generator } from "tslib";
import assert from 'assert';
import cookie from 'js-cookie';
import { normalize } from '../normalize';
import { Analytics } from '../../../analytics';
import { JSDOM } from 'jsdom';
describe('before loading', function () {
    var jsdom;
    beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
        var html, windowSpy;
        return __generator(this, function (_a) {
            jest.restoreAllMocks();
            jest.resetAllMocks();
            html = "\n    <!DOCTYPE html>\n      <head></head>\n      <body></body>\n    </html>\n    ".trim();
            jsdom = new JSDOM(html, {
                runScripts: 'dangerously',
                resources: 'usable',
                url: 'https://localhost',
            });
            windowSpy = jest.spyOn(global, 'window', 'get');
            windowSpy.mockImplementation(function () { return jsdom.window; });
            return [2 /*return*/];
        });
    }); });
    var options;
    var analytics;
    beforeEach(function () {
        options = { apiKey: 'oq0vdlg7yi' };
        analytics = new Analytics({ writeKey: options.apiKey });
        window.localStorage.clear();
    });
    afterEach(function () {
        analytics.reset();
        Object.keys(cookie.get()).map(function (k) { return cookie.remove(k); });
        if (window.localStorage) {
            window.localStorage.clear();
        }
    });
    describe('#normalize', function () {
        var object;
        beforeEach(function () {
            cookie.remove('s:context.referrer');
            object = {
                type: 'track',
            };
        });
        it('should add .anonymousId', function () {
            analytics.user().anonymousId('anon-id');
            normalize(analytics, object, options, {});
            assert(object.anonymousId === 'anon-id');
        });
        it('should add .sentAt', function () {
            normalize(analytics, object, options, {});
            assert(object.sentAt);
            // assert(type(object.sentAt) === 'date')
        });
        it('should add .userId', function () {
            analytics.user().id('user-id');
            normalize(analytics, object, options, {});
            assert(object.userId === 'user-id');
        });
        it('should not replace the .userId', function () {
            analytics.user().id('user-id');
            object.userId = 'existing-id';
            normalize(analytics, object, options, {});
            assert(object.userId === 'existing-id');
        });
        it('should always add .anonymousId even if .userId is given', function () {
            var _a;
            var object = { userId: 'baz', type: 'track' };
            normalize(analytics, object, options, {});
            assert(((_a = object.anonymousId) === null || _a === void 0 ? void 0 : _a.length) === 36);
        });
        it('should add .context', function () {
            normalize(analytics, object, options, {});
            assert(object.context);
        });
        it('should not rewrite context if provided', function () {
            var ctx = {};
            var obj = __assign(__assign({}, object), { context: ctx });
            normalize(analytics, obj, options, {});
            expect(obj.context).toEqual(ctx);
        });
        it('should copy .options to .context', function () {
            var opts = {};
            var obj = __assign(__assign({}, object), { options: opts });
            normalize(analytics, obj, options, {});
            assert(obj.context === opts);
            assert(obj.options == null);
        });
        it('should add .writeKey', function () {
            normalize(analytics, object, options, {});
            assert(object.writeKey === options.apiKey);
        });
        it('should add .library', function () {
            var _a, _b, _c;
            normalize(analytics, object, options, {});
            assert((_a = object.context) === null || _a === void 0 ? void 0 : _a.library);
            assert(((_b = object.context) === null || _b === void 0 ? void 0 : _b.library.name) === 'analytics.js');
            assert(((_c = object.context) === null || _c === void 0 ? void 0 : _c.library.version) === "next-" + process.env.VERSION);
        });
        it('should allow override of .library', function () {
            var _a, _b, _c;
            var ctx = {
                library: {
                    name: 'analytics-wordpress',
                    version: '1.0.3',
                },
            };
            var obj = __assign(__assign({}, object), { context: ctx });
            normalize(analytics, obj, options, {});
            assert((_a = obj.context) === null || _a === void 0 ? void 0 : _a.library);
            assert(((_b = obj.context) === null || _b === void 0 ? void 0 : _b.library.name) === 'analytics-wordpress');
            assert(((_c = obj.context) === null || _c === void 0 ? void 0 : _c.library.version) === '1.0.3');
        });
        it('should add .userAgent', function () {
            var _a;
            normalize(analytics, object, options, {});
            assert(((_a = object.context) === null || _a === void 0 ? void 0 : _a.userAgent) === navigator.userAgent);
        });
        it('should add .locale', function () {
            var _a;
            normalize(analytics, object, options, {});
            assert(((_a = object.context) === null || _a === void 0 ? void 0 : _a.locale) === navigator.language);
        });
        it('should not replace .locale if provided', function () {
            var _a;
            var ctx = {
                locale: 'foobar',
            };
            var obj = __assign(__assign({}, object), { context: ctx });
            normalize(analytics, obj, options, {});
            assert(((_a = obj.context) === null || _a === void 0 ? void 0 : _a.locale) === 'foobar');
        });
        it('should add .campaign', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=source&utm_medium=medium&utm_term=term&utm_content=content&utm_campaign=name',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.campaign);
            assert(object.context.campaign.source === 'source');
            assert(object.context.campaign.medium === 'medium');
            assert(object.context.campaign.term === 'term');
            assert(object.context.campaign.content === 'content');
            assert(object.context.campaign.name === 'name');
        });
        it('should decode query params', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=%5BFoo%5D',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.campaign);
            assert(object.context.campaign.source === '[Foo]');
        });
        it('should guard against undefined utm params', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.campaign);
            assert(object.context.campaign.source === '');
        });
        it('should guard against empty utm params', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.campaign);
            assert(object.context.campaign.source === '');
        });
        it('only parses utm params suffixed with _', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert.deepStrictEqual(object.context.campaign, {});
        });
        it('should guard against short utm params', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert.deepStrictEqual(object.context.campaign, {});
        });
        it('should allow override of .campaign', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=source&utm_medium=medium&utm_term=term&utm_content=content&utm_campaign=name',
            });
            var obj = __assign(__assign({}, object), { context: {
                    campaign: {
                        source: 'overrideSource',
                        medium: 'overrideMedium',
                        term: 'overrideTerm',
                        content: 'overrideContent',
                        name: 'overrideName',
                    },
                } });
            normalize(analytics, obj, options, {});
            assert(obj);
            assert(obj.context);
            assert(obj.context.campaign);
            assert(obj.context.campaign.source === 'overrideSource');
            assert(obj.context.campaign.medium === 'overrideMedium');
            assert(obj.context.campaign.term === 'overrideTerm');
            assert(obj.context.campaign.content === 'overrideContent');
            assert(obj.context.campaign.name === 'overrideName');
        });
        it('should add .referrer.id and .referrer.type', function () {
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=source&urid=medium',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.referrer);
            expect(object.context.referrer.id).toEqual('medium');
            assert(object.context.referrer.type === 'millennial-media');
        });
        it('should add .referrer.id and .referrer.type from cookie', function () {
            cookie.set('s:context.referrer', '{"id":"baz","type":"millennial-media"}');
            jsdom.reconfigure({
                url: 'http://localhost?utm_source=source',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.referrer);
            assert(object.context.referrer.id === 'baz');
            assert(object.context.referrer.type === 'millennial-media');
        });
        it('should add .referrer.id and .referrer.type from cookie when no query is given', function () {
            cookie.set('s:context.referrer', '{"id":"medium","type":"millennial-media"}');
            jsdom.reconfigure({
                url: 'http://localhost',
            });
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.referrer);
            assert(object.context.referrer.id === 'medium');
            assert(object.context.referrer.type === 'millennial-media');
        });
        it('shouldnt add non amp ga cookie', function () {
            cookie.set('_ga', 'some-nonamp-id');
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(!object.context.amp);
        });
        it('should add .amp.id from store', function () {
            cookie.set('_ga', 'amp-foo');
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(object.context.amp);
            assert(object.context.amp.id === 'amp-foo');
        });
        it('should not add .amp if theres no _ga', function () {
            cookie.remove('_ga');
            normalize(analytics, object, options, {});
            assert(object);
            assert(object.context);
            assert(!object.context.amp);
        });
        describe('failed initializations', function () {
            it.skip('should add failedInitializations as part of _metadata object if this.analytics.failedInitilizations is not empty', function () { });
        });
        describe('unbundling', function () {
            it('should add a list of bundled integrations', function () {
                normalize(analytics, object, options, {
                    'Segment.io': {},
                    other: {
                        bundlingStatus: 'bundled',
                    },
                });
                assert(object);
                assert(object._metadata);
                assert.deepEqual(object._metadata.bundled, ['Segment.io', 'other']);
            });
            it('should add a list of bundled ids', function () {
                normalize(analytics, object, __assign(__assign({}, options), { maybeBundledConfigIds: {
                        other: ['o_123', 'o_456'],
                    } }), {
                    'Segment.io': {},
                    other: {
                        bundlingStatus: 'bundled',
                    },
                });
                assert(object);
                assert(object._metadata);
                assert.deepEqual(object._metadata.bundledIds, ['o_123', 'o_456']);
            });
            it('should add a list of unbundled integrations when `unbundledIntegrations` is set', function () {
                options.unbundledIntegrations = ['other2'];
                normalize(analytics, object, options, {
                    other2: {
                        bundlingStatus: 'unbundled',
                    },
                });
                assert(object);
                assert(object._metadata);
                assert.deepEqual(object._metadata.unbundled, ['other2']);
            });
        });
        it('should pick up messageId from AJS', function () {
            normalize(analytics, object, options, {}); // ajs core generates the message ID here
            var messageId = object.messageId;
            normalize(analytics, object, options, {});
            assert.equal(object.messageId, messageId);
        });
    });
});
//# sourceMappingURL=normalize.test.js.map