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(); }); });