/** * Tests de migración Dexie v1 → v2 (Sprint 1). * * Verifican que: * 1. Registros sin los campos nuevos reciben defaults correctos tras el upgrade. * 2. Registros con los campos ya presentes no son modificados. * 3. Los nuevos campos se pueden leer y persistir correctamente. * * Usan fake-indexeddb (parcheado en tests/setup.ts). */ import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { db } from '@/persistence/db' import { activityRepo, processRepo } from '@/persistence/repositories' import type { Activity, Process } from '@/domain/types' // ─── Fixtures de registros "viejos" (sin campos Sprint 1) ───────────────────── function makeLegacyActivity(id: string, processId: string): Omit { return { id, processId, bpmnElementId: `task_${id}`, name: `Tarea ${id}`, type: 'task', directCostFixed: 500, executionTimeMinutes: 45, assignedResources: [], } } function makeLegacyProcess(id: string): Omit { return { id, name: 'Proceso Legacy', clientName: 'Cliente Viejo', bpmnXml: '', currency: 'USD', overheadPercentage: 0.15, createdAt: 1000, updatedAt: 2000, } } // ─── Setup / Teardown ───────────────────────────────────────────────────────── beforeEach(async () => { await db.open() await db.transaction('rw', [db.processes, db.activities], async () => { await db.processes.clear() await db.activities.clear() }) }) afterEach(async () => { await db.close() }) // ─── Tests de defaults tras migración ───────────────────────────────────────── describe('Migración Dexie v2 — Activity: defaults de campos Sprint 1', () => { it('actividades nuevas tienen automatable=false por defecto', async () => { const act: Activity = { ...makeLegacyActivity('a1', 'p1'), automatable: false, automatedCostFixed: 0, automatedTimeMinutes: 0, automatedAssignedResources: [], } await activityRepo.save(act) const retrieved = await activityRepo.getByProcess('p1') expect(retrieved[0].automatable).toBe(false) expect(retrieved[0].automatedCostFixed).toBe(0) expect(retrieved[0].automatedTimeMinutes).toBe(0) }) it('los campos de automatización persisten con valores no-default', async () => { const act: Activity = { ...makeLegacyActivity('a2', 'p1'), automatable: true, automatedCostFixed: 12.5, automatedTimeMinutes: 3, automatedAssignedResources: [], } await activityRepo.save(act) const [retrieved] = await activityRepo.getByProcess('p1') expect(retrieved.automatable).toBe(true) expect(retrieved.automatedCostFixed).toBe(12.5) expect(retrieved.automatedTimeMinutes).toBe(3) }) it('update de actividad preserva los campos de automatización existentes', async () => { const act: Activity = { ...makeLegacyActivity('a3', 'p1'), automatable: true, automatedCostFixed: 5, automatedTimeMinutes: 10, automatedAssignedResources: [], } await activityRepo.save(act) // Actualizar solo directCostFixed — los campos de automatización no deben cambiar await activityRepo.save({ ...act, directCostFixed: 999 }) const [updated] = await activityRepo.getByProcess('p1') expect(updated.directCostFixed).toBe(999) expect(updated.automatable).toBe(true) expect(updated.automatedCostFixed).toBe(5) }) }) describe('Migración Dexie v2 — Process: defaults de campos Sprint 1', () => { it('procesos nuevos tienen annualFrequency=1000 por defecto', async () => { const proc: Process = { ...makeLegacyProcess('proc-1'), annualFrequency: 1000, analysisHorizonYears: 3, automationInvestment: 0, groupId: null, tags: [], } await processRepo.save(proc) const retrieved = await processRepo.getById('proc-1') expect(retrieved!.annualFrequency).toBe(1000) expect(retrieved!.analysisHorizonYears).toBe(3) expect(retrieved!.automationInvestment).toBe(0) }) it('los campos de volumetría persisten con valores configurados', async () => { const proc: Process = { ...makeLegacyProcess('proc-2'), annualFrequency: 5000, analysisHorizonYears: 5, automationInvestment: 75_000, groupId: null, tags: [], } await processRepo.save(proc) const retrieved = await processRepo.getById('proc-2') expect(retrieved!.annualFrequency).toBe(5000) expect(retrieved!.analysisHorizonYears).toBe(5) expect(retrieved!.automationInvestment).toBe(75_000) }) it('update de proceso preserva campos de volumetría', async () => { const proc: Process = { ...makeLegacyProcess('proc-3'), annualFrequency: 2000, analysisHorizonYears: 4, automationInvestment: 30_000, groupId: null, tags: [], } await processRepo.save(proc) // Actualizar solo el nombre — los campos de volumetría no deben cambiar await processRepo.save({ ...proc, name: 'Nombre Actualizado' }) const updated = await processRepo.getById('proc-3') expect(updated!.name).toBe('Nombre Actualizado') expect(updated!.annualFrequency).toBe(2000) expect(updated!.automationInvestment).toBe(30_000) }) })