feat(templates): T5 boot seeder + default seeds
TemplateSeeder (OnModuleInit) seeds repo file defaults as global (scopeId NULL) templates if absent. Idempotent per (key,channel,locale,version): re-boot inserts nothing; a bumped version adds a new row and keeps the old for audit. Seeds: welcome (email), payment.receipt (email+sms), onboarding.reminder (email) — placeholder copy for marketing to replace. 3 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { resetDb } from '../test-utils/reset-db';
|
||||
import { TemplateSeeder } from './template.seeder';
|
||||
import { TEMPLATE_SEEDS, type TemplateSeed } from './seeds';
|
||||
import type { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
const url = process.env.DATABASE_URL ?? 'postgresql://iios:iios@localhost:5434/iios?schema=public';
|
||||
const prisma = new PrismaClient({ datasources: { db: { url } } });
|
||||
const seeder = new TemplateSeeder(prisma as unknown as PrismaService);
|
||||
|
||||
beforeAll(async () => { await prisma.$connect(); });
|
||||
afterAll(async () => { await prisma.$disconnect(); });
|
||||
beforeEach(async () => { await resetDb(prisma); });
|
||||
|
||||
describe('TemplateSeeder', () => {
|
||||
it('seeds the file defaults as global (scopeId NULL) templates', async () => {
|
||||
const n = await seeder.seed(TEMPLATE_SEEDS);
|
||||
expect(n).toBe(TEMPLATE_SEEDS.length);
|
||||
const rows = await prisma.iiosMessageTemplate.findMany();
|
||||
expect(rows).toHaveLength(TEMPLATE_SEEDS.length);
|
||||
expect(rows.every((r) => r.scopeId === null)).toBe(true);
|
||||
const welcome = rows.find((r) => r.key === 'welcome' && r.channel === 'EMAIL');
|
||||
expect(welcome?.variables).toEqual(['firstName', 'signupLink']);
|
||||
});
|
||||
|
||||
it('is idempotent — re-seeding inserts nothing and creates no duplicates', async () => {
|
||||
await seeder.seed(TEMPLATE_SEEDS);
|
||||
const second = await seeder.seed(TEMPLATE_SEEDS);
|
||||
expect(second).toBe(0);
|
||||
expect(await prisma.iiosMessageTemplate.count()).toBe(TEMPLATE_SEEDS.length);
|
||||
});
|
||||
|
||||
it('a bumped version inserts a new row and leaves the old one', async () => {
|
||||
await seeder.seed(TEMPLATE_SEEDS);
|
||||
const bumped: TemplateSeed = { key: 'welcome', channel: 'EMAIL', locale: 'en', version: 2, subject: 'v2', bodyText: 'v2', variables: [] };
|
||||
const n = await seeder.seed([bumped]);
|
||||
expect(n).toBe(1);
|
||||
const welcomes = await prisma.iiosMessageTemplate.findMany({ where: { key: 'welcome', channel: 'EMAIL' }, orderBy: { version: 'asc' } });
|
||||
expect(welcomes.map((w) => w.version)).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user