import { describe, it, expect } from 'vitest'; import type { Hono } from 'hono'; import { createApp } from '../src/app'; import { authToken, bearer } from './helpers'; const PASSWORD = 'sterk-wachtwoord-123'; async function signInStatus(app: Hono, email: string, password: string): Promise { const res = await app.request('/api/auth/sign-in/email', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email, password }), }); return res.status; } describe('GET /api/admin/users', () => { it('401s without a token, 403s for a worker', async () => { const app = createApp(); expect((await app.request('/api/admin/users')).status).toBe(401); const workerTok = await authToken(app, 'users-list-worker@example.com'); expect((await app.request('/api/admin/users', { headers: bearer(workerTok) })).status).toBe( 403, ); }); it('returns each user with role and status', async () => { const app = createApp(); const adminTok = await authToken(app, 'users-list-admin@example.com', 'admin'); await authToken(app, 'users-list-w@example.com'); // a worker const res = await app.request('/api/admin/users', { headers: bearer(adminTok) }); expect(res.status).toBe(200); const users = await res.json(); const admin = users.find((u: { email: string }) => u.email === 'users-list-admin@example.com'); const worker = users.find((u: { email: string }) => u.email === 'users-list-w@example.com'); expect(admin.role).toBe('admin'); expect(admin.status).toBe('active'); expect(worker.role).toBe('worker'); expect(worker.status).toBe('active'); }); }); describe('POST /api/admin/users', () => { it('creates a user who can then sign in', async () => { const app = createApp(); const adminTok = await authToken(app, 'users-create-admin@example.com', 'admin'); const res = await app.request('/api/admin/users', { method: 'POST', headers: bearer(adminTok), body: JSON.stringify({ email: 'created-worker@example.com', name: 'Nieuwe Werker', password: PASSWORD, role: 'worker', }), }); expect(res.status).toBe(200); const created = await res.json(); expect(created.email).toBe('created-worker@example.com'); expect(created.role).toBe('worker'); expect(created.status).toBe('active'); expect(await signInStatus(app, 'created-worker@example.com', PASSWORD)).toBe(200); }); it('rejects a duplicate email with 409', async () => { const app = createApp(); const adminTok = await authToken(app, 'users-dup-admin@example.com', 'admin'); const body = JSON.stringify({ email: 'dup@example.com', name: 'Dup', password: PASSWORD, role: 'worker', }); expect( (await app.request('/api/admin/users', { method: 'POST', headers: bearer(adminTok), body })) .status, ).toBe(200); expect( (await app.request('/api/admin/users', { method: 'POST', headers: bearer(adminTok), body })) .status, ).toBe(409); }); it('rejects a too-short password with 400', async () => { const app = createApp(); const adminTok = await authToken(app, 'users-shortpw-admin@example.com', 'admin'); const res = await app.request('/api/admin/users', { method: 'POST', headers: bearer(adminTok), body: JSON.stringify({ email: 'short@example.com', name: 'S', password: 'short', role: 'worker', }), }); expect(res.status).toBe(400); }); it('403s for a worker', async () => { const app = createApp(); const workerTok = await authToken(app, 'users-create-worker@example.com'); const res = await app.request('/api/admin/users', { method: 'POST', headers: bearer(workerTok), body: JSON.stringify({ email: 'x@example.com', name: 'X', password: PASSWORD, role: 'worker', }), }); expect(res.status).toBe(403); }); });