test(api): Auth & /me — fill gaps + lifecycle test
This commit is contained in:
32
apps/api/test/integration/auth-lifecycle.test.ts
Normal file
32
apps/api/test/integration/auth-lifecycle.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { createApp } from '../../src/app';
|
||||
import { authToken, bearer, resetDb } from '../helpers';
|
||||
|
||||
describe('auth lifecycle (create worker → sign in → /api/me → admin route 403)', () => {
|
||||
beforeEach(resetDb);
|
||||
|
||||
it('issues a bearer that authorizes /api/me as a worker but not admin routes', async () => {
|
||||
const app = createApp();
|
||||
const token = await authToken(app, 'auth-lifecycle@example.com', 'worker');
|
||||
|
||||
// /api/me returns the full worker identity for the freshly-issued token.
|
||||
const meRes = await app.request('/api/me', { headers: bearer(token) });
|
||||
expect(meRes.status).toBe(200);
|
||||
const { user } = await meRes.json();
|
||||
expect(user).toEqual({
|
||||
id: expect.any(String),
|
||||
email: 'auth-lifecycle@example.com',
|
||||
name: 'auth-lifecycle',
|
||||
role: 'worker',
|
||||
});
|
||||
|
||||
// The same token is rejected by an admin-only route (worker is not an admin).
|
||||
const adminRes = await app.request('/api/admin/users', { headers: bearer(token) });
|
||||
expect(adminRes.status).toBe(403);
|
||||
|
||||
// The bearer keeps working across repeated requests (stateless token, not one-shot).
|
||||
for (let i = 0; i < 3; i++) {
|
||||
expect((await app.request('/api/me', { headers: bearer(token) })).status).toBe(200);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user