import { __awaiter, __generator } from "tslib";
var fetch = jest.fn();
jest.mock('unfetch', function () {
    return fetch;
});
import batch from '../batched-dispatcher';
var fatEvent = {
    _id: '609c0e91fe97b680e384d6e4',
    index: 5,
    guid: 'ca7fac24-41c9-45db-bc53-59b544e43943',
    isActive: false,
    balance: '$2,603.43',
    picture: 'http://placehold.it/32x32',
    age: 36,
    eyeColor: 'blue',
    name: 'Myers Hoover',
    gender: 'male',
    company: 'SILODYNE',
    email: 'myershoover@silodyne.com',
    phone: '+1 (986) 580-3562',
    address: '240 Ryder Avenue, Belva, Nebraska, 929',
    about: 'Non eu nulla exercitation consectetur reprehenderit culpa mollit non consectetur magna tempor. Do et duis occaecat eu culpa dolor elit et est pariatur qui. Veniam dolore amet minim veniam quis esse. Aute commodo sint officia velit dolor. Sit enim nisi eu exercitation dolore nulla dolor occaecat. Sunt eu pariatur reprehenderit ipsum et nulla cillum culpa ea.\r\n',
    registered: '2019-04-13T09:29:21 +05:00',
    latitude: 68.879515,
    longitude: -46.670697,
    tags: ['magna', 'ex', 'nostrud', 'mollit', 'laborum', 'exercitation', 'sit'],
    friends: [
        {
            id: 0,
            name: 'Lynn Brock',
        },
        {
            id: 1,
            name: 'May Hull',
        },
        {
            id: 2,
            name: 'Elena Henderson',
        },
    ],
    greeting: 'Hello, Myers Hoover! You have 5 unread messages.',
    favoriteFruit: 'strawberry',
};
describe('Batching', function () {
    beforeEach(function () {
        jest.resetAllMocks();
        jest.restoreAllMocks();
    });
    afterEach(function () {
        window.close();
    });
    it('does not send requests right away', function () { return __awaiter(void 0, void 0, void 0, function () {
        var dispatch;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    dispatch = batch("https://api.segment.io").dispatch;
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            hello: 'world',
                        })];
                case 1:
                    _a.sent();
                    expect(fetch).not.toHaveBeenCalled();
                    return [2 /*return*/];
            }
        });
    }); });
    it('sends requests after a batch limit is hit', function () { return __awaiter(void 0, void 0, void 0, function () {
        var dispatch;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    dispatch = batch("https://api.segment.io", {
                        size: 3,
                    }).dispatch;
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'first',
                        })];
                case 1:
                    _a.sent();
                    expect(fetch).not.toHaveBeenCalled();
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'second',
                        })];
                case 2:
                    _a.sent();
                    expect(fetch).not.toHaveBeenCalled();
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'third',
                        })];
                case 3:
                    _a.sent();
                    expect(fetch).toHaveBeenCalledTimes(1);
                    expect(fetch.mock.calls[0]).toMatchInlineSnapshot("\n      Array [\n        \"https://https://api.segment.io/batch\",\n        Object {\n          \"body\": \"{\\\"batch\\\":[{\\\"event\\\":\\\"first\\\"},{\\\"event\\\":\\\"second\\\"},{\\\"event\\\":\\\"third\\\"}]}\",\n          \"headers\": Object {\n            \"Authorization\": \"Basic dW5kZWZpbmVkOg==\",\n            \"Content-Type\": \"application/json\",\n          },\n          \"method\": \"post\",\n        },\n      ]\n    ");
                    return [2 /*return*/];
            }
        });
    }); });
    it('sends requests if the size of events exceeds tracking API limits', function () { return __awaiter(void 0, void 0, void 0, function () {
        var dispatch, i, i;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    dispatch = batch("https://api.segment.io", {
                        size: 600,
                    }).dispatch;
                    i = 0;
                    _a.label = 1;
                case 1:
                    if (!(i < 250)) return [3 /*break*/, 4];
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'fat event',
                            properties: fatEvent,
                        })];
                case 2:
                    _a.sent();
                    _a.label = 3;
                case 3:
                    i++;
                    return [3 /*break*/, 1];
                case 4:
                    expect(fetch).not.toHaveBeenCalled();
                    i = 0;
                    _a.label = 5;
                case 5:
                    if (!(i < 250)) return [3 /*break*/, 8];
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'fat event',
                            properties: fatEvent,
                        })];
                case 6:
                    _a.sent();
                    _a.label = 7;
                case 7:
                    i++;
                    return [3 /*break*/, 5];
                case 8:
                    // still called, even though our batch limit is 600 events
                    expect(fetch).toHaveBeenCalledTimes(1);
                    return [2 /*return*/];
            }
        });
    }); });
    it('sends requests when the timeout expires', function () { return __awaiter(void 0, void 0, void 0, function () {
        var dispatch;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    jest.useFakeTimers();
                    dispatch = batch("https://api.segment.io", {
                        size: 100,
                        timeout: 10000,
                    }).dispatch;
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'first',
                        })];
                case 1:
                    _a.sent();
                    expect(fetch).not.toHaveBeenCalled();
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/i", {
                            event: 'second',
                        })];
                case 2:
                    _a.sent();
                    jest.advanceTimersByTime(11000); // 11 seconds
                    expect(fetch).toHaveBeenCalledTimes(1);
                    expect(fetch.mock.calls[0]).toMatchInlineSnapshot("\n      Array [\n        \"https://https://api.segment.io/batch\",\n        Object {\n          \"body\": \"{\\\"batch\\\":[{\\\"event\\\":\\\"first\\\"},{\\\"event\\\":\\\"second\\\"}]}\",\n          \"headers\": Object {\n            \"Authorization\": \"Basic dW5kZWZpbmVkOg==\",\n            \"Content-Type\": \"application/json\",\n          },\n          \"method\": \"post\",\n        },\n      ]\n    ");
                    return [2 /*return*/];
            }
        });
    }); });
    it('clears the buffer between flushes', function () { return __awaiter(void 0, void 0, void 0, function () {
        var dispatch;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    jest.useFakeTimers();
                    dispatch = batch("https://api.segment.io", {
                        size: 100,
                        timeout: 10000,
                    }).dispatch;
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                            event: 'first',
                        })];
                case 1:
                    _a.sent();
                    jest.advanceTimersByTime(11000); // 11 seconds
                    return [4 /*yield*/, dispatch("https://api.segment.io/v1/i", {
                            event: 'second',
                        })];
                case 2:
                    _a.sent();
                    jest.advanceTimersByTime(11000); // 11 seconds
                    expect(fetch).toHaveBeenCalledTimes(2);
                    expect(fetch.mock.calls[0]).toMatchInlineSnapshot("\n      Array [\n        \"https://https://api.segment.io/batch\",\n        Object {\n          \"body\": \"{\\\"batch\\\":[{\\\"event\\\":\\\"first\\\"}]}\",\n          \"headers\": Object {\n            \"Authorization\": \"Basic dW5kZWZpbmVkOg==\",\n            \"Content-Type\": \"application/json\",\n          },\n          \"method\": \"post\",\n        },\n      ]\n    ");
                    expect(fetch.mock.calls[1]).toMatchInlineSnapshot("\n      Array [\n        \"https://https://api.segment.io/batch\",\n        Object {\n          \"body\": \"{\\\"batch\\\":[{\\\"event\\\":\\\"second\\\"}]}\",\n          \"headers\": Object {\n            \"Authorization\": \"Basic dW5kZWZpbmVkOg==\",\n            \"Content-Type\": \"application/json\",\n          },\n          \"method\": \"post\",\n        },\n      ]\n    ");
                    return [2 /*return*/];
            }
        });
    }); });
    describe('on unload', function () {
        var unloadHandler = undefined;
        beforeEach(function () {
            jest
                .spyOn(window, 'addEventListener')
                .mockImplementation(function (evt, handler) {
                if (evt === 'beforeunload') {
                    unloadHandler = handler;
                }
            });
        });
        it('flushes the batch', function () { return __awaiter(void 0, void 0, void 0, function () {
            var dispatch;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        dispatch = batch("https://api.segment.io").dispatch;
                        return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                                hello: 'world',
                            })];
                    case 1:
                        _a.sent();
                        return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                                bye: 'world',
                            })];
                    case 2:
                        _a.sent();
                        expect(fetch).not.toHaveBeenCalled();
                        unloadHandler === null || unloadHandler === void 0 ? void 0 : unloadHandler();
                        expect(fetch).toHaveBeenCalledTimes(1);
                        return [2 /*return*/];
                }
            });
        }); });
        it('flushes in batches of no more than 64kb', function () { return __awaiter(void 0, void 0, void 0, function () {
            var dispatch, i;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        dispatch = batch("https://api.segment.io", {
                            size: 1000,
                        }).dispatch;
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < 80)) return [3 /*break*/, 4];
                        return [4 /*yield*/, dispatch("https://api.segment.io/v1/t", {
                                event: 'fat event',
                                properties: fatEvent,
                            })];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        i++;
                        return [3 /*break*/, 1];
                    case 4:
                        expect(fetch).not.toHaveBeenCalled();
                        unloadHandler === null || unloadHandler === void 0 ? void 0 : unloadHandler();
                        expect(fetch).toHaveBeenCalledTimes(2);
                        return [2 /*return*/];
                }
            });
        }); });
    });
});
//# sourceMappingURL=batched-dispatcher.test.js.map