"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const runQuirrel_1 = require("./runQuirrel");
const fastify_1 = __importDefault(require("fastify"));
const delay_1 = __importDefault(require("delay"));
const supertest_1 = __importDefault(require("supertest"));
function testAgainst(backend) {
    async function setup({ fail = false } = {}) {
        const server = (0, fastify_1.default)();
        const executionIds = [];
        server.post("/", (request, reply) => {
            executionIds.push(request.id);
            const { status } = JSON.parse(request.body);
            if (status) {
                reply.status(status).send();
                return;
            }
            throw new Error("Something broke!");
        });
        const endpoint = encodeURIComponent(await server.listen({
            port: 0,
        }));
        const incidentReceiverAuthorizations = [];
        const incidentReceiverBodies = [];
        const incidentReceiver = (0, fastify_1.default)();
        incidentReceiver.post("/incident", (request, reply) => {
            if (fail) {
                reply.status(500).send();
            }
            else {
                incidentReceiverBodies.push(request.body);
                incidentReceiverAuthorizations.push(request.headers.authorization);
                reply.status(200).send();
            }
        });
        const incidentReceiverEndpoint = (await incidentReceiver.listen({
            port: 0,
        })) + "/incident";
        const res = await (0, runQuirrel_1.run)(backend, {
            incidentReceiver: {
                endpoint: incidentReceiverEndpoint,
                passphrase: "super-secret",
            },
        });
        const quirrel = res.server;
        const teardown = res.teardown;
        return {
            quirrel,
            endpoint,
            incidentReceiverBodies,
            incidentReceiverAuthorizations,
            executionIds,
            teardown: () => Promise.all([teardown(), server.close(), incidentReceiver.close()]),
        };
    }
    describe(backend + " > incidents", () => {
        test("are sent to the incident receiver", async () => {
            const { teardown, quirrel, endpoint, incidentReceiverAuthorizations, incidentReceiverBodies, } = await setup({
                fail: false,
            });
            const runAt = new Date().toISOString();
            await (0, supertest_1.default)(quirrel)
                .post("/queues/" + endpoint)
                .send({
                body: JSON.stringify({ foo: "bar" }),
                id: "a",
                runAt,
            })
                .expect(201);
            await (0, delay_1.default)(100);
            expect(incidentReceiverBodies).toEqual([
                {
                    type: "incident",
                    incident: {
                        body: JSON.stringify({
                            statusCode: 500,
                            error: "Internal Server Error",
                            message: "Something broke!",
                        }),
                        status: 500,
                    },
                    job: {
                        endpoint: decodeURIComponent(endpoint),
                        id: "a",
                        payload: JSON.stringify({ foo: "bar" }),
                        runAt,
                        tokenId: "anonymous",
                    },
                },
            ]);
            expect(incidentReceiverAuthorizations).toEqual(["Bearer super-secret"]);
            await teardown();
        });
        describe("on a repeated job", () => {
            describe("when seeing a 404", () => {
                it("ends that job", async () => {
                    const { teardown, quirrel, endpoint, incidentReceiverBodies, } = await setup();
                    const runAt = new Date().toISOString();
                    await (0, supertest_1.default)(quirrel)
                        .post("/queues/" + endpoint)
                        .send({
                        body: JSON.stringify({ status: 404 }),
                        id: "a",
                        runAt,
                        repeat: {
                            every: 1 * 1000,
                            times: 3,
                        },
                    })
                        .expect(201);
                    await (0, delay_1.default)(100);
                    expect(incidentReceiverBodies).toHaveLength(1);
                    await (0, supertest_1.default)(quirrel).get(`/queues/${endpoint}/a`).expect(404);
                    await teardown();
                });
            });
            describe("when seeing non-404", () => {
                it("schedules next execution", async () => {
                    const { teardown, quirrel, endpoint, incidentReceiverBodies, } = await setup();
                    const runAt = new Date().toISOString();
                    await (0, supertest_1.default)(quirrel)
                        .post("/queues/" + endpoint)
                        .send({
                        body: JSON.stringify({ status: 502 }),
                        id: "a",
                        runAt,
                        repeat: {
                            every: 50,
                            times: 3,
                        },
                    })
                        .expect(201);
                    await (0, delay_1.default)(200);
                    expect(incidentReceiverBodies).toHaveLength(3);
                    await teardown();
                });
            });
        });
        describe("with retry", () => {
            it("retries", async () => {
                const { teardown, quirrel, endpoint, incidentReceiverBodies, executionIds, } = await setup();
                const runAt = new Date().toISOString();
                await (0, supertest_1.default)(quirrel)
                    .post("/queues/" + endpoint)
                    .send({
                    body: JSON.stringify({ status: 502 }),
                    id: "a",
                    runAt,
                    retry: [100, 200],
                })
                    .expect(201);
                await (0, delay_1.default)(500);
                expect(executionIds).toHaveLength(3);
                expect(incidentReceiverBodies).toHaveLength(1);
                await teardown();
            });
        });
        describe("when the incident receiver is down", () => {
            it("just continues normally", async () => {
                const { teardown, quirrel, endpoint, incidentReceiverAuthorizations, incidentReceiverBodies, } = await setup({
                    fail: true,
                });
                const runAt = new Date().toISOString();
                await (0, supertest_1.default)(quirrel)
                    .post("/queues/" + endpoint)
                    .send({
                    body: JSON.stringify({ foo: "bar" }),
                    id: "a",
                    runAt,
                })
                    .expect(201);
                await (0, delay_1.default)(50);
                expect(incidentReceiverBodies).toEqual([]);
                expect(incidentReceiverAuthorizations).toEqual([]);
                await teardown();
            });
        });
    });
}
testAgainst("Redis");
testAgainst("Mock");
//# sourceMappingURL=incident.test.js.map