Add auth role to api
This commit is contained in:
1 parent
9a476d9b86
commit
f27d87531c
6 files changed
+364
No files matched your search
@@ -0,0 +1,88 @@
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createAuthRouter } from './auth.router.ts';
|
||||
import { AuthService } from './auth.service.ts';
|
||||
import { Pool } from 'pg';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
function createMockResponse() {
|
||||
const res: Partial<Response> = {};
|
||||
const data = { statusCode: 200, jsonPayload: null as any, cookies: {} as any };
|
||||
|
||||
res.status = function (code: number) { data.statusCode = code; return this as Response; };
|
||||
res.json = function (payload: any) { data.jsonPayload = payload; return this as Response; };
|
||||
res.cookie = function (name: string, val: string, options: any) {
|
||||
data.cookies[name] = { val, options };
|
||||
return this as Response;
|
||||
};
|
||||
return { mockRes: res as Response, data };
|
||||
}
|
||||
|
||||
function createMockDb(userRows: any[], sessionRows: any[] = []) {
|
||||
return {
|
||||
query: async (text: string, values: any[]) => {
|
||||
if (text.trim().startsWith('SELECT') && text.includes('FROM users')) {
|
||||
return { rows: userRows };
|
||||
}
|
||||
return { rows: sessionRows };
|
||||
}
|
||||
} as unknown as Pool;
|
||||
}
|
||||
|
||||
describe('Auth Router (TDD)', () => {
|
||||
const authService = new AuthService();
|
||||
|
||||
describe('POST /register', () => {
|
||||
it('should block registrations missing username or password with a 400 status', async () => {
|
||||
const mockDb = createMockDb([]);
|
||||
const router = createAuthRouter(mockDb, authService);
|
||||
|
||||
const mockReq = { body: { username: '' } } as unknown as Request;
|
||||
const { mockRes, data } = createMockResponse();
|
||||
|
||||
const handler = router.stack.find((l: any) => l.route.path === '/register').route.stack[0].handle;
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
assert.equal(data.statusCode, 400);
|
||||
assert.equal(data.jsonPayload.success, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /login', () => {
|
||||
it('should successfully issue a high-entropy cookie on valid credentials', async () => {
|
||||
const password = 'secure-password';
|
||||
const hash = await authService.hashPassword(password);
|
||||
|
||||
// Simulate database finding the registered user
|
||||
const mockDb = createMockDb([{ id: 42, username: 'testuser', password_hash: hash }]);
|
||||
const router = createAuthRouter(mockDb, authService);
|
||||
|
||||
const mockReq = { body: { username: 'testuser', password } } as unknown as Request;
|
||||
const { mockRes, data } = createMockResponse();
|
||||
|
||||
const handler = router.stack.find((l: any) => l.route.path === '/login').route.stack[0].handle;
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
assert.equal(data.statusCode, 200);
|
||||
assert.equal(data.jsonPayload.success, true);
|
||||
assert.ok(data.cookies['session_token']);
|
||||
assert.equal(data.cookies['session_token'].options.httpOnly, true);
|
||||
assert.equal(data.cookies['session_token'].options.sameSite, 'strict');
|
||||
});
|
||||
|
||||
it('should reject invalid passwords with a 401 status code', async () => {
|
||||
const hash = await authService.hashPassword('real-password');
|
||||
const mockDb = createMockDb([{ id: 42, username: 'testuser', password_hash: hash }]);
|
||||
const router = createAuthRouter(mockDb, authService);
|
||||
|
||||
const mockReq = { body: { username: 'testuser', password: 'wrong-password' } } as unknown as Request;
|
||||
const { mockRes, data } = createMockResponse();
|
||||
|
||||
const handler = router.stack.find((l: any) => l.route.path === '/login').route.stack[0].handle;
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
assert.equal(data.statusCode, 401);
|
||||
assert.equal(data.jsonPayload.success, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user