diff options
Diffstat (limited to 'src/lib/server/services/routines.test.ts')
| -rw-r--r-- | src/lib/server/services/routines.test.ts | 104 |
1 files changed, 49 insertions, 55 deletions
diff --git a/src/lib/server/services/routines.test.ts b/src/lib/server/services/routines.test.ts index 2ad409a..b92db25 100644 --- a/src/lib/server/services/routines.test.ts +++ b/src/lib/server/services/routines.test.ts @@ -1,108 +1,103 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { createTestDb } from '$lib/server/db/test-helper'; -import { add as addProject } from './projects'; -import { - add, - edit, - archive, - complete, - loadAllVersions, - loadArchived, - loadProjectDashboard, - loadOverview, -} from './routines'; +import { createTestDb, type TestDb } from '$lib/server/db/test-helper'; +import { ProjectsService } from './projects'; +import { RoutinesService } from './routines'; describe('routines service', () => { - let db: Awaited<ReturnType<typeof createTestDb>>['db']; + let db: TestDb['db']; + let service: RoutinesService; let projectId: number; beforeEach(async () => { const testDb = await createTestDb(); db = testDb.db; - const project = await addProject('Household', db); + service = new RoutinesService(db); + const project = await new ProjectsService(db).add('Household'); projectId = project.id; }); it('creates a routine with version 1', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); + const r = await service.add(projectId, 'clean kitchen', '7d'); expect(r.id).toBe(1); expect(r.version).toBe(1); expect(r.frequency).toBe('7d'); }); it('edit inserts a new snapshot version and keeps history', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); - const updated = await edit( - r.id, - { name: 'clean kitchen deeply', frequency: '3d' }, - db, - ); + const r = await service.add(projectId, 'clean kitchen', '7d'); + const updated = await service.edit(r.id, { + name: 'clean kitchen deeply', + frequency: '3d', + }); expect(updated.version).toBe(2); expect(updated.frequency).toBe('3d'); - const versions = await loadAllVersions(r.id, db); + const versions = await service.loadAllVersions(r.id); expect(versions).toHaveLength(2); expect(versions[0].frequency).toBe('7d'); expect(versions[1].frequency).toBe('3d'); }); it('new routines start with an empty description', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); + const r = await service.add(projectId, 'clean kitchen', '7d'); expect(r.description).toBe(''); }); it('edit is partial: name/frequency edits keep the description and vice-versa', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); - const described = await edit(r.id, { description: 'wax on, wax off' }, db); + const r = await service.add(projectId, 'clean kitchen', '7d'); + const described = await service.edit(r.id, { + description: 'wax on, wax off', + }); expect(described.name).toBe('clean kitchen'); expect(described.frequency).toBe('7d'); expect(described.description).toBe('wax on, wax off'); - const renamed = await edit(r.id, { name: 'clean the whole kitchen' }, db); + const renamed = await service.edit(r.id, { + name: 'clean the whole kitchen', + }); expect(renamed.version).toBe(3); expect(renamed.description).toBe('wax on, wax off'); expect(renamed.frequency).toBe('7d'); - const refreq = await edit(r.id, { frequency: '14d' }, db); + const refreq = await service.edit(r.id, { frequency: '14d' }); expect(refreq.version).toBe(4); expect(refreq.name).toBe('clean the whole kitchen'); expect(refreq.description).toBe('wax on, wax off'); - const cleared = await edit(r.id, { description: '' }, db); + const cleared = await service.edit(r.id, { description: '' }); expect(cleared.version).toBe(5); expect(cleared.description).toBe(''); expect(cleared.name).toBe('clean the whole kitchen'); }); it('archive inserts an archived snapshot without removing history', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); - await archive(r.id, db); - const versions = await loadAllVersions(r.id, db); + const r = await service.add(projectId, 'clean kitchen', '7d'); + await service.archive(r.id); + const versions = await service.loadAllVersions(r.id); expect(versions).toHaveLength(2); expect(versions[0].archived).toBe(false); expect(versions[1].archived).toBe(true); - const dashboard = await loadProjectDashboard( + const dashboard = await service.loadProjectDashboard( projectId, Temporal.Now.instant(), - db, ); expect(dashboard.routines).toHaveLength(0); expect(dashboard.healthScore).toBe(100); }); it('loadArchived lists archived routines; edits keep the archive date', async () => { - const a = await add(projectId, 'clean kitchen', '7d', db); - await add(projectId, 'water plants', '3d', db); - await archive(a.id, db); - const stamped = (await loadAllVersions(a.id, db))[1].archivedAt; + const a = await service.add(projectId, 'clean kitchen', '7d'); + await service.add(projectId, 'water plants', '3d'); + await service.archive(a.id); + const stamped = (await service.loadAllVersions(a.id))[1].archivedAt; expect(stamped).toBeTruthy(); - const edited = await edit(a.id, { name: 'clean kitchen deeply' }, db); + const edited = await service.edit(a.id, { name: 'clean kitchen deeply' }); expect(edited.archived).toBe(true); expect(edited.archivedAt).toBe(stamped); - const archived = await loadArchived(projectId, db); + const archived = await service.loadArchived(projectId); expect(archived.map((r) => r.id)).toEqual([a.id]); expect(archived[0].name).toBe('clean kitchen deeply'); expect(archived[0].frequency).toBe('7d'); @@ -110,12 +105,12 @@ describe('routines service', () => { }); it('loadArchived sorts most recently archived first', async () => { - const a = await add(projectId, 'first', '1d', db); - const b = await add(projectId, 'second', '1d', db); - await archive(a.id, db); - await archive(b.id, db); + const a = await service.add(projectId, 'first', '1d'); + const b = await service.add(projectId, 'second', '1d'); + await service.archive(a.id); + await service.archive(b.id); - const archived = await loadArchived(projectId, db); + const archived = await service.loadArchived(projectId); expect(archived).toHaveLength(2); // Descending archive date; equal timestamps keep insertion order. expect( @@ -126,28 +121,27 @@ describe('routines service', () => { }); it('complete records the snapshot version it was made against', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); - await edit(r.id, { frequency: '5d' }, db); + const r = await service.add(projectId, 'clean kitchen', '7d'); + await service.edit(r.id, { frequency: '5d' }); const doneAt = Temporal.Now.instant().toString({ smallestUnit: 'millisecond', }); - const completion = await complete(r.id, 'with vinegar', doneAt, db); + const completion = await service.complete(r.id, 'with vinegar', doneAt); expect(completion.routineVersion).toBe(2); expect(completion.note).toBe('with vinegar'); }); it('dashboard computes urgency and health from completions', async () => { - const r = await add(projectId, 'clean kitchen', '7d', db); + const r = await service.add(projectId, 'clean kitchen', '7d'); const created = Temporal.Instant.from(r.createdAt); - await complete( + await service.complete( r.id, null, created.toString({ smallestUnit: 'millisecond' }), - db, ); // 22 days after completion with a 7-day routine => two periods overdue const now = created.toZonedDateTimeISO('UTC').add({ days: 22 }).toInstant(); - const dashboard = await loadProjectDashboard(projectId, now, db); + const dashboard = await service.loadProjectDashboard(projectId, now); expect(dashboard.routines).toHaveLength(1); expect(dashboard.routines[0].status).toBe('veryLate'); expect(dashboard.healthScore).toBe(0); @@ -157,12 +151,12 @@ describe('routines service', () => { }); it('overview aggregates per-project health and a global score', async () => { - await add(projectId, 'clean kitchen', '7d', db); - const growth = await addProject('Personal growth', db); - await add(growth.id, 'read 30 minutes', '1d', db); + await service.add(projectId, 'clean kitchen', '7d'); + const growth = await new ProjectsService(db).add('Personal growth'); + await service.add(growth.id, 'read 30 minutes', '1d'); const now = Temporal.Now.instant(); - const overview = await loadOverview(now, db); + const overview = await service.loadOverview(now); expect(overview.projects).toHaveLength(2); expect(overview.globalScore).toBe( Math.round(overview.projects.reduce((s, p) => s + p.healthScore, 0) / 2), |
