import { TestBed } from '@angular/core/testing'; import { describe, it, expect } from 'vitest'; import { Result } from '@shared/kernel/fp'; import { Brief, BriefDecisions } from '@brief/domain/brief'; import { BriefAdapter, BriefView } from '@brief/infrastructure/brief.adapter'; import { BriefStore } from './brief.store'; const decisions: BriefDecisions = { canEdit: true, canApprove: true, canReject: true, canSend: true, }; const brief: Brief = { briefId: 'b1', beroep: 'arts', templateId: 't1', placeholders: [], sections: [], status: { tag: 'draft' }, drafterId: 'u1', }; const view: BriefView = { brief, availablePassages: [], decisions }; function setup(adapter: Partial): BriefStore { TestBed.configureTestingModule({ providers: [{ provide: BriefAdapter, useValue: adapter }] }); return TestBed.inject(BriefStore); } describe('BriefStore action state (Idle | Busy | Failed)', () => { it('is Busy synchronously once a transition starts, then Idle on success', async () => { const approved: BriefView = { ...view, brief: { ...brief, status: { tag: 'approved', approvedBy: 'u2', approvedAt: 't' } }, }; const store = setup({ load: (): Promise> => Promise.resolve({ ok: true, value: view }), save: (): Promise> => Promise.resolve({ ok: true, value: view }), approve: (): Promise> => Promise.resolve({ ok: true, value: approved }), }); await store.load(); const pending = store.approve(); expect(store.busy()).toBe(true); // set synchronously, before any await resolves await pending; expect(store.busy()).toBe(false); expect(store.lastError()).toBeNull(); }); it('goes Busy then Failed on a failing transition, surfacing the error', async () => { const store = setup({ load: (): Promise> => Promise.resolve({ ok: true, value: view }), save: (): Promise> => Promise.resolve({ ok: true, value: view }), approve: (): Promise> => Promise.resolve({ ok: false, error: 'niet toegestaan' }), }); await store.load(); await store.approve(); expect(store.busy()).toBe(false); expect(store.lastError()).toBe('niet toegestaan'); }); it('a subsequent successful transition clears a prior Failed state', async () => { let approveResult: Result = { ok: false, error: 'eerste poging mislukt' }; const store = setup({ load: (): Promise> => Promise.resolve({ ok: true, value: view }), save: (): Promise> => Promise.resolve({ ok: true, value: view }), approve: (): Promise> => Promise.resolve(approveResult), }); await store.load(); await store.approve(); expect(store.lastError()).toBe('eerste poging mislukt'); approveResult = { ok: true, value: { ...view, brief: { ...brief, status: { tag: 'approved', approvedBy: 'u2', approvedAt: 't' } } }, }; await store.approve(); expect(store.busy()).toBe(false); expect(store.lastError()).toBeNull(); }); });