From 4b2e44c3ea706a56579cfb587fbeca2c6062b47b Mon Sep 17 00:00:00 2001 From: Thomas Joise Date: Sun, 19 Jul 2026 23:27:32 +0530 Subject: [PATCH] test(onboarding-migration): add coverage for dropped ticked milestone keys Add one test case to cover the scenario where old milestone keys that don't map to the new template (amc_start, setup_done for SMS) are ticked and should be counted in the migration's dropped tally. Verifies both dropped and carried counts are accurate. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../test/migrate-onboarding-templates.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/apps/hq/test/migrate-onboarding-templates.test.ts b/apps/hq/test/migrate-onboarding-templates.test.ts index 6d34d15..8873af4 100644 --- a/apps/hq/test/migrate-onboarding-templates.test.ts +++ b/apps/hq/test/migrate-onboarding-templates.test.ts @@ -121,6 +121,47 @@ describe('onboarding template migration', () => { expect((audits[0] as unknown as { n: number }).n).toBe(1) }) + it('counts ticked dropped keys (unmapped or not in new template)', async () => { + const cmId = await makeSmsClientModule() + // Insert old generic rows with two ticked keys that will be dropped: + // - amc_start: unmapped (not in KEY_MAP) + // - setup_done: maps to 'setup_configuration', but SMS template doesn't have it + // Plus one carried key (installed -> installation) to verify carried count too. + const rows: [string, number, string | null][] = [ + ['amc_start', 1, '2026-02-15'], // ticked, unmapped -> dropped + ['setup_done', 1, '2026-03-01'], // ticked, maps to setup_configuration but SMS template lacks it -> dropped + ['installed', 1, '2026-03-25'], // ticked, maps to installation which IS in SMS template -> carried + ['advance_paid', 0, null], + ['go_live', 0, null], + ['balance_paid', 0, null], + ] + for (const [i, r] of rows.entries()) { + await db.run( + `INSERT INTO project_milestone (id,client_module_id,key,label,done,done_on,sort) + VALUES (?,?,?,?,?,?,?)`, + `m${i}`, cmId, r[0], String(r[0]), r[1], r[2], i, + ) + } + + const res = await migrateOnboardingTemplates(db) + expect(res.projects).toBe(1) + expect(res.carried).toBe(1) // only installed -> installation + expect(res.dropped).toBe(2) // amc_start (unmapped) + setup_done (not in SMS template) + + // Verify the dropped keys are gone from the migrated template + const ms = await listProjectMilestones(db, cmId) + expect(ms.map((m) => m.key)).toEqual([ + 'document_collection', 'dlt_registration', 'account_creation', 'installation', + 'testing', 'training', 'go_live', 'advance_payment', 'balance_payment', + ]) + expect(ms.some((m) => m.key === 'amc_start' || m.key === 'setup_done')).toBe(false) + + // Verify the carried installation tick is preserved + const installation = ms.find((m) => m.key === 'installation')! + expect(installation.done).toBe(true) + expect(installation.doneOn).toBe('2026-03-25') + }) + it('leaves a module without a per-module template untouched', async () => { const client = await createClient(db, 'u1', { name: 'Other Society', stateCode: '32' }) const mod = await createModule(db, 'u1', { code: 'NOTEMPLATE', name: 'No Template Module' })