Files
Pat-Manager/src/lib/assessmentShareService.test.js
Ashikagi 0acece98dc
All checks were successful
Vercel Production Deployment / Deploy-Production (push) Successful in 1m1s
Unit Tests
2026-03-28 15:54:02 +01:00

134 lines
3.7 KiB
JavaScript

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']
});
});
});