feat: harden bootstrap and add tests

This commit is contained in:
2026-06-28 16:43:03 -05:00
parent 01ea9e391d
commit 991e73fcff
39 changed files with 3399 additions and 459 deletions
+52
View File
@@ -0,0 +1,52 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { authenticateUser, createUser, hashPassword, verifyPassword } from '@/lib/auth';
const { query } = vi.hoisted(() => ({ query: vi.fn() }));
vi.mock('@/lib/db', () => ({
db: {
query,
},
}));
describe('auth helpers', () => {
beforeEach(() => {
query.mockReset();
});
it('hashes passwords before storing a user', async () => {
query.mockResolvedValueOnce({ rows: [{ id: 1, username: 'alice', role: 'user' }] });
const user = await createUser('alice', 's3cret', 'user');
expect(user).toEqual({ id: 1, username: 'alice', role: 'user' });
expect(query).toHaveBeenCalledTimes(1);
const [, params] = query.mock.calls[0];
expect(params[0]).toBe('alice');
expect(params[1]).not.toBe('s3cret');
expect(await verifyPassword('s3cret', params[1] as string)).toBe(true);
});
it('authenticates a user with the stored password hash', async () => {
const passwordHash = await hashPassword('secret-password');
query.mockResolvedValueOnce({
rows: [{ id: 2, username: 'bob', password_hash: passwordHash, role: 'admin' }],
});
await expect(authenticateUser('bob', 'secret-password')).resolves.toEqual({
id: 2,
username: 'bob',
role: 'admin',
});
});
it('rejects an invalid password', async () => {
const passwordHash = await hashPassword('secret-password');
query.mockResolvedValueOnce({
rows: [{ id: 2, username: 'bob', password_hash: passwordHash, role: 'admin' }],
});
await expect(authenticateUser('bob', 'wrong-password')).resolves.toBeNull();
});
});