/** * Regression: saving the round Config form must NOT wipe operational keys that * live outside the form schema (ceremony projectOrder, per-project timing * overrides, finals-docs upload toggle). Found live: a Config save mid-test * destroyed the running ceremony's run order. */ import { describe, it, expect, beforeAll, afterAll } from 'vitest' import { prisma, createCaller } from '../setup' import { createTestUser, createTestProgram, createTestCompetition, createTestRound, cleanupTestData, } from '../helpers' import { roundRouter } from '@/server/routers/round' let program: any let round: any let admin: any let adminCaller: ReturnType beforeAll(async () => { program = await createTestProgram() const competition = await createTestCompetition(program.id) round = await createTestRound(competition.id, { roundType: 'LIVE_FINAL', status: 'ROUND_ACTIVE', configJson: { presentationDurationMinutes: 5, projectOrder: ['p-one', 'p-two'], projectTimingOverrides: { 'p-one': { presentationSeconds: 480 } }, allowFinalistRevisedUploads: true, }, }) admin = await createTestUser('SUPER_ADMIN') adminCaller = createCaller(roundRouter, admin) }) afterAll(async () => { await cleanupTestData(program.id, [admin.id]) }) describe('round.update configJson merge', () => { it('updates form fields without wiping operational keys', async () => { await adminCaller.update({ id: round.id, configJson: { presentationDurationMinutes: 10, qaDurationMinutes: 3 }, }) const updated = await prisma.round.findUniqueOrThrow({ where: { id: round.id } }) const cfg = updated.configJson as Record expect(cfg.presentationDurationMinutes).toBe(10) // form field applied expect(cfg.qaDurationMinutes).toBe(3) expect(cfg.projectOrder).toEqual(['p-one', 'p-two']) // ceremony state survives expect((cfg.projectTimingOverrides as any)['p-one'].presentationSeconds).toBe(480) expect(cfg.allowFinalistRevisedUploads).toBe(true) // finals-docs toggle survives }) })