diff --git a/apps/web/src/server/service/campaign-service.unit.test.ts b/apps/web/src/server/service/campaign-service.unit.test.ts index ead5c8db..52a5d420 100644 --- a/apps/web/src/server/service/campaign-service.unit.test.ts +++ b/apps/web/src/server/service/campaign-service.unit.test.ts @@ -2,41 +2,43 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { createHash } from "crypto"; import { UnsubscribeReason } from "@prisma/client"; -const { mockDb, mockQueueAdd, mockTx, mockUpdateContactSubscription } = - vi.hoisted(() => { - const mockTx = { - campaignEmail: { +const { mockDb, mockTx, mockUpdateContactSubscription } = vi.hoisted(() => { + const mockTx = { + campaignEmail: { + findUnique: vi.fn(), + create: vi.fn(), + }, + email: { + findFirst: vi.fn(), + create: vi.fn(), + update: vi.fn(), + }, + emailEvent: { + create: vi.fn(), + }, + }; + + return { + mockTx, + mockDb: { + $transaction: vi.fn(async (callback: ReturnType) => + callback(mockTx), + ), + contact: { findUnique: vi.fn(), - create: vi.fn(), }, - email: { - findFirst: vi.fn(), - create: vi.fn(), + campaign: { + findUnique: vi.fn(), update: vi.fn(), }, - emailEvent: { - create: vi.fn(), - }, - }; + }, + mockUpdateContactSubscription: vi.fn(), + }; +}); - return { - mockTx, - mockDb: { - $transaction: vi.fn(async (callback: ReturnType) => - callback(mockTx), - ), - contact: { - findUnique: vi.fn(), - }, - campaign: { - findUnique: vi.fn(), - update: vi.fn(), - }, - }, - mockQueueAdd: vi.fn(), - mockUpdateContactSubscription: vi.fn(), - }; - }); +const { mockQueueAdd } = vi.hoisted(() => ({ + mockQueueAdd: vi.fn(), +})); vi.mock("~/server/db", () => ({ db: mockDb, @@ -123,31 +125,6 @@ const input = { error: new Error("Queue for region ap-southeast-2 not found"), }; -describe("CampaignBatchService.queueBatch", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it("uses a BullMQ-compatible custom job ID", async () => { - mockDb.campaign.findUnique.mockResolvedValue({ - lastSentAt: null, - batchWindowMinutes: 0, - status: "SCHEDULED", - }); - - await CampaignBatchService.queueBatch({ - campaignId: "campaign_1", - teamId: 7, - }); - - expect(mockQueueAdd).toHaveBeenCalledWith( - "campaign-campaign_1", - { campaignId: "campaign_1", teamId: 7 }, - expect.objectContaining({ jobId: "campaign-batch-campaign_1" }), - ); - }); -}); - describe("recordCampaignContactFailure", () => { beforeEach(() => { vi.clearAllMocks(); @@ -225,6 +202,31 @@ describe("recordCampaignContactFailure", () => { }); }); +describe("CampaignBatchService", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("queues batches with a BullMQ-safe custom job ID", async () => { + mockDb.campaign.findUnique.mockResolvedValue({ + lastSentAt: null, + batchWindowMinutes: 0, + status: "SCHEDULED", + }); + + await CampaignBatchService.queueBatch({ + campaignId: "campaign_1", + teamId: 7, + }); + + expect(mockQueueAdd).toHaveBeenCalledWith( + "campaign-campaign_1", + { campaignId: "campaign_1", teamId: 7 }, + expect.objectContaining({ jobId: "campaign-batch-campaign_1" }), + ); + }); +}); + describe("campaign contact subscription changes", () => { beforeEach(() => { vi.clearAllMocks();