118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
import { after, describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { CampaignRecipe, MailboxRole } from '../../lib/prisma';
|
|
import { assignSatellite, createCampaign, startCampaign } from '../../services/campaign.service';
|
|
import { prisma } from '../../lib/prisma';
|
|
import {
|
|
cleanupCampaign,
|
|
cleanupInbox,
|
|
createTestInbox,
|
|
} from '../helpers/test-db';
|
|
|
|
describe('integration: recipes', () => {
|
|
const campaignIds: string[] = [];
|
|
const inboxIds: string[] = [];
|
|
|
|
after(async () => {
|
|
for (const id of campaignIds) await cleanupCampaign(id);
|
|
for (const id of inboxIds) await cleanupInbox(id);
|
|
});
|
|
|
|
async function setupCampaign(recipe: CampaignRecipe, extra?: Record<string, unknown>) {
|
|
const primary = await createTestInbox({ role: MailboxRole.primary });
|
|
const sat1 = await createTestInbox();
|
|
const sat2 = await createTestInbox();
|
|
inboxIds.push(primary.id, sat1.id, sat2.id);
|
|
|
|
const campaign = await createCampaign({
|
|
primaryMailboxId: primary.id,
|
|
name: `Test ${recipe}`,
|
|
recipe,
|
|
durationDays: 14,
|
|
minEmailsPerDay: 1,
|
|
maxEmailsPerDay: 40,
|
|
...extra,
|
|
});
|
|
campaignIds.push(campaign.id);
|
|
|
|
await assignSatellite(campaign.id, sat1.id);
|
|
await assignSatellite(campaign.id, sat2.id);
|
|
|
|
return startCampaign(campaign.id);
|
|
}
|
|
|
|
it('flat recipe persists constant plannedSends', async () => {
|
|
const campaign = await setupCampaign(CampaignRecipe.flat);
|
|
const schedules = await prisma.dailySchedule.findMany({
|
|
where: { campaignId: campaign.id },
|
|
orderBy: { dayIndex: 'asc' },
|
|
});
|
|
assert.equal(schedules.length, 14);
|
|
for (const row of schedules) {
|
|
assert.equal(row.plannedSends, 40);
|
|
}
|
|
});
|
|
|
|
it('custom recipe persists hold-last schedule', async () => {
|
|
const primary = await createTestInbox({ role: MailboxRole.primary });
|
|
const sat1 = await createTestInbox();
|
|
const sat2 = await createTestInbox();
|
|
inboxIds.push(primary.id, sat1.id, sat2.id);
|
|
|
|
const campaign = await createCampaign({
|
|
primaryMailboxId: primary.id,
|
|
name: 'Test custom',
|
|
recipe: CampaignRecipe.custom,
|
|
durationDays: 14,
|
|
customSchedule: [
|
|
{ day: 1, sends: 2 },
|
|
{ day: 2, sends: 5 },
|
|
],
|
|
});
|
|
campaignIds.push(campaign.id);
|
|
await assignSatellite(campaign.id, sat1.id);
|
|
await assignSatellite(campaign.id, sat2.id);
|
|
const started = await startCampaign(campaign.id);
|
|
|
|
const schedules = await prisma.dailySchedule.findMany({
|
|
where: { campaignId: started.id },
|
|
orderBy: { dayIndex: 'asc' },
|
|
});
|
|
assert.equal(schedules[0]!.plannedSends, 2);
|
|
assert.equal(schedules[1]!.plannedSends, 5);
|
|
assert.equal(schedules[13]!.plannedSends, 5);
|
|
});
|
|
|
|
it('randomized recipe is deterministic per campaign id seed', async () => {
|
|
const a = await setupCampaign(CampaignRecipe.randomized);
|
|
const bPrimary = await createTestInbox({ role: MailboxRole.primary });
|
|
inboxIds.push(bPrimary.id);
|
|
const b = await createCampaign({
|
|
primaryMailboxId: bPrimary.id,
|
|
name: 'Random B',
|
|
recipe: CampaignRecipe.randomized,
|
|
durationDays: 14,
|
|
});
|
|
campaignIds.push(b.id);
|
|
const satB1 = await createTestInbox();
|
|
const satB2 = await createTestInbox();
|
|
inboxIds.push(satB1.id, satB2.id);
|
|
await assignSatellite(b.id, satB1.id);
|
|
await assignSatellite(b.id, satB2.id);
|
|
|
|
const scheduleA = await prisma.dailySchedule.findMany({
|
|
where: { campaignId: a.id },
|
|
orderBy: { dayIndex: 'asc' },
|
|
});
|
|
const restarted = await startCampaign(b.id);
|
|
const scheduleB = await prisma.dailySchedule.findMany({
|
|
where: { campaignId: restarted.id },
|
|
orderBy: { dayIndex: 'asc' },
|
|
});
|
|
|
|
assert.notDeepEqual(
|
|
scheduleA.map((r) => r.plannedSends),
|
|
scheduleB.map((r) => r.plannedSends),
|
|
);
|
|
});
|
|
});
|