import { afterEach, describe, expect, it, vi } from 'vitest'; const importService = async (supabaseMock) => { vi.resetModules(); vi.doMock('./supabaseClient', () => ({ supabase: supabaseMock })); return import('./assessmentShareService'); }; afterEach(() => { vi.clearAllMocks(); vi.resetModules(); vi.doUnmock('./supabaseClient'); delete globalThis.window; }); describe('assessmentShareService', () => { it('creates a share link with the current browser URL', async () => { globalThis.window = { location: { origin: 'https://pat.example.com', pathname: '/manager' } }; const rpc = vi.fn().mockResolvedValue({ data: { share_token: 'token-123' }, error: null }); const { createAssessmentShareLink } = await importService({ rpc }); const result = await createAssessmentShareLink({ id: 'assessment-1' }); expect(rpc).toHaveBeenCalledWith('create_or_get_assessment_share', { p_assessment_id: 'assessment-1' }); expect(result).toEqual({ token: 'token-123', url: 'https://pat.example.com/manager?share=token-123' }); }); it('maps profile visibility RPC errors to a user-facing German message', async () => { const rpc = vi.fn().mockResolvedValue({ data: null, error: { message: 'Tests are hidden in the profile' } }); const { createAssessmentShareLink } = await importService({ rpc }); await expect(createAssessmentShareLink({ id: 'assessment-1' })).rejects.toThrow( 'Deine Tests sind im Profil aktuell nicht sichtbar.' ); }); it('lists existing shares by assessment id', async () => { const inMock = vi.fn().mockResolvedValue({ data: [ { assessment_id: 'a1', share_token: 'share-a1' }, { assessment_id: 'a2', share_token: 'share-a2' } ], error: null }); const selectMock = vi.fn(() => ({ in: inMock })); const fromMock = vi.fn(() => ({ select: selectMock })); const { listAssessmentShares } = await importService({ from: fromMock }); const result = await listAssessmentShares(['a1', 'a2']); expect(fromMock).toHaveBeenCalledWith('assessment_shares'); expect(selectMock).toHaveBeenCalledWith('assessment_id, share_token'); expect(inMock).toHaveBeenCalledWith('assessment_id', ['a1', 'a2']); expect(result).toEqual({ a1: 'share-a1', a2: 'share-a2' }); }); it('hydrates shared assessments and recalculates derived exercise values', async () => { const rpc = vi.fn().mockResolvedValue({ data: [ { id: 'shared-1', pat_type: 'PAT 2', datum: '2026-03-28', name: 'Max Mustermann', exercises: [ { name: 'Gerade Einsteiger', soll: 6, faktor: 10, values: ['2', '4', ''] }, { name: 'Split Drill', soll: 4, faktor: 5, subA: ['1', '3'], subB: ['5', ''], subLabels: ['A', 'B'] } ] } ], error: null }); const { getSharedAssessment } = await importService({ rpc }); const result = await getSharedAssessment('share-token'); expect(rpc).toHaveBeenCalledWith('get_shared_assessment', { p_share_token: 'share-token' }); expect(result).toMatchObject({ id: 'shared-1', patType: 'PAT 2', datum: '2026-03-28', name: 'Max Mustermann' }); expect(result.exercises[0]).toMatchObject({ name: 'Gerade Einsteiger', durchschnitt: 3, points: 30 }); expect(result.exercises[1]).toMatchObject({ name: 'Split Drill', durchschnitt: 3, points: 15, subLabels: ['A', 'B'] }); }); });