f110_undo_skipped_test_API_endpoints #38

Merged
jared merged 3 commits from f110_undo_skipped_test_API_endpoints into development 2025-11-05 10:24:20 +01:00
14 changed files with 90 additions and 94 deletions

View File

@@ -14,5 +14,15 @@ export const handle: Handle = async ({ event, resolve }) => {
event.cookies.delete('session', {path: ROUTE_NAMES.ROOT}); event.cookies.delete('session', {path: ROUTE_NAMES.ROOT});
event.locals.user = null; event.locals.user = null;
} }
if (event.url.pathname.startsWith('/api')) {
if (!event.locals.user) {
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
status: 401,
headers: { 'Content-Type': 'application/json' }
});
}
}
return await resolve(event); return await resolve(event);
} }

View File

@@ -0,0 +1,23 @@
import { getCrimesListByToken, getVorgaenge } from '$lib/server/vorgangService.js';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params, url }) => {
const vorgangList = getVorgaenge();
const vorgangToken = params.vorgang;
const crimesList = await getCrimesListByToken(vorgangToken);
const vorgang = vorgangList.find((v) => v.vorgangToken === vorgangToken); //vorgang sollte ein eigener Typ werden, und dann kann man es hier vernünftig typisieren
if (!vorgang || !crimesList) {
throw new Error(`Fehlgeschlagen, es wurden keine Daten zum token gefunden`);
}
//Variabeln für NameItemEditor
const crimeNames: string[] = crimesList.map((l) => l.name);
return {
vorgang,
vorgangList,
crimesList,
url,
crimeNames
};
}

View File

@@ -1,25 +0,0 @@
import { API_ROUTES } from '../../../index.js';
export async function load({fetch, params, url}){
const vorgangResponse = await fetch(API_ROUTES.LIST);
const vorgangList = await vorgangResponse.json()
const vorgangToken = params.vorgang;
const crimesListResponse = await fetch(API_ROUTES.VORGANG(vorgangToken))
const crimesList = await crimesListResponse.json();
const vorgang = vorgangList.find(v => v.vorgangToken === vorgangToken); //vorgang sollte ein eigener Typ werden, und dann kann man es hier vernünftig typisieren
if(!vorgang || !crimesList){
throw new Error(`Fehlgeschlagen, es wurden keine Daten zum token gefunden`);
}
//Variabeln für NameItemEditor
const crimeNames: string[] = crimesList.map((l) => l.name);
return {
vorgang,
vorgangList,
crimesList,
url,
crimeNames
}
}

View File

