From 8803187ce1326799ca61571293ac5a1cb392f560 Mon Sep 17 00:00:00 2001 From: mina Date: Tue, 9 Sep 2025 18:25:04 +0200 Subject: [PATCH] implement tests TatortList.view, check delete/edit Item --- src/lib/components/NameItemEditor.svelte | 3 +- src/lib/config.ts | 2 +- .../(token-based)/list/[vorgang]/+page.svelte | 38 ++++----- tests/ComponentNameItemEditor.view.test.ts | 47 +---------- tests/TatortList.test.ts | 77 +++++++++++++++++ tests/TatortList.view.test.ts | 84 ++++++------------- tests/VorgangList.view.test.ts | 49 +---------- tests/fixtures.ts | 47 +++++++++++ 8 files changed, 167 insertions(+), 180 deletions(-) create mode 100644 tests/TatortList.test.ts create mode 100644 tests/fixtures.ts diff --git a/src/lib/components/NameItemEditor.svelte b/src/lib/components/NameItemEditor.svelte index 8a1d299..a1207ea 100644 --- a/src/lib/components/NameItemEditor.svelte +++ b/src/lib/components/NameItemEditor.svelte @@ -81,8 +81,9 @@ } -
+
{ diff --git a/src/lib/config.ts b/src/lib/config.ts index 0775514..2e2bf34 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,3 +1,3 @@ import { readFileSync } from 'fs'; -export default JSON.parse(readFileSync('./config.json').toString()); +export default JSON.parse(readFileSync('./config_prod.json').toString()); diff --git a/src/routes/(token-based)/list/[vorgang]/+page.svelte b/src/routes/(token-based)/list/[vorgang]/+page.svelte index 549f032..1d65d2a 100644 --- a/src/routes/(token-based)/list/[vorgang]/+page.svelte +++ b/src/routes/(token-based)/list/[vorgang]/+page.svelte @@ -25,6 +25,7 @@ prefix?: string; // add other properties as needed } + console.log(data.url); let vorgangName: string = data.vorgang.vorgangName; let crimesList: ListItem[] = $state(data.crimesList); @@ -53,25 +54,18 @@ }) .then(() => { inProgress = false; + invalidateAll(); + crimesList = data.crimesList; + open = false; }) .catch((err) => { inProgress = false; isError = true; console.log('ERROR', err); }); - - if (!res.ok) { - const msg = await res.text(); - console.error('❌ Fehler beim Umbenennen:', msg); - isError = true; - inProgress = false; - } else { - await invalidateAll(); - crimesList = data.crimesList; - open = false; - inProgress = false; - } } catch (err) { + isError = true; + inProgress = false; console.error('⚠️ Netzwerkfehler:', err); inProgress = false; } @@ -82,7 +76,6 @@ inProgress = true; let url = new URL(data.url); url.pathname += `/${tatort}`; - console.log('Delete tatort: ', `/api${url.pathname}`, url.pathname); try { const res = await fetch(`/api${url.pathname}`, { @@ -94,21 +87,15 @@ }) .then(() => { inProgress = false; + console.log('🗑️ Erfolgreich gelöscht:', url.pathname); + invalidateAll(); + crimesList = data.crimesList; }) .catch((err) => { isError = true; inProgress = false; console.log('ERROR', err); }); - if (!res.ok) { - const msg = await res.text(); - console.error('❌ Fehler beim Löschen:', msg); - } else { - console.log('🗑️ Erfolgreich gelöscht:', url.pathname); - await invalidateAll(); - - crimesList = data.crimesList; - } } catch (err) { isError = true; inProgress = false; @@ -180,9 +167,12 @@ Mit freundlichen Grüßen, onDelete={handleDelete} > {:else} - {item.name} + {item.name} +

{/if} {#if item.size}

diff --git a/tests/ComponentNameItemEditor.view.test.ts b/tests/ComponentNameItemEditor.view.test.ts index d5bc1f5..d25b7a9 100644 --- a/tests/ComponentNameItemEditor.view.test.ts +++ b/tests/ComponentNameItemEditor.view.test.ts @@ -1,54 +1,9 @@ import { fireEvent, render } from '@testing-library/svelte'; import { describe, expect, it, vi } from "vitest"; import NameItemEditor from '$lib/components/NameItemEditor.svelte'; +import { baseData } from './fixtures'; -const testUser = { - admin: true, -exp: 1757067123, -iat: 1757063523, -id: "admin", -} -const testCrimesList = [ - { - name: 'model-A', - lastModified: '2025-08-28T09:44:12.453Z', - etag: '558f35716f6af953f9bb5d75f6d77e6a', - size: 8947140, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - }, - { - name: 'model-z', - lastModified: '2025-08-28T10:37:20.142Z', - etag: '43e3989c32c4682bee407baaf83b6fa0', - size: 35788560, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - } - ]; -const testVorgangsList = [ - { -vorgangName: "vorgang-1", -vorgangPIN: "pin-123", -vorgangToken: "c322f26f-8c5e-4cb9-94b3-b5433bf5109e" - }, - { -vorgangName: "vorgang-2", -vorgangPIN: "pin-2", -vorgangToken: "cb0051bc-5f38-47b8-943c-9352d4d9c984" - } - -] - -const baseData = { - user: testUser, - vorgang: testVorgangsList[0], - vorgangList: testVorgangsList, - crimesList: testCrimesList, - url: URL, - crimeNames: [ "modell-A" ], -} const testCrimesListIndex = 0; const testItem = baseData.crimesList[testCrimesListIndex]; diff --git a/tests/TatortList.test.ts b/tests/TatortList.test.ts new file mode 100644 index 0000000..beeb8a3 --- /dev/null +++ b/tests/TatortList.test.ts @@ -0,0 +1,77 @@ +import { fireEvent, getAllByTestId, queryAllByTestId, render, screen, within } from '@testing-library/svelte'; +import { describe, expect, it, vi } from "vitest"; +import TatortListPage from "../src/routes/(token-based)/list/[vorgang]/+page.svelte"; +import { baseData } from './fixtures'; + + +// Mock für invalidateAll +vi.mock('$app/navigation', () => ({ + invalidateAll: vi.fn() +})); + +// Minimaler fetch-Mock +global.fetch = vi.fn().mockResolvedValue({ ok: true }); + +describe('Seite: Vorgangsansicht', () => { + describe('Szenario: Admin + Liste gefüllt', () => { +it('ändert den Namen nach Speichern', async () => { + const testData = structuredClone(baseData); + const oldName = testData.crimesList[0].name; + + render(TatortListPage, { props: { data: testData } }); + + const firstItem = screen.getAllByTestId('test-list-item')[0]; + await fireEvent.click(within(firstItem).getByTestId('edit-button')); + + const input = within(firstItem).getByRole('textbox'); + await fireEvent.input(input, { target: { value: 'Fall-B' } }); + +await fireEvent.click(within(firstItem).getByTestId('commit-button')); + +// Erwartung: fetch wurde aufgerufen +expect(global.fetch).toHaveBeenCalledWith( + expect.stringContaining(`/api/list/${testData.vorgang.vorgangToken}/${oldName}`), + expect.any(Object) +); + +// Erwartung: neuer Name ist sofort im DOM sichtbar +expect(within(firstItem).getByRole('textbox')).toHaveValue('Fall-B'); + +}); + +it('entfernt das Listenelement nach Löschen', async () => { + const testData = structuredClone(baseData); + testData.url = new URL('https://example.com/vorgang-1'); // Fix für Invalid URL + const toDelete = testData.crimesList[0]; + + global.fetch = vi.fn().mockResolvedValue({ ok: true }); + +render(TatortListPage, { props: { data: testData } }); + const deletedFirstItem = screen.getAllByTestId('test-list-item')[0]; + + + const deletedLink = within(deletedFirstItem).getByRole('link'); + + const deletedExpectedHref = `/view/${testData.vorgang.vorgangToken}/${toDelete.name}?pin=${testData.vorgang.vorgangPIN}`; + + expect(deletedLink).toBeInTheDocument(); + + expect(deletedLink).toHaveAttribute('href', deletedExpectedHref); + expect(deletedLink).toHaveAttribute('title', toDelete.name); + + +await fireEvent.click(within(deletedFirstItem).getByTestId('delete-button')); + +// Erwartung: fetch wurde aufgerufen +expect(global.fetch).toHaveBeenCalledWith( + expect.stringContaining(`/api/vorgang-1/${toDelete.name}`), + expect.any(Object) +); + +// Erwartung: Element ist nicht mehr im DOM +expect(within(deletedFirstItem).getByRole('textbox')).toHaveValue(toDelete.name); + }); + }); +}); + + diff --git a/tests/TatortList.view.test.ts b/tests/TatortList.view.test.ts index f47f86e..878da66 100644 --- a/tests/TatortList.view.test.ts +++ b/tests/TatortList.view.test.ts @@ -1,58 +1,11 @@ import { render, screen, within } from '@testing-library/svelte'; import { describe, expect, it, test } from "vitest"; import TatortListPage from "../src/routes/(token-based)/list/[vorgang]/+page.svelte"; - -const testUser = { - admin: true, -exp: 1757067123, -iat: 1757063523, -id: "admin", -} -const testCrimesList = [ - { - name: 'model-A', - lastModified: '2025-08-28T09:44:12.453Z', - etag: '558f35716f6af953f9bb5d75f6d77e6a', - size: 8947140, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - }, - { - name: 'model-z', - lastModified: '2025-08-28T10:37:20.142Z', - etag: '43e3989c32c4682bee407baaf83b6fa0', - size: 35788560, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - } - ]; - -const testVorgangsList = [ - { -vorgangName: "vorgang-1", -vorgangPIN: "pin-123", -vorgangToken: "c322f26f-8c5e-4cb9-94b3-b5433bf5109e" - }, - { -vorgangName: "vorgang-2", -vorgangPIN: "pin-2", -vorgangToken: "cb0051bc-5f38-47b8-943c-9352d4d9c984" - } - -] - -const baseData = { - user: testUser, - vorgang: testVorgangsList[0], - vorgangList: testVorgangsList, - crimesList: testCrimesList, - url: URL, - crimeNames: [ "modell-A" ] -} - +import { baseData } from './fixtures'; describe('Seite: Vorgangsansicht', () => { test.todo('zeigt PIN und Share-Link, wenn Admin'); + test.todo('zeigt PIN und Share-Link disabeld, wenn Liste leer') describe('Szenario: Liste leer (unabhängig von Rolle)', () => { it('zeigt Hinweistext bei leerer Liste', () => { @@ -105,17 +58,28 @@ describe('Seite: Vorgangsansicht', () => { }); describe('Szenario: Admin + Liste gefüllt', () => { - it('zeigt PIN und Share-Link disabeld, wenn Liste leer', () => { }); - it('zeigt PIN und Share-Link disabeld=false', () => { }); - it('zeigt Listeneinträge mit Edit/Delete', () => { }); - it('gibt Edit/Delete-Events korrekt weiter', () => { }); - }); + const testData = { ...baseData, user: { ...baseData.user, admin: true }}; + it('zeigt Listeneinträge mit Komponente NameItemEditor', () => { + const { getAllByTestId } = render(TatortListPage, {props:{data: testData}}); + const items = getAllByTestId('test-nameItemEditor'); + + expect(items.length).toBeGreaterThan(0); + }); + }); + describe('Szenario: Viewer + Liste gefüllt', () => { - it('zeigt Listeneinträge ohne Edit/Delete', () => { }); - it('zeigt Link und Änderungsdatum', () => { }); - it('zeigt keinen Share-Link oder PIN', () => { }); - }); + const testData = { ...baseData, user: { ...baseData.user, admin: false }}; + it('zeigt Listeneinträge mit p', () => { + render(TatortListPage, { props: { data: testData } }); + const paragraphs = screen.queryAllByTestId('test-nameItem-p'); - test.todo('Modal testen, wenn open') + expect(paragraphs).toHaveLength(testData.crimesList.length); + paragraphs.forEach((p, i) => { + expect(p).toHaveTextContent(testData.crimesList[i].name); + }); + }); + + test.todo('zeigt keinen Share-Link oder PIN') + test.todo('Modal testen, wenn open') + }); }); - diff --git a/tests/VorgangList.view.test.ts b/tests/VorgangList.view.test.ts index ae467e4..36334e2 100644 --- a/tests/VorgangList.view.test.ts +++ b/tests/VorgangList.view.test.ts @@ -1,54 +1,7 @@ import { render } from '@testing-library/svelte'; import { describe, expect, it } from "vitest"; import VorgangListPage from '../src/routes/(angemeldet)/list/+page.svelte'; -const testUser = { - admin: true, -exp: 1757067123, -iat: 1757063523, -id: "admin", -} -const testCrimesList = [ - { - name: 'model-A', - lastModified: '2025-08-28T09:44:12.453Z', - etag: '558f35716f6af953f9bb5d75f6d77e6a', - size: 8947140, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - }, - { - name: 'model-z', - lastModified: '2025-08-28T10:37:20.142Z', - etag: '43e3989c32c4682bee407baaf83b6fa0', - size: 35788560, - prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', - show_button: true - } - ]; - -const testVorgangsList = [ - { -vorgangName: "vorgang-1", -vorgangPIN: "pin-123", -vorgangToken: "c322f26f-8c5e-4cb9-94b3-b5433bf5109e" - }, - { -vorgangName: "vorgang-2", -vorgangPIN: "pin-2", -vorgangToken: "cb0051bc-5f38-47b8-943c-9352d4d9c984" - } - -] - -const baseData = { - user: testUser, - vorgang: testVorgangsList[0], - vorgangList: testVorgangsList, - crimesList: testCrimesList, - url: URL, - crimeNames: [ "modell-A" ], - -} +import { baseData } from './fixtures'; describe('Vorgänge Liste Page EmptyList-Komponente View', ()=>{ it('zeigt EmptyList-Komponente an, wenn Liste leer ist', () => { diff --git a/tests/fixtures.ts b/tests/fixtures.ts new file mode 100644 index 0000000..cb40c9f --- /dev/null +++ b/tests/fixtures.ts @@ -0,0 +1,47 @@ +const testUser = { + admin: true, +exp: 1757067123, +iat: 1757063523, +id: "admin", +} +const testCrimesList = [ + { + name: 'modell-A', + lastModified: '2025-08-28T09:44:12.453Z', + etag: '558f35716f6af953f9bb5d75f6d77e6a', + size: 8947140, + prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', + show_button: true + }, + { + name: 'Fall-A', + lastModified: '2025-08-28T10:37:20.142Z', + etag: '43e3989c32c4682bee407baaf83b6fa0', + size: 35788560, + prefix: '7596e4d5-c51f-482d-a4aa-ff76434305fc', + show_button: true + } + ]; + +const testVorgangsList = [ + { +vorgangName: "vorgang-1", +vorgangPIN: "pin-123", +vorgangToken: "c322f26f-8c5e-4cb9-94b3-b5433bf5109e" + }, + { +vorgangName: "vorgang-2", +vorgangPIN: "pin-2", +vorgangToken: "cb0051bc-5f38-47b8-943c-9352d4d9c984" + } + +] + +export const baseData = { + user: testUser, + vorgang: testVorgangsList[0], + vorgangList: testVorgangsList, + crimesList: testCrimesList, + url: new URL(`https://example.com/${testVorgangsList[0].vorgangToken}`), + crimeNames: [ "modell-A", "Fall-A" ], +}