import { TestBed } from '@angular/core/testing'; import { describe, it, expect, vi } from 'vitest'; import { SUBMIT_FAILED } from '@shared/application/submit'; import { AanvragenAdapter } from '@registratie/infrastructure/aanvragen.adapter'; import { AdminCasesStore } from './admin-cases.store'; const summary = (id: string) => ({ id, type: 'registratie', status: { tag: 'Concept', stepIndex: 0, stepCount: 3 }, documentIds: [], createdAt: '2026-07-23T10:00:00Z', updatedAt: '2026-07-23T10:00:00Z', owner: '19012345601', }); function setup(adapter: Partial): AdminCasesStore { TestBed.configureTestingModule({ providers: [{ provide: AanvragenAdapter, useValue: adapter }], }); return TestBed.inject(AdminCasesStore); } describe('AdminCasesStore', () => { it('loads and parses the cross-owner list', async () => { const store = setup({ listAll: () => Promise.resolve([summary('a'), summary('b')]) }); await store.load(); const s = store.cases(); expect(s.tag).toBe('Success'); expect(s.tag === 'Success' && s.value.map((c) => c.id)).toEqual(['a', 'b']); }); it('deletes optimistically and confirms via the admin endpoint', async () => { const deleteAny = vi.fn().mockResolvedValue(undefined); const store = setup({ listAll: () => Promise.resolve([summary('a'), summary('b')]), deleteAny, }); await store.load(); await store.delete('a'); expect(deleteAny).toHaveBeenCalledWith('a'); const s = store.cases(); expect(s.tag === 'Success' && s.value.map((c) => c.id)).toEqual(['b']); }); // RB-20: a failed delete must not be silent — the row rolls back AND the store // surfaces the error the page renders. Before RB-20 this only rolled back // (bare `catch { this.state.set(before) }`), so `lastError()` stayed null forever. it('rolls back the removal and surfaces the error when the delete fails', async () => { const deleteAny = vi.fn().mockRejectedValue(new Error('boom')); const store = setup({ listAll: () => Promise.resolve([summary('a')]), deleteAny }); await store.load(); await store.delete('a'); const s = store.cases(); expect(s.tag === 'Success' && s.value.map((c) => c.id)).toEqual(['a']); // reappears expect(store.lastError()).toBe(SUBMIT_FAILED); }); it('clears a stale error on the next delete attempt', async () => { const deleteAny = vi .fn() .mockRejectedValueOnce(new Error('boom')) .mockResolvedValueOnce(undefined); const store = setup({ listAll: () => Promise.resolve([summary('a'), summary('b')]), deleteAny, }); await store.load(); await store.delete('a'); expect(store.lastError()).toBe(SUBMIT_FAILED); await store.delete('b'); expect(store.lastError()).toBeNull(); }); });