@@ -1,7 +1,7 @@
import { getVorgaenge } from '$lib/server/vorgangService'; import { getVorgaenge } from '$lib/server/vorgangService';
import { json } from '@sveltejs/kit';
export async function GET({ locals }) { export async function GET() {
const vorgaenge = getVorgaenge(); const vorgaenge = getVorgaenge();
return new Response(JSON.stringify(vorgaenge), { return new Response(JSON.stringify(vorgaenge), {

View File

@@ -1,4 +1,5 @@
import { BUCKET, client } from '$lib/minio'; import { BUCKET, client } from '$lib/minio';
import { json } from '@sveltejs/kit';
import { import {
deleteVorgangByToken, deleteVorgangByToken,
getCrimesListByToken, getCrimesListByToken,
@@ -43,8 +44,7 @@ export async function HEAD({ params }) {
} }
} }
export async function GET({ params, locals }) { export async function GET({ params }) {
try { try {
const vorgangToken = params.vorgang; const vorgangToken = params.vorgang;
const crimesList = await getCrimesListByToken(vorgangToken); const crimesList = await getCrimesListByToken(vorgangToken);

View File

@@ -24,7 +24,7 @@ export async function GET() {
}); });
} }
export async function DELETE({ request }: { request: Request }) { export async function DELETE({ request }) {
const url_fragments = request.url.split('/'); const url_fragments = request.url.split('/');
const item = url_fragments.at(-1); const item = url_fragments.at(-1);
const vorgang = url_fragments.at(-2); const vorgang = url_fragments.at(-2);

View File

@@ -4,21 +4,14 @@ import bcrypt from 'bcrypt';
const saltRounds = 12; const saltRounds = 12;
export function GET({ locals }) { export function GET() {
if (!locals.user) {
return json({ error: 'Unauthorized' }, { status: 401 });
}
const userList = getUsers(); const userList = getUsers();
return new Response(JSON.stringify(userList)); return new Response(JSON.stringify(userList));
} }
export async function POST({ request, locals }) { export async function POST({ request }) {
if (!locals.user) {
return json({ error: 'Unauthorized' }, { status: 401 });
}
const data = await request.json(); const data = await request.json();
const userName = data.userName; const userName = data.userName;
const userPassword = data.userPassword; const userPassword = data.userPassword;

View File

@@ -1,11 +1,7 @@
import { json } from '@sveltejs/kit'; import { json } from '@sveltejs/kit';
import { deleteUser } from '$lib/server/userService'; import { deleteUser } from '$lib/server/userService';
export async function DELETE({ params, locals }) { export async function DELETE({ params }) {
if (!locals.user) {
return json({ error: 'Unauthorized' }, { status: 401 });
}
const userId = params.user; const userId = params.user;
const rowCount = deleteUser(userId); const rowCount = deleteUser(userId);

View File

@@ -0,0 +1,37 @@
import { describe, test, expect, vi } from 'vitest';
import { handle } from '../../src/hooks.server';
const event = {
url: new URL("http://localhost/api/list"),
cookies: { get: vi.fn(() => null) },
locals: {user: null}
};
vi.mock('$lib/auth', () => ({
decryptToken: vi.fn()
}));
describe('API-Endpoints: Zugangs-Mechanismus', () => {
test('Unautorisierter Zugriff', async () => {
const resolve = vi.fn();
const response = await handle({ event, resolve });
expect(response.status).toBe(401);
const body = await response.json();
expect(body.error).toBe('Unauthorized');
expect(resolve).not.toHaveBeenCalled();
});
test('Authentifizierter Zugriff', async () => {
event.locals = {user: { id: 'admin', admin: true }}
const resolve = vi.fn(() => new Response('ok', { status: 200 }));
const response = await handle({ event, resolve });
expect(response.status).toBe(200);
expect(await response.text()).toBe('ok');
expect(resolve).toHaveBeenCalled();
});
})

View File

@@ -14,21 +14,6 @@ const event = {
}; };
describe('API-Endpoints: list', () => { describe('API-Endpoints: list', () => {
test.skip('Unerlaubter Zugriff', async () => {
const event = {
locals: {
user: null
}
};
const response = await GET(event);
expect(response.status).toBe(401);
const json = await response.json();
const errorObj = { error: 'Unauthorized' };
expect(json).toEqual(errorObj);
});
test('Leere Liste wenn keine Vorgänge existieren', async () => { test('Leere Liste wenn keine Vorgänge existieren', async () => {
vi.mocked(getVorgaenge).mockReturnValueOnce([]); vi.mocked(getVorgaenge).mockReturnValueOnce([]);

View File

@@ -31,21 +31,6 @@ const MockEvent = {
}; };
describe('API-Endpoints: list/[vorgang]', () => { describe('API-Endpoints: list/[vorgang]', () => {
test.skip('Unerlaubter Zugriff', async () => {
const event = {
locals: {
user: null
}
};
const response = await GET(event);
expect(response.status).toBe(401);
const json = await response.json();
const errorObj = { error: 'Unauthorized' };
expect(json).toEqual(errorObj);
});
test('Vorgang ohne Tatorte', async () => { test('Vorgang ohne Tatorte', async () => {
const testCrimesList = []; const testCrimesList = [];

View File

@@ -1,6 +1,7 @@
import { describe, test, expect, vi } from 'vitest'; import { describe, test, expect, vi } from 'vitest';
import { DELETE, PUT } from '$root/routes/api/list/[vorgang]/[tatort]/+server'; import { DELETE, PUT } from '$root/routes/api/list/[vorgang]/[tatort]/+server';
import { BUCKET, client } from '$lib/minio'; import { BUCKET, client } from '$lib/minio';
import { baseData } from '../fixtures';
// Mock data and methods // Mock data and methods
const fakeVorgangToken = `c399423a-ba37-4fe1-bbdf-80e5881168ff`; const fakeVorgangToken = `c399423a-ba37-4fe1-bbdf-80e5881168ff`;
@@ -22,7 +23,8 @@ vi.mock('$lib/minio', () => ({
describe('API-Endpoints: list/[vorgang]/[tatort]', () => { describe('API-Endpoints: list/[vorgang]/[tatort]', () => {
test('Löschen von Tatorten', async () => { test('Löschen von Tatorten', async () => {
const request = new Request(fakeCrimeAPIURL); const request = new Request(fakeCrimeAPIURL);
const response = await DELETE({ request }); const locals = { user: baseData.user }
const response = await DELETE({ locals, request });
expect(client.removeObject).toHaveBeenCalledWith(BUCKET, fakeCrimePath); expect(client.removeObject).toHaveBeenCalledWith(BUCKET, fakeCrimePath);
@@ -40,11 +42,12 @@ describe('API-Endpoints: list/[vorgang]/[tatort]', () => {
}) })
}); });
const params = { vorgang: fakeVorgangToken }; const params = { vorgang: fakeVorgangToken };
const locals = { user: baseData.user }
// Mock Datei nicht gefunden // Mock Datei nicht gefunden
client.statObject.mockRejectedValueOnce(new Error('NotFound')); client.statObject.mockRejectedValueOnce(new Error('NotFound'));
const response = await PUT({ params, request }); const response = await PUT({ locals, params, request });
const fakeCrimeNewPath = `${fakeVorgangToken}/${fakeCrimeNewName}`; const fakeCrimeNewPath = `${fakeVorgangToken}/${fakeCrimeNewName}`;
expect(client.statObject).toHaveBeenCalledWith(BUCKET, fakeCrimeNewPath); expect(client.statObject).toHaveBeenCalledWith(BUCKET, fakeCrimeNewPath);
@@ -62,9 +65,10 @@ describe('API-Endpoints: list/[vorgang]/[tatort]', () => {
newName: '' newName: ''
}) })
}); });
const locals = { user: baseData.user }
const params = { vorgang: fakeVorgangToken }; const params = { vorgang: fakeVorgangToken };
const response = await PUT({ params, request }); const response = await PUT({ locals, params, request });
expect(response.status).toBe(400); expect(response.status).toBe(400);
}); });
@@ -77,11 +81,12 @@ describe('API-Endpoints: list/[vorgang]/[tatort]', () => {
}) })
}); });
const params = { vorgang: fakeVorgangToken }; const params = { vorgang: fakeVorgangToken };
const locals = { user: baseData.user }
// Datei existiert bereits // Datei existiert bereits
client.statObject.mockResolvedValueOnce({}); client.statObject.mockResolvedValueOnce({});
const response = await PUT({ params, request }); const response = await PUT({ locals, params, request });
expect(response.status).toBe(400); expect(response.status).toBe(400);

View File

@@ -16,21 +16,6 @@ vi.mock('bcrypt', () => ({
})); }));
describe('API-Endpoint: Users', () => { describe('API-Endpoint: Users', () => {
test('Unerlaubter Zugriff', async () => {
const event = {
locals: {
user: null
}
};
const response = await GET(event);
expect(response.status).toBe(401);
const errorMessage = { error: 'Unauthorized' };
const json = await response.json();
expect(json).toEqual(errorMessage);
});
// [INFO] Test auf keine User nicht notwendig, da immer min. ein User vorhanden // [INFO] Test auf keine User nicht notwendig, da immer min. ein User vorhanden
// Mock eingelogter User bzw. stelle locals.user zur Verfügung // Mock eingelogter User bzw. stelle locals.user zur Verfügung

View File

@@ -1,9 +1,11 @@
import { describe, test, expect, vi } from 'vitest'; import { describe, test, expect, vi } from 'vitest';
import { GET } from '$root/routes/api/vorgang/[vorgang]/vorgangPIN/+server'; import { GET } from '$root/routes/api/vorgang/[vorgang]/vorgangPIN/+server';
import { db } from '$lib/server/dbService'; import { db } from '$lib/server/dbService';
import { baseData } from '../fixtures';
const mockEvent = { const mockEvent = {
params: { vorgang: '123' } params: { vorgang: '123' },
locals: { user: baseData.user }
}; };
vi.mock('$lib/server/dbService', () => ({ vi.mock('$lib/server/dbService', () => ({