/** * Fake repos pour les tests routes : implementent l'API publique des repos * (list/get/create/update*) en utilisant un store in-memory. */ import type { Decimal } from 'decimal.js'; import type { Attribution } from '../../src/domain/attribution.js'; import type { Bloc } from '../../src/domain/bloc.js'; import type { Client } from '../../src/domain/client.js'; import type { Formation } from '../../src/domain/formation.js'; import type { Intervention } from '../../src/domain/intervention.js'; import type { Module } from '../../src/domain/module.js'; import type { Personne } from '../../src/domain/personne.js'; import type { Projet } from '../../src/domain/projet.js'; import type { Tache } from '../../src/domain/tache.js'; import type { StatutAttribution, StatutIntervention } from '../../src/domain/types.js'; import { errors } from '../../src/lib/errors.js'; import type { RepoSet } from '../../src/repos/baserow-repo.js'; interface ListResult { items: T[]; meta: { page: number; per_page: number; total: number; total_pages: number }; } class FakeReadRepo { constructor( private readonly entityName: string, public store: T[] = [], ) {} list(): Promise> { return Promise.resolve({ items: this.store, meta: { page: 1, per_page: 200, total: this.store.length, total_pages: 1 }, }); } get(id: number): Promise { const found = this.store.find((x) => x.id === id); if (!found) return Promise.reject(errors.notFound(this.entityName, id)); return Promise.resolve(found); } } export class FakeAttributionRepo extends FakeReadRepo { public lastCreated?: { moduleId: number; personneId: number; heuresAttribuees: Decimal; statut: StatutAttribution; }; public lastUpdate?: { id: number; heures: Decimal }; public nextId = 1000; constructor(store: Attribution[] = []) { super('Attribution', store); } create(input: { moduleId: number; personneId: number; heuresAttribuees: Decimal; dateDebut: Date | null; dateFin: Date | null; statut: StatutAttribution; }) { this.lastCreated = input; const id = this.nextId++; return Promise.resolve({ id, order: '1', ...input }); } updateHeuresRealisees(id: number, heures: Decimal) { this.lastUpdate = { id, heures }; return Promise.resolve({ id, order: '1', attribution_heures_realisees: heures.toNumber() }); } } export class FakeInterventionRepo extends FakeReadRepo { public lastCreated?: { tacheId: number; personneId: number; heures: Decimal; date: Date; notes: string | null; statut: StatutIntervention; }; public nextId = 2000; constructor(store: Intervention[] = []) { super('Intervention', store); } create(input: { tacheId: number; personneId: number; heures: Decimal; date: Date; notes: string | null; statut: StatutIntervention; }) { this.lastCreated = input; const id = this.nextId++; return Promise.resolve({ id, order: '1', ...input }); } } export interface FakeReposBundle extends RepoSet { personnes: FakeReadRepo & RepoSet['personnes']; formations: FakeReadRepo & RepoSet['formations']; blocs: FakeReadRepo & RepoSet['blocs']; modules: FakeReadRepo & RepoSet['modules']; attributions: FakeAttributionRepo & RepoSet['attributions']; clients: FakeReadRepo & RepoSet['clients']; projets: FakeReadRepo & RepoSet['projets']; taches: FakeReadRepo & RepoSet['taches']; interventions: FakeInterventionRepo & RepoSet['interventions']; } export function buildFakeRepos(stores: { personnes?: Personne[]; formations?: Formation[]; blocs?: Bloc[]; modules?: Module[]; attributions?: Attribution[]; clients?: Client[]; projets?: Projet[]; taches?: Tache[]; interventions?: Intervention[]; }): FakeReposBundle { // Cast force : on shippe l'interface publique RepoSet meme si les classes // BaseRepo ne sont pas etendues. Les tests ne tapent que les methodes utilisees. return { personnes: new FakeReadRepo('Personne', stores.personnes ?? []), formations: new FakeReadRepo('Formation', stores.formations ?? []), blocs: new FakeReadRepo('Bloc', stores.blocs ?? []), modules: new FakeReadRepo('Module', stores.modules ?? []), attributions: new FakeAttributionRepo(stores.attributions ?? []), clients: new FakeReadRepo('Client', stores.clients ?? []), projets: new FakeReadRepo('Projet', stores.projets ?? []), taches: new FakeReadRepo('Tache', stores.taches ?? []), interventions: new FakeInterventionRepo(stores.interventions ?? []), } as unknown as FakeReposBundle; }