import { __awaiter, __generator } from "tslib";
import { mocked } from 'ts-jest/utils';
import unfetch from 'unfetch';
import { RemoteMetrics } from '../remote-metrics';
jest.mock('unfetch', function () {
    return jest.fn();
});
describe('remote metrics', function () {
    test('stores metrics in a queue when sampling', function () {
        var remote = new RemoteMetrics({
            sampleRate: 100,
        });
        remote.increment('analytics_js.banana', ['phone:1']);
        expect(remote.queue).toMatchInlineSnapshot("\n      Array [\n        Object {\n          \"metric\": \"analytics_js.banana\",\n          \"tags\": Object {\n            \"library\": \"analytics.js\",\n            \"library_version\": \"next-undefined\",\n            \"phone\": \"1\",\n          },\n          \"type\": \"Counter\",\n          \"value\": 1,\n        },\n      ]\n    ");
    });
    test('does not store when not sampling', function () {
        var remote = new RemoteMetrics({
            sampleRate: 0,
        });
        remote.increment('analytics_js.banana', ['phone:1']);
        expect(remote.queue).toMatchInlineSnapshot("Array []");
    });
    test('ignores messages after reaching threshold', function () {
        var remote = new RemoteMetrics({
            sampleRate: 100,
            maxQueueSize: 3,
        });
        remote.increment('analytics_js.banana', ['phone:1']);
        remote.increment('analytics_js.banana', ['phone:1']);
        remote.increment('analytics_js.banana', ['phone:1']);
        remote.increment('analytics_js.banana', ['phone:1']);
        expect(remote.queue.length).toBe(3);
    });
    test('force flushes errors', function () {
        var remote = new RemoteMetrics({
            sampleRate: 100,
        });
        var spy = jest.spyOn(remote, 'flush');
        remote.increment('analytics_js.banana', ['phone:1']);
        expect(spy).not.toHaveBeenCalled();
        remote.increment('analytics_js.banana.error', ['phone:1']);
        expect(spy).toHaveBeenCalled();
    });
    test('sends requests on flush', function () { return __awaiter(void 0, void 0, void 0, function () {
        var spy, remote;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    spy = mocked(unfetch).mockImplementation();
                    remote = new RemoteMetrics({
                        sampleRate: 100,
                    });
                    remote.increment('analytics_js.banana', ['phone:1']);
                    return [4 /*yield*/, remote.flush()];
                case 1:
                    _a.sent();
                    expect(spy).toHaveBeenCalled();
                    expect(spy.mock.calls[0]).toMatchInlineSnapshot("\n      Array [\n        \"https://api.segment.io/v1/m\",\n        Object {\n          \"body\": \"{\\\"series\\\":[{\\\"type\\\":\\\"Counter\\\",\\\"metric\\\":\\\"analytics_js.banana\\\",\\\"value\\\":1,\\\"tags\\\":{\\\"phone\\\":\\\"1\\\",\\\"library\\\":\\\"analytics.js\\\",\\\"library_version\\\":\\\"next-undefined\\\"}}]}\",\n          \"headers\": Object {\n            \"Content-Type\": \"text/plain\",\n          },\n          \"method\": \"POST\",\n        },\n      ]\n    ");
                    return [2 /*return*/];
            }
        });
    }); });
    test('clears queue after sending', function () { return __awaiter(void 0, void 0, void 0, function () {
        var remote;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    remote = new RemoteMetrics({
                        sampleRate: 100,
                    });
                    remote.increment('analytics_js.banana', ['phone:1']);
                    expect(remote.queue.length).toBe(1);
                    return [4 /*yield*/, remote.flush()];
                case 1:
                    _a.sent();
                    expect(remote.queue.length).toBe(0);
                    return [2 /*return*/];
            }
        });
    }); });
    test('does not crash on errors', function () { return __awaiter(void 0, void 0, void 0, function () {
        var errorSpy, error, remote;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    errorSpy = jest.spyOn(console, 'error').mockImplementation();
                    error = new Error('aaay');
                    mocked(unfetch).mockImplementation(function () {
                        throw error;
                    });
                    remote = new RemoteMetrics({
                        sampleRate: 100,
                    });
                    remote.increment('analytics_js.banana', ['phone:1']);
                    return [4 /*yield*/, remote.flush()];
                case 1:
                    _a.sent();
                    expect(errorSpy).toHaveBeenCalledWith(error);
                    return [2 /*return*/];
            }
        });
    }); });
    test('disables metrics reporting in case of errors', function () { return __awaiter(void 0, void 0, void 0, function () {
        var error, remote;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    jest.spyOn(console, 'error').mockImplementation();
                    error = new Error('aaay');
                    mocked(unfetch).mockImplementation(function () {
                        throw error;
                    });
                    remote = new RemoteMetrics({
                        sampleRate: 100,
                    });
                    remote.increment('analytics_js.banana', ['phone:1']);
                    return [4 /*yield*/, remote.flush()];
                case 1:
                    _a.sent();
                    expect(remote.sampleRate).toBe(0);
                    return [2 /*return*/];
            }
        });
    }); });
    test('flushs on a schedule', function () {
        jest.useFakeTimers();
        var remote = new RemoteMetrics({
            sampleRate: 100,
            flushTimer: 100,
        });
        var flushSpy = jest.spyOn(remote, 'flush');
        remote.increment('analytics_js.banana', ['phone:1']);
        jest.advanceTimersByTime(500);
        expect(flushSpy).toHaveBeenCalledTimes(5);
    });
});
//# sourceMappingURL=remote-metrics.test.js.map