Files
Mind-o-Mat/tests/webapp/notes-api-client.test.ts
Jannik c717353037
CI / test (push) Canceled after 0s
CI / webapp (push) Canceled after 0s
fix: beheben von Lint- und Prettier-Fehlern in Tests und Config
2026-09-08 16:54:21 +02:00

131 lines
4.1 KiB
TypeScript

// Tests fuer notes-api (Client-Funktionen mit fetch-Mock)
// Phase 4.1
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
import {
loadNote,
saveNote,
triggerSync,
listNotes,
type NoteData,
} from '../../webapp/src/notes-api';
describe('notes-api Client', () => {
let originalFetch: typeof globalThis.fetch;
beforeEach(() => {
originalFetch = globalThis.fetch;
});
afterEach(() => {
globalThis.fetch = originalFetch;
vi.restoreAllMocks();
});
describe('loadNote', () => {
it('gibt null zurueck bei 404', async () => {
globalThis.fetch = vi.fn(
async () => new Response('Not Found', { status: 404, statusText: 'Not Found' }),
) as typeof fetch;
const result = await loadNote('notiz.md');
expect(result).toBeNull();
});
it('parst Notiz-Antwort korrekt', async () => {
const noteData: NoteData = {
id: 'test.md',
content: '# Test',
frontmatter: { title: 'Test' },
lastModified: '2026-09-05T10:00:00Z',
};
globalThis.fetch = vi.fn(
async () =>
new Response(JSON.stringify(noteData), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
) as typeof fetch;
const result = await loadNote('test.md');
expect(result).toEqual(noteData);
});
it('wirft bei HTTP-Fehler (500)', async () => {
globalThis.fetch = vi.fn(
async () =>
new Response('Server Error', { status: 500, statusText: 'Internal Server Error' }),
) as typeof fetch;
await expect(loadNote('test.md')).rejects.toThrow('HTTP 500');
});
it('encoded den noteId in der URL', async () => {
const fetchMock = vi.fn(async () => new Response('null', { status: 404 })) as typeof fetch;
globalThis.fetch = fetchMock;
await loadNote('path with spaces.md');
expect(fetchMock).toHaveBeenCalledWith('/api/notes/path%20with%20spaces.md');
});
});
describe('saveNote', () => {
it('sendet PUT mit Content im Body', async () => {
const fetchMock = vi.fn(
async () =>
new Response(
JSON.stringify({ id: 'x.md', content: 'Y', frontmatter: {}, lastModified: 'now' }),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
),
) as typeof fetch;
globalThis.fetch = fetchMock;
await saveNote('x.md', 'Y');
const [url, init] = fetchMock.mock.calls[0];
expect(url).toBe('/api/notes/x.md');
expect(init?.method).toBe('PUT');
expect((init?.headers as Record<string, string>)['Content-Type']).toBe('application/json');
const body = JSON.parse(init?.body as string);
expect(body.content).toBe('Y');
});
});
describe('triggerSync', () => {
it('sendet POST an /api/sync und gibt ok zurueck', async () => {
const fetchMock = vi.fn(
async () =>
new Response(JSON.stringify({ ok: true, message: 'Sync OK' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
) as typeof fetch;
globalThis.fetch = fetchMock;
const result = await triggerSync();
expect(result.ok).toBe(true);
expect(result.message).toBe('Sync OK');
});
it('gibt Fehler zurueck bei 500', async () => {
globalThis.fetch = vi.fn(async () => new Response('Fail', { status: 500 })) as typeof fetch;
await expect(triggerSync()).rejects.toThrow('HTTP 500');
});
});
describe('listNotes', () => {
it('parst Notiz-Liste', async () => {
globalThis.fetch = vi.fn(
async () =>
new Response(JSON.stringify({ notes: ['a.md', 'b.md'] }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
) as typeof fetch;
const notes = await listNotes();
expect(notes).toEqual(['a.md', 'b.md']);
});
it('gibt leeres Array bei Fehler', async () => {
globalThis.fetch = vi.fn(async () => new Response('Boom', { status: 500 })) as typeof fetch;
await expect(listNotes()).rejects.toThrow('HTTP 500');
});
});
});