- PGlite (in-memory WASM Postgres) hosted in a child process, exposed via TCP socket; real migrations applied with prisma migrate deploy - Vitest harness (vitest.integration.config.ts, global-setup spawns PGlite + built Nuxt server, per-test TRUNCATE, factories, cookie-jar API client); no mocks, zero production code changes - 50 tests across auth, hunt, team, submit, review, showcase, diashow incl. SuperJSON envelope check; *.itest.ts keeps bun test untouched - CI: parallel unit + integration jobs in .github/workflows/test.yml - tests/ covered by nuxt typecheck via tests/tsconfig.json reference
125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
import { beforeEach, describe, expect, it } from 'vitest';
|
|
import { newClient } from '../helpers/api';
|
|
import { resetDatabase } from '../helpers/database';
|
|
import { createUser, TEST_PASSWORD } from '../helpers/factories';
|
|
|
|
beforeEach(resetDatabase);
|
|
|
|
describe('register', () => {
|
|
it('creates a user and starts a session', async () => {
|
|
const client = newClient();
|
|
const res = await client.register(
|
|
'new-user@test.dev',
|
|
'New User',
|
|
'verysecret1'
|
|
);
|
|
expect(res.status).toBe(200);
|
|
const body = await res.json();
|
|
expect(body.success).toBe(true);
|
|
expect(body.user.id).toBeTypeOf('number');
|
|
|
|
// The register response already carries a session cookie.
|
|
const profile = await client.get('/api/auth/profile');
|
|
expect(profile.status).toBe(200);
|
|
expect(await profile.json()).toMatchObject({
|
|
name: 'New User',
|
|
email: 'new-user@test.dev',
|
|
uploadedFiles: []
|
|
});
|
|
});
|
|
|
|
it('rejects invalid input with 400', async () => {
|
|
const client = newClient();
|
|
// password too short
|
|
expect(
|
|
(await client.register('short@test.dev', 'Short', 'short')).status
|
|
).toBe(400);
|
|
// invalid email
|
|
expect(
|
|
(await client.register('not-an-email', 'NoMail', 'longenough1')).status
|
|
).toBe(400);
|
|
// empty name
|
|
expect(
|
|
(await client.register('empty@test.dev', '', 'longenough1')).status
|
|
).toBe(400);
|
|
});
|
|
|
|
it('rejects duplicate email with 409', async () => {
|
|
await createUser({ email: 'dupe@test.dev' });
|
|
const client = newClient();
|
|
const res = await client.register('dupe@test.dev', 'Dupe', 'verysecret1');
|
|
expect(res.status).toBe(409);
|
|
});
|
|
});
|
|
|
|
describe('login', () => {
|
|
it('logs in with correct credentials', async () => {
|
|
const user = await createUser({ email: 'login@test.dev' });
|
|
const client = newClient();
|
|
const res = await client.login('login@test.dev', TEST_PASSWORD);
|
|
expect(res.status).toBe(200);
|
|
expect(await res.json()).toEqual({
|
|
success: true,
|
|
user: { id: user.id }
|
|
});
|
|
|
|
const profile = await client.get('/api/auth/profile');
|
|
expect(profile.status).toBe(200);
|
|
});
|
|
|
|
it('rejects wrong password and unknown email with 404', async () => {
|
|
await createUser({ email: 'known@test.dev' });
|
|
const client = newClient();
|
|
expect(
|
|
(await client.login('known@test.dev', 'wrong-password-1')).status
|
|
).toBe(404);
|
|
expect((await client.login('unknown@test.dev', TEST_PASSWORD)).status).toBe(
|
|
404
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('profile', () => {
|
|
it('requires a session', async () => {
|
|
const res = await newClient().get('/api/auth/profile');
|
|
expect(res.status).toBe(401);
|
|
});
|
|
|
|
it('updates name and email', async () => {
|
|
await createUser({ email: 'update-me@test.dev' });
|
|
const client = newClient();
|
|
await client.login('update-me@test.dev', TEST_PASSWORD);
|
|
|
|
const res = await client.post('/api/auth/profile', {
|
|
name: 'Updated Name',
|
|
email: 'updated@test.dev'
|
|
});
|
|
expect(res.status).toBe(200);
|
|
expect(await res.json()).toEqual({ ok: true });
|
|
|
|
const profile = await client.get('/api/auth/profile');
|
|
expect(await profile.json()).toMatchObject({
|
|
name: 'Updated Name',
|
|
email: 'updated@test.dev'
|
|
});
|
|
|
|
// login works with the new email afterwards
|
|
expect(
|
|
(await newClient().login('updated@test.dev', TEST_PASSWORD)).status
|
|
).toBe(200);
|
|
});
|
|
|
|
it('rejects taking an existing email with 409', async () => {
|
|
await createUser({ email: 'first@test.dev' });
|
|
await createUser({ email: 'second@test.dev' });
|
|
const client = newClient();
|
|
await client.login('first@test.dev', TEST_PASSWORD);
|
|
|
|
const res = await client.post('/api/auth/profile', {
|
|
name: 'First User',
|
|
email: 'second@test.dev'
|
|
});
|
|
expect(res.status).toBe(409);
|
|
});
|
|
});
|