From 45b5a36d04d207eb721018da0de428af0f55662d Mon Sep 17 00:00:00 2001 From: Chi Cong Tran Date: Mon, 6 Oct 2025 09:40:30 +0200 Subject: [PATCH] add tests for PIN handling via cookies --- tests/views/Anmeldung.test.ts | 143 +++++++++++++++++++++++++++ tests/views/VorgangList.view.test.ts | 9 ++ 2 files changed, 152 insertions(+) create mode 100644 tests/views/Anmeldung.test.ts diff --git a/tests/views/Anmeldung.test.ts b/tests/views/Anmeldung.test.ts new file mode 100644 index 0000000..f357c10 --- /dev/null +++ b/tests/views/Anmeldung.test.ts @@ -0,0 +1,143 @@ +import { describe, it, expect, vi } from 'vitest'; +import { actions } from '$root/routes/anmeldung/+page.server'; +import { load } from '$root/routes/(token-based)/+layout.server' + +import { baseData } from '../fixtures'; +import { ROUTE_NAMES } from '../../src/routes'; +import { dev } from '$app/environment'; +import { vorgangExists, vorgangPINValidation } from '$lib/server/vorgangService'; + +vi.mock('$lib/server/vorgangService', () => ({ + vorgangExists: vi.fn(), + vorgangPINValidation: vi.fn(), +})); + +describe('Vorgang Anzeige via Token', () => { + it('Setze Cookie nach erfolgreicher Eingabe', async () => { + // Mock formData + const vorgObj = baseData.vorgang; + + const formData = new FormData(); + formData.set('vorgang-token', vorgObj.vorgangToken); + formData.set('vorgang-pin', vorgObj.vorgangPIN); + + const mockRequest = { + formData: vi.fn().mockResolvedValue(formData) + }; + + const cookiesSet = vi.fn(); + + const event = { + request: mockRequest, + cookies: { + set: cookiesSet + } + }; + + let thrownRedirect; + try { + await actions.getVorgangByToken(event); + } catch (e) { + thrownRedirect = e; + } + + // Redirect bei erfolgreicher Eingabe + expect(thrownRedirect?.status).toBe(303); + expect(thrownRedirect?.location).toBe(ROUTE_NAMES.VORGANG(vorgObj.vorgangToken)); + + // Cookie wurde gesetzt + const COOKIE_NAME = `token-${vorgObj.vorgangToken}` + expect(cookiesSet).toHaveBeenCalledWith(COOKIE_NAME, vorgObj.vorgangPIN, { + path: '/', + httpOnly: true, + sameSite: 'strict', + secure: !dev + }); + }); + + it('Schlägt fehl wenn keine Daten übergeben werden', async () => { + const formData = new FormData(); // no data + + const mockRequest = { + formData: vi.fn().mockResolvedValue(formData) + }; + + const cookiesSet = vi.fn(); + + const event = { + request: mockRequest, + cookies: { + set: cookiesSet + } + }; + + const result = await actions.getVorgangByToken(event); + + expect(result).toBeUndefined(); + + // Cookie wird nicht gesetzt + expect(cookiesSet).not.toHaveBeenCalled(); + }); +}); + +describe('Teste Guard', () => { + it('Lese Cookie aus', async () => { + const vorgObj = baseData.vorgang; + + const COOKIE_NAME = `token-${vorgObj.vorgangToken}` + const cookiesGet = vi.fn().mockImplementation((key: string) => { + if (key === COOKIE_NAME) return vorgObj.vorgangPIN; + return undefined; + }); + + + // mocked objects + const event = { + cookies: { + get: cookiesGet + }, + locals: {}, + params: {vorgang: vorgObj.vorgangToken} + }; + vi.mocked(vorgangExists).mockReturnValueOnce(true); + vi.mocked(vorgangPINValidation).mockReturnValueOnce(true); + + await load(event); + + expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); + }); + + it('Kein Cookie gesetzt', async () => { + const vorgObj = baseData.vorgang; + + const COOKIE_NAME = `token-${vorgObj.vorgangToken}` + const cookiesGet = vi.fn().mockImplementation((key: string) => { + if (key === COOKIE_NAME) return vorgObj.vorgangPIN; + return undefined; + }); + + + // mocked objects + const event = { + cookies: { + get: cookiesGet + }, + locals: {}, + params: {vorgang: vorgObj.vorgangToken} + }; + vi.mocked(vorgangExists).mockReturnValueOnce(true); + vi.mocked(vorgangPINValidation).mockReturnValueOnce(false); + + let thrownRedirect; + try { + await load(event); + throw new Error('Function did not throw') + } catch (e) { + thrownRedirect = e; + } + expect(thrownRedirect?.status).toBe(303); + expect(thrownRedirect?.location).toBe(ROUTE_NAMES.ANMELDUNG_VORGANG_PARAM(vorgObj.vorgangToken)); + + expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); + }); +}); diff --git a/tests/views/VorgangList.view.test.ts b/tests/views/VorgangList.view.test.ts index c03bdf3..8349c2f 100644 --- a/tests/views/VorgangList.view.test.ts +++ b/tests/views/VorgangList.view.test.ts @@ -33,4 +33,13 @@ describe('Teste Links auf Korrektheit', () => { expect(linkElement).toBeInTheDocument(); expect(linkElement).toHaveAttribute('href', expectedURL); }); + + it('Links enthalten keinen VorgangsPIN', () => { + const vorgListOneItem = baseData.vorgangList.slice(0, 1) + + render(VorgangListPage, { props: { data: { ...baseData, vorgangList: vorgListOneItem } } }); + const listItem = screen.getByTestId("test-list-item"); + const linkElement = within(listItem).getByRole('link'); + expect(linkElement.getAttribute('href')?.toLowerCase()).not.toContain('pin'); + }); });