import { __awaiter, __generator } from "tslib";
import { sourceMiddlewarePlugin } from '..';
import { Analytics } from '../../../analytics';
import { Context } from '../../../core/context';
import { asPromise } from '../../../lib/as-promise';
describe(sourceMiddlewarePlugin, function () {
    var simpleMiddleware = function (_a) {
        var payload = _a.payload, next = _a.next;
        if (!payload.obj.context) {
            payload.obj.context = {};
        }
        payload.obj.context.hello = 'from the other side';
        next(payload);
    };
    var xt = sourceMiddlewarePlugin(simpleMiddleware);
    it('creates a source middleware', function () {
        expect(xt.name).toEqual('Source Middleware simpleMiddleware');
        expect(xt.version).toEqual('0.1.0');
    });
    it('is loaded automatically', function () { return __awaiter(void 0, void 0, void 0, function () {
        var _a;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    // @ts-expect-error
                    _a = expect;
                    return [4 /*yield*/, xt.load(Context.system())];
                case 1:
                    // @ts-expect-error
                    _a.apply(void 0, [_b.sent()]).toBeTruthy();
                    expect(xt.isLoaded()).toBe(true);
                    return [2 /*return*/];
            }
        });
    }); });
    describe('Middleware', function () {
        it('allows for changing the event', function () { return __awaiter(void 0, void 0, void 0, function () {
            var changeProperties, xt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        changeProperties = function (_a) {
                            var payload = _a.payload, next = _a.next;
                            if (!payload.obj.properties) {
                                payload.obj.properties = {};
                            }
                            payload.obj.properties.hello = 'from the other side';
                            next(payload);
                        };
                        xt = sourceMiddlewarePlugin(changeProperties);
                        _a = expect;
                        return [4 /*yield*/, xt.track(new Context({
                                type: 'track',
                            }))];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.properties]).toEqual({
                            hello: 'from the other side',
                        });
                        return [2 /*return*/];
                }
            });
        }); });
        it('uses a segment facade object', function () { return __awaiter(void 0, void 0, void 0, function () {
            var type, facadeMiddleware, xt;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        type = '';
                        facadeMiddleware = function (_a) {
                            var payload = _a.payload, next = _a.next;
                            type = payload.type();
                            next(payload);
                        };
                        xt = sourceMiddlewarePlugin(facadeMiddleware);
                        return [4 /*yield*/, xt.track(new Context({
                                type: 'track',
                            }))];
                    case 1:
                        _a.sent();
                        expect(type).toEqual(type);
                        return [2 /*return*/];
                }
            });
        }); });
        it('cancels the event if `next` is not called', function (done) { return __awaiter(void 0, void 0, void 0, function () {
            var hangs, hangsXT, doesNotHang, doesNotHangXT, toReturn, returnedCtx, toCancel;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        hangs = function () { };
                        hangsXT = sourceMiddlewarePlugin(hangs);
                        doesNotHang = function (_a) {
                            var next = _a.next, payload = _a.payload;
                            next(payload);
                        };
                        doesNotHangXT = sourceMiddlewarePlugin(doesNotHang);
                        toReturn = new Context({ type: 'track' });
                        return [4 /*yield*/, doesNotHangXT.track(toReturn)];
                    case 1:
                        returnedCtx = _a.sent();
                        expect(returnedCtx).toBe(toReturn);
                        toCancel = new Context({ type: 'track' });
                        return [4 /*yield*/, asPromise(hangsXT.track(toCancel)).catch(function (err) {
                                expect(err).toMatchInlineSnapshot("\n          ContextCancelation {\n            \"reason\": \"Middleware `next` function skipped\",\n            \"retry\": false,\n            \"type\": \"middleware_cancellation\",\n          }\n        ");
                                done();
                            })];
                    case 2:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('Common use cases', function () {
        it('can be used to cancel an event altogether', function () { return __awaiter(void 0, void 0, void 0, function () {
            var blowUp, ajs, ctx, notDelivered;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        blowUp = function () {
                            // do nothing
                            // do not invoke next
                        };
                        ajs = new Analytics({
                            writeKey: 'abc',
                        });
                        return [4 /*yield*/, ajs.page('hello')];
                    case 1:
                        ctx = _a.sent();
                        expect(ctx.logs().map(function (l) { return l.message; })).toContain('Delivered');
                        return [4 /*yield*/, ajs.addSourceMiddleware(blowUp)];
                    case 2:
                        _a.sent();
                        return [4 /*yield*/, ajs.page('hello')];
                    case 3:
                        notDelivered = _a.sent();
                        expect(notDelivered.logs().map(function (l) { return l.message; })).not.toContain('Delivered');
                        return [2 /*return*/];
                }
            });
        }); });
        it('can be used to re-route/cancel destinations', function () { return __awaiter(void 0, void 0, void 0, function () {
            var middlewareInvoked, pageMock, skipGA, gaDestination, ajs;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        middlewareInvoked = false;
                        pageMock = jest.fn();
                        skipGA = function (_a) {
                            var payload = _a.payload, next = _a.next;
                            if (!payload.obj.integrations) {
                                payload.obj.integrations = {};
                            }
                            payload.obj.integrations['Google Analytics'] = false;
                            middlewareInvoked = true;
                            next(payload);
                        };
                        gaDestination = {
                            name: 'Google Analytics',
                            isLoaded: function () { return true; },
                            load: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
                                return [2 /*return*/];
                            }); }); },
                            type: 'destination',
                            version: '1.0',
                            page: function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
                                return __generator(this, function (_a) {
                                    pageMock();
                                    return [2 /*return*/, ctx];
                                });
                            }); },
                        };
                        ajs = new Analytics({
                            writeKey: 'abc',
                        });
                        return [4 /*yield*/, ajs.register(gaDestination)];
                    case 1:
                        _a.sent();
                        return [4 /*yield*/, ajs.page('hello')];
                    case 2:
                        _a.sent();
                        expect(pageMock).toHaveBeenCalled();
                        return [4 /*yield*/, ajs.addSourceMiddleware(skipGA)];
                    case 3:
                        _a.sent();
                        return [4 /*yield*/, ajs.page('hello')];
                    case 4:
                        _a.sent();
                        expect(middlewareInvoked).toBe(true);
                        expect(pageMock).toHaveBeenCalledTimes(1);
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('Event API', function () {
        it('wraps track', function () { return __awaiter(void 0, void 0, void 0, function () {
            var evt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        evt = new Context({
                            type: 'track',
                        });
                        _a = expect;
                        return [4 /*yield*/, xt.track(evt)];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.context]).toMatchInlineSnapshot("\n        Object {\n          \"hello\": \"from the other side\",\n        }\n      ");
                        return [2 /*return*/];
                }
            });
        }); });
        it('wraps identify', function () { return __awaiter(void 0, void 0, void 0, function () {
            var evt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        evt = new Context({
                            type: 'identify',
                        });
                        _a = expect;
                        return [4 /*yield*/, xt.identify(evt)];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.context]).toMatchInlineSnapshot("\n        Object {\n          \"hello\": \"from the other side\",\n        }\n      ");
                        return [2 /*return*/];
                }
            });
        }); });
        it('wraps page', function () { return __awaiter(void 0, void 0, void 0, function () {
            var evt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        evt = new Context({
                            type: 'page',
                        });
                        _a = expect;
                        return [4 /*yield*/, xt.page(evt)];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.context]).toMatchInlineSnapshot("\n        Object {\n          \"hello\": \"from the other side\",\n        }\n      ");
                        return [2 /*return*/];
                }
            });
        }); });
        it('wraps group', function () { return __awaiter(void 0, void 0, void 0, function () {
            var evt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        evt = new Context({
                            type: 'group',
                        });
                        _a = expect;
                        return [4 /*yield*/, xt.group(evt)];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.context]).toMatchInlineSnapshot("\n        Object {\n          \"hello\": \"from the other side\",\n        }\n      ");
                        return [2 /*return*/];
                }
            });
        }); });
        it('wraps alias', function () { return __awaiter(void 0, void 0, void 0, function () {
            var evt, _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        evt = new Context({
                            type: 'alias',
                        });
                        _a = expect;
                        return [4 /*yield*/, xt.alias(evt)];
                    case 1:
                        _a.apply(void 0, [(_b.sent()).event.context]).toMatchInlineSnapshot("\n        Object {\n          \"hello\": \"from the other side\",\n        }\n      ");
                        return [2 /*return*/];
                }
            });
        }); });
    });
});
//# sourceMappingURL=index.test.js.map