const outbox = require("../../../../src/services/integrations/outbox"); describe("Integration Outbox", () => { it("enqueues new event", async () => { const mockPrisma = { integrationOutbox: { findUnique: vi.fn().mockResolvedValue(null), create: vi.fn().mockResolvedValue({ id: 1, status: "pending" }), }, }; const result = await outbox.enqueueIntegrationEvent(mockPrisma, { eventType: "test" }); expect(result.id).toBe(1); expect(result.duplicated).toBe(false); }); it("detects duplicated event", async () => { const mockPrisma = { integrationOutbox: { findUnique: vi.fn().mockResolvedValue({ id: 2, status: "pending" }), }, }; const result = await outbox.enqueueIntegrationEvent(mockPrisma, { eventType: "test", dedupeKey: "key" }); expect(result.id).toBe(2); expect(result.duplicated).toBe(true); }); it("marks as processing", async () => { const mockPrisma = { integrationOutbox: { update: vi.fn().mockResolvedValue({ id: 1, status: "processing" }), }, }; const res = await outbox.markOutboxProcessing(mockPrisma, 1, "actor"); expect(res.status).toBe("processing"); }); it("fetches pending events", async () => { const mockPrisma = { integrationOutbox: { findMany: vi.fn().mockResolvedValue([{ id: 1 }]), }, }; const items = await outbox.fetchPendingOutboxEvents(mockPrisma, { batchSize: 5 }); expect(items.length).toBe(1); }); it("marks outbox succeeded", async () => { const mockPrisma = { integrationOutbox: { update: vi.fn().mockResolvedValue({ id: 1, status: "succeeded" }), }, }; const res = await outbox.markOutboxSucceeded(mockPrisma, 1, "actor"); expect(res.status).toBe("succeeded"); }); it("handles failed outbox and schedules retry", async () => { const mockPrisma = { integrationOutbox: { update: vi.fn().mockImplementation(async ({ data }) => { return { status: data.status, retry: data.next_retry_at }; }), }, }; const res = await outbox.markOutboxFailed(mockPrisma, {}, { id: 1, attempts: 0 }, { retryable: true }, "actor"); expect(res.status).toBe("failed"); expect(res.retry).toBeInstanceOf(Date); }); it("moves to dead_letter if max attempts reached", async () => { const mockPrisma = { integrationOutbox: { update: vi.fn().mockImplementation(async ({ data }) => { return { status: data.status, retry: data.next_retry_at }; }), }, }; const res = await outbox.markOutboxFailed(mockPrisma, {}, { id: 1, attempts: 5, max_attempts: 5 }, { retryable: true }, "actor"); expect(res.status).toBe("dead_letter"); expect(res.retry).toBeNull(); }); });