f100_backend_api-endpoints_tests #31
64
tests/APIList.test.ts
Normal file
64
tests/APIList.test.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { describe, test, expect, vi } from 'vitest';
|
||||
import { GET } from '../src/routes/api/list/+server';
|
||||
import { getVorgaenge } from '$lib/server/vorgangService';
|
||||
|
||||
// Mocks
|
||||
vi.mock('$lib/server/vorgangService', () => ({
|
||||
getVorgaenge: vi.fn()
|
||||
}));
|
||||
|
||||
const event = {
|
||||
locals: {
|
||||
user: { id: 'admin', admin: true }
|
||||
}
|
||||
};
|
||||
|
||||
describe('API-Endpoints: list', () => {
|
||||
test('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 () => {
|
||||
vi.mocked(getVorgaenge).mockReturnValueOnce([]);
|
||||
|
||||
const response = await GET(event);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual([]);
|
||||
});
|
||||
|
||||
test('Liste mit existierenden Vorgängen', async () => {
|
||||
const testVorgaenge = [
|
||||
{
|
||||
vorgangToken: '19f1d34e-4f31-48e8-830f-c4e42c29085e',
|
||||
vorgangName: 'xyz-123',
|
||||
vorgangPIN: 'pin-123'
|
||||
},
|
||||
{
|
||||
vorgangToken: '7596e4d5-c51f-482d-a4aa-ff76434305fc',
|
||||
vorgangName: 'vorgang-2',
|
||||
vorgangPIN: 'pin-2'
|
||||
}
|
||||
];
|
||||
|
||||
vi.mocked(getVorgaenge).mockReturnValueOnce(testVorgaenge);
|
||||
|
||||
const response = await GET(event);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(testVorgaenge);
|
||||
});
|
||||
});
|
||||
136
tests/APIListVorgang.test.ts
Normal file
136
tests/APIListVorgang.test.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import { describe, test, expect, vi } from 'vitest';
|
||||
import { DELETE, GET, HEAD } from '../src/routes/api/list/[vorgang]/+server';
|
||||
import {
|
||||
getCrimesListByToken,
|
||||
vorgangNameExists,
|
||||
deleteVorgangByToken
|
||||
} from '$lib/server/vorgangService';
|
||||
import { client } from '$lib/minio';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
// Mocks
|
||||
vi.mock('$lib/server/vorgangService', () => ({
|
||||
getCrimesListByToken: vi.fn(),
|
||||
vorgangNameExists: vi.fn(),
|
||||
deleteVorgangByToken: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('$lib/minio', () => ({
|
||||
client: {
|
||||
listObjects: vi.fn(),
|
||||
removeObjects: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
const MockEvent = {
|
||||
params: { vorgang: '123' },
|
||||
locals: {
|
||||
user: { id: 'admin', admin: true }
|
||||
}
|
||||
};
|
||||
|
||||
describe('API-Endpoints: list/[vorgang]', () => {
|
||||
test('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 () => {
|
||||
const testCrimesList = [];
|
||||
|
||||
vi.mocked(getCrimesListByToken).mockReturnValueOnce(testCrimesList);
|
||||
|
||||
const response = await GET(MockEvent);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(testCrimesList);
|
||||
});
|
||||
|
||||
test('Vorgang mit Tatorte', async () => {
|
||||
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
|
||||
}
|
||||
];
|
||||
|
||||
vi.mocked(getCrimesListByToken).mockReturnValueOnce(testCrimesList);
|
||||
|
||||
const response = await GET(MockEvent);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(testCrimesList);
|
||||
});
|
||||
|
||||
test('Vorgang existiert via HEAD', async () => {
|
||||
const vorgangExists = true;
|
||||
vi.mocked(vorgangNameExists).mockReturnValueOnce(vorgangExists);
|
||||
|
||||
const response = await HEAD(MockEvent);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const textContent = await response.text();
|
||||
expect(textContent).toEqual('');
|
||||
});
|
||||
|
||||
test('Vorgang existiert nicht via HEAD', async () => {
|
||||
const vorgangExists = false;
|
||||
vi.mocked(vorgangNameExists).mockReturnValueOnce(vorgangExists);
|
||||
const response = await HEAD(MockEvent);
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
const textContent = await response.text();
|
||||
|
||||
expect(textContent).toEqual('');
|
||||
});
|
||||
|
||||
test('Lösche Vorgang und dazugehörige S3 Objekte', async () => {
|
||||
// Mock data
|
||||
const fakeStream = new EventEmitter();
|
||||
vi.mocked(client.listObjects).mockReturnValue(fakeStream);
|
||||
vi.mocked(client.removeObjects).mockResolvedValue(undefined);
|
||||
vi.mocked(deleteVorgangByToken).mockReturnValueOnce(undefined);
|
||||
|
||||
const responsePromise = DELETE(MockEvent);
|
||||
const fakeCrimeNames = [
|
||||
`${MockEvent.params.vorgang}/file1.glb`,
|
||||
`${MockEvent.params.vorgang}/file2.glb`
|
||||
];
|
||||
|
||||
// simulate data stream
|
||||
fakeStream.emit('data', { name: fakeCrimeNames[0] });
|
||||
fakeStream.emit('data', { name: fakeCrimeNames[1] });
|
||||
fakeStream.emit('end');
|
||||
|
||||
const response = await responsePromise;
|
||||
|
||||
expect(client.removeObjects).toHaveBeenCalledWith('tatort', fakeCrimeNames);
|
||||
expect(deleteVorgangByToken).toHaveBeenCalledWith(MockEvent.params.vorgang);
|
||||
|
||||
expect(response.status).toBe(204);
|
||||
});
|
||||
});
|
||||
93
tests/APIListVorgangTatort.test.ts
Normal file
93
tests/APIListVorgangTatort.test.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { describe, test, expect, vi } from 'vitest';
|
||||
import { DELETE, PUT } from '../src/routes/api/list/[vorgang]/[tatort]/+server';
|
||||
import { BUCKET, client } from '$lib/minio';
|
||||
|
||||
// Mock data and methods
|
||||
const fakeVorgangToken = `c399423a-ba37-4fe1-bbdf-80e5881168ff`;
|
||||
const fakeCrimeOldName = `model-A`;
|
||||
const fakeCrimeNewName = 'model-Z';
|
||||
const fakeCrimePath = `${fakeVorgangToken}/${fakeCrimeOldName}`;
|
||||
const fullFakeCrimePath = `/${BUCKET}/${fakeCrimePath}`;
|
||||
const fakeCrimeAPIURL = `http://localhost:5173/api/list/${fakeCrimePath}`;
|
||||
|
||||
vi.mock('$lib/minio', () => ({
|
||||
client: {
|
||||
removeObject: vi.fn(),
|
||||
statObject: vi.fn(),
|
||||
copyObject: vi.fn()
|
||||
},
|
||||
BUCKET: 'tatort'
|
||||
}));
|
||||
|
||||
describe('API-Endpoints: list/[vorgang]/[tatort]', () => {
|
||||
test('Löschen von Tatorten', async () => {
|
||||
const request = new Request(fakeCrimeAPIURL);
|
||||
const response = await DELETE({ request });
|
||||
|
||||
expect(client.removeObject).toHaveBeenCalledWith(BUCKET, fakeCrimePath);
|
||||
|
||||
expect(response.status).toBe(204);
|
||||
const responseBody = await response.text();
|
||||
expect(responseBody).toBe('');
|
||||
});
|
||||
|
||||
test('Umbennen von Tatorten: Erfolgreich', async () => {
|
||||
const request = new Request(fakeCrimeAPIURL, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
oldName: fakeCrimeOldName,
|
||||
newName: fakeCrimeNewName
|
||||
})
|
||||
});
|
||||
const params = { vorgang: fakeVorgangToken };
|
||||
|
||||
// Mock Datei nicht gefunden
|
||||
client.statObject.mockRejectedValueOnce(new Error('NotFound'));
|
||||
|
||||
const response = await PUT({ params, request });
|
||||
|
||||
const fakeCrimeNewPath = `${fakeVorgangToken}/${fakeCrimeNewName}`;
|
||||
expect(client.statObject).toHaveBeenCalledWith(BUCKET, fakeCrimeNewPath);
|
||||
expect(client.copyObject).toHaveBeenCalledWith(BUCKET, fakeCrimeNewPath, fullFakeCrimePath);
|
||||
expect(client.removeObject).toHaveBeenCalledWith(BUCKET, fakeCrimePath);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
test('Umbennen von Tatorten: Fehlende(r) Name', async () => {
|
||||
const request = new Request(fakeCrimeAPIURL, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
oldName: '',
|
||||
newName: ''
|
||||
})
|
||||
});
|
||||
const params = { vorgang: fakeVorgangToken };
|
||||
|
||||
const response = await PUT({ params, request });
|
||||
expect(response.status).toBe(400);
|
||||
});
|
||||
|
||||
test('Umbennen von Tatorten: Existierender Name', async () => {
|
||||
const request = new Request(fakeCrimeAPIURL, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
oldName: fakeCrimeOldName,
|
||||
newName: fakeCrimeNewName
|
||||
})
|
||||
});
|
||||
const params = { vorgang: fakeVorgangToken };
|
||||
|
||||
// Datei existiert bereits
|
||||
client.statObject.mockResolvedValueOnce({});
|
||||
|
||||
const response = await PUT({ params, request });
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
|
||||
const fakeCrimeNewPath = `${fakeVorgangToken}/${fakeCrimeNewName}`;
|
||||
expect(client.statObject).toHaveBeenCalledWith(BUCKET, fakeCrimeNewPath);
|
||||
expect(client.copyObject).not.toHaveBeenCalled();
|
||||
expect(client.removeObject).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
40
tests/APIUser.test.ts
Normal file
40
tests/APIUser.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import { GET } from '../src/routes/api/user/+server';
|
||||
|
||||
const id = 'admin';
|
||||
|
||||
describe('API-Endpoints: User ist Admin', () => {
|
||||
test('User ist Admin', async () => {
|
||||
const admin = true;
|
||||
const event = {
|
||||
locals: {
|
||||
user: { id, admin }
|
||||
}
|
||||
};
|
||||
|
||||
const fakeResult = { admin };
|
||||
|
||||
const response = await GET(event);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(fakeResult);
|
||||
});
|
||||
|
||||
test('User ist kein Admin', async () => {
|
||||
const admin = false;
|
||||
const event = {
|
||||
locals: {
|
||||
user: { id, admin }
|
||||
}
|
||||
};
|
||||
|
||||
const fakeResult = { admin };
|
||||
|
||||
const response = await GET(event);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(fakeResult);
|
||||
});
|
||||
});
|
||||
163
tests/APIUsers.test.ts
Normal file
163
tests/APIUsers.test.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import { describe, test, expect, vi, beforeEach } from 'vitest';
|
||||
import { GET, POST } from '../src/routes/api/users/+server';
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
import { addUser, getUsers } from '$lib/server/userService';
|
||||
|
||||
vi.mock('$lib/server/userService', () => ({
|
||||
addUser: vi.fn(),
|
||||
getUsers: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('bcrypt', () => ({
|
||||
default: {
|
||||
hashSync: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
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
|
||||
|
||||
// Mock eingelogter User bzw. stelle locals.user zur Verfügung
|
||||
const fakeLoggedInUser = { id: 'admin', admin: true };
|
||||
const mockLocals = {
|
||||
user: fakeLoggedInUser
|
||||
};
|
||||
|
||||
test('Rufe Liste aller User ab', async () => {
|
||||
const fakeLoggedInUser = { id: 'admin', admin: true };
|
||||
const event = {
|
||||
locals: {
|
||||
user: fakeLoggedInUser
|
||||
}
|
||||
};
|
||||
|
||||
const fakeResult = [{ userId: 42, userName: 'admin' }];
|
||||
getUsers.mockReturnValueOnce(fakeResult);
|
||||
|
||||
const response = await GET(event);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(fakeResult);
|
||||
});
|
||||
|
||||
test('Füge Benutzer hinzu: Erfolgreich', async () => {
|
||||
// Mocke Parameter und Funktionen von Drittparteien
|
||||
const fakeUsersAPIURL = `http://localhost:5173/api/users`;
|
||||
const fakeUserID = 42;
|
||||
const fakeUsername = 'admin';
|
||||
const fakeUserPassword = 'pass-123';
|
||||
|
||||
const mockRequest = new Request(fakeUsersAPIURL, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
userName: fakeUsername,
|
||||
userPassword: fakeUserPassword
|
||||
})
|
||||
});
|
||||
|
||||
const mockedHash = 'mocked-hash';
|
||||
bcrypt.hashSync.mockReturnValueOnce(mockedHash);
|
||||
|
||||
const mockedRowInfo = {
|
||||
changes: 1,
|
||||
lastInsertRowid: fakeUserID
|
||||
};
|
||||
addUser.mockReturnValueOnce(mockedRowInfo);
|
||||
|
||||
const response = await POST({
|
||||
request: mockRequest,
|
||||
locals: mockLocals
|
||||
});
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
|
||||
const fakeResult = { userId: fakeUserID, userName: fakeUsername };
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(fakeResult);
|
||||
|
||||
expect(addUser).toHaveBeenCalledWith(fakeUsername, mockedHash);
|
||||
});
|
||||
|
||||
test('Füge Benutzer hinzu: Fehlender Name oder Passwort', async () => {
|
||||
// Mocke Parameter und Funktionen von Drittparteien
|
||||
const fakeUsersAPIURL = `http://localhost:5173/api/users`;
|
||||
const fakeUserID = 42;
|
||||
const fakeUsername = '';
|
||||
const fakeUserPassword = '';
|
||||
|
||||
const mockRequest = new Request(fakeUsersAPIURL, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
userName: fakeUsername,
|
||||
userPassword: fakeUserPassword
|
||||
})
|
||||
});
|
||||
|
||||
const response = await POST({
|
||||
request: mockRequest,
|
||||
locals: mockLocals
|
||||
});
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
|
||||
const errorMessage = { error: 'Missing input' };
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(errorMessage);
|
||||
|
||||
expect(addUser).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Füge Benutzer hinzu: Nicht erfolgreich, keine Datenbankänderung', async () => {
|
||||
// Mocke Parameter und Funktionen von Drittparteien
|
||||
const fakeUsersAPIURL = `http://localhost:5173/api/users`;
|
||||
const fakeUserID = 42;
|
||||
const fakeUsername = 'admin';
|
||||
const fakeUserPassword = 'pass-123';
|
||||
|
||||
const mockRequest = new Request(fakeUsersAPIURL, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
userName: fakeUsername,
|
||||
userPassword: fakeUserPassword
|
||||
})
|
||||
});
|
||||
|
||||
const mockedHash = 'mocked-hash';
|
||||
bcrypt.hashSync.mockReturnValueOnce(mockedHash);
|
||||
|
||||
const mockedRowInfo = {
|
||||
changes: 0,
|
||||
lastInsertRowid: fakeUserID
|
||||
};
|
||||
addUser.mockReturnValueOnce(mockedRowInfo);
|
||||
|
||||
const response = await POST({
|
||||
request: mockRequest,
|
||||
locals: mockLocals
|
||||
});
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
|
||||
const body = await response.text();
|
||||
expect(body).toEqual('');
|
||||
|
||||
expect(addUser).toHaveBeenCalledWith(fakeUsername, mockedHash);
|
||||
});
|
||||
});
|
||||
43
tests/APIVorgangVorgangVorgangPIN.test.ts
Normal file
43
tests/APIVorgangVorgangVorgangPIN.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { describe, test, expect, vi } from 'vitest';
|
||||
import { GET } from '../src/routes/api/vorgang/[vorgang]/vorgangPIN/+server';
|
||||
import { db } from '$lib/server/dbService';
|
||||
|
||||
const mockEvent = {
|
||||
params: { vorgang: '123' }
|
||||
};
|
||||
|
||||
vi.mock('$lib/server/dbService', () => ({
|
||||
db: {
|
||||
prepare: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
describe('API-Endpoint: Vorgang-PIN', () => {
|
||||
test('Vorgang PIN: Erfolgreich', async () => {
|
||||
// only interested in PIN value
|
||||
const mockPIN = 'pin-123';
|
||||
const mockRow = { pin: mockPIN };
|
||||
|
||||
const getMock = vi.fn().mockReturnValue(mockRow);
|
||||
|
||||
db.prepare.mockReturnValue({ get: getMock });
|
||||
const response = await GET(mockEvent);
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const body = await response.text();
|
||||
expect(body).toEqual(mockPIN);
|
||||
});
|
||||
|
||||
test('Vorgang PIN: Nicht erfolgreich', async () => {
|
||||
const mockRow = {};
|
||||
|
||||
const getMock = vi.fn().mockReturnValue(mockRow);
|
||||
|
||||
db.prepare.mockReturnValue({ get: getMock });
|
||||
const response = await GET(mockEvent);
|
||||
expect(response.status).toBe(404);
|
||||
|
||||
const body = await response.text();
|
||||
expect(body).toEqual('');
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@ export default defineConfig({
|
||||
name: 'client',
|
||||
environment: 'jsdom',
|
||||
clearMocks: true,
|
||||
include: ['src/**/*.svelte.{test,spec}.{js,ts}'],
|
||||
include: ['tests/**/*.{test,spec}.{js,ts}', 'src/**/*.svelte.{test,spec}.{js,ts}'],
|
||||
exclude: ['src/lib/server/**'],
|
||||
setupFiles: ['./vitest-setup-client.ts']
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user