Skip to content

Commit d9d69b8

Browse files
committed
fix(auth): gate dev-login from production registration
1 parent 8e4066e commit d9d69b8

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import cookie from '@fastify/cookie';
2+
import jwt from '@fastify/jwt';
3+
import Fastify from 'fastify';
4+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5+
6+
import { authRoutes } from '../routes/auth.js';
7+
8+
import type { PrismaClient } from '@prisma/client';
9+
10+
const mockUser = {
11+
id: 'user-123',
12+
username: 'devcard-demo',
13+
};
14+
15+
const prismaMock = {
16+
user: {
17+
findUnique: vi.fn(),
18+
},
19+
};
20+
21+
async function buildApp(nodeEnv: string) {
22+
vi.stubEnv('NODE_ENV', nodeEnv);
23+
24+
const app = Fastify();
25+
await app.register(jwt, { secret: 'test-secret' });
26+
await app.register(cookie);
27+
app.decorate('prisma', prismaMock as unknown as PrismaClient);
28+
app.decorate('authenticate', async () => {});
29+
await app.register(authRoutes, { prefix: '/auth' });
30+
await app.ready();
31+
return app;
32+
}
33+
34+
describe('auth dev-login route registration', () => {
35+
beforeEach(() => {
36+
vi.clearAllMocks();
37+
});
38+
39+
afterEach(() => {
40+
vi.unstubAllEnvs();
41+
});
42+
43+
it('registers /auth/dev-login outside production', async () => {
44+
prismaMock.user.findUnique.mockResolvedValue(mockUser);
45+
const app = await buildApp('development');
46+
47+
const res = await app.inject({
48+
method: 'POST',
49+
url: '/auth/dev-login',
50+
});
51+
52+
expect(res.statusCode).toBe(200);
53+
expect(res.json()).toHaveProperty('token');
54+
expect(prismaMock.user.findUnique).toHaveBeenCalledWith({
55+
where: { username: 'devcard-demo' },
56+
});
57+
58+
await app.close();
59+
});
60+
61+
it('does not register /auth/dev-login in production', async () => {
62+
const app = await buildApp('production');
63+
64+
const res = await app.inject({
65+
method: 'POST',
66+
url: '/auth/dev-login',
67+
});
68+
69+
expect(res.statusCode).toBe(404);
70+
expect(prismaMock.user.findUnique).not.toHaveBeenCalled();
71+
72+
await app.close();
73+
});
74+
75+
it('keeps other auth routes registered in production', async () => {
76+
const app = await buildApp('production');
77+
78+
const res = await app.inject({
79+
method: 'POST',
80+
url: '/auth/logout',
81+
});
82+
83+
expect(res.statusCode).toBe(200);
84+
expect(res.json()).toMatchObject({ message: 'Logged out' });
85+
86+
await app.close();
87+
});
88+
});

0 commit comments

Comments
 (0)