Initial commit: digital reception monorepo (M1-M11 + demo extensions)
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import type { INestApplication } from '@nestjs/common';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import request from 'supertest';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import { AppModule } from '../src/app.module';
|
||||
import { PrismaService } from '../src/prisma/prisma.service';
|
||||
|
||||
describe('Auth (e2e)', () => {
|
||||
let app: INestApplication;
|
||||
let prisma: PrismaService;
|
||||
|
||||
const SENIOR_EMAIL = 'senior@local';
|
||||
const SENIOR_PASSWORD = process.env.SEED_PASSWORD_SENIOR ?? 'senior123';
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = module.createNestApplication();
|
||||
app.use(cookieParser());
|
||||
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
|
||||
await app.init();
|
||||
prisma = app.get(PrismaService);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it('GET /health is public', async () => {
|
||||
const res = await request(app.getHttpServer()).get('/health');
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.status).toBe('ok');
|
||||
});
|
||||
|
||||
it('GET /auth/me requires auth', async () => {
|
||||
const res = await request(app.getHttpServer()).get('/auth/me');
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
it('POST /auth/login returns access cookie and userId', async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post('/auth/login')
|
||||
.send({ email: SENIOR_EMAIL, password: SENIOR_PASSWORD });
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.userId).toBeDefined();
|
||||
const cookies = (res.headers['set-cookie'] as unknown as string[]) ?? [];
|
||||
expect(cookies.some((c) => c.startsWith('access_token='))).toBe(true);
|
||||
expect(cookies.some((c) => c.startsWith('refresh_token='))).toBe(true);
|
||||
});
|
||||
|
||||
it('GET /auth/me with cookie returns user + role', async () => {
|
||||
const loginRes = await request(app.getHttpServer())
|
||||
.post('/auth/login')
|
||||
.send({ email: SENIOR_EMAIL, password: SENIOR_PASSWORD });
|
||||
const cookies = (loginRes.headers['set-cookie'] as unknown as string[]) ?? [];
|
||||
|
||||
const meRes = await request(app.getHttpServer())
|
||||
.get('/auth/me')
|
||||
.set('Cookie', cookies);
|
||||
|
||||
expect(meRes.status).toBe(200);
|
||||
expect(meRes.body.email).toBe(SENIOR_EMAIL);
|
||||
expect(meRes.body.role).toBe('SENIOR_ADMIN');
|
||||
});
|
||||
|
||||
it('POST /auth/login with bad password → 401', async () => {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post('/auth/login')
|
||||
.send({ email: SENIOR_EMAIL, password: 'wrong-password' });
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
|
||||
it('POST /auth/logout clears tokens', async () => {
|
||||
const loginRes = await request(app.getHttpServer())
|
||||
.post('/auth/login')
|
||||
.send({ email: SENIOR_EMAIL, password: SENIOR_PASSWORD });
|
||||
const cookies = (loginRes.headers['set-cookie'] as unknown as string[]) ?? [];
|
||||
|
||||
const logoutRes = await request(app.getHttpServer())
|
||||
.post('/auth/logout')
|
||||
.set('Cookie', cookies);
|
||||
|
||||
expect(logoutRes.status).toBe(200);
|
||||
|
||||
// Используем тот же refresh — должен быть отозван.
|
||||
const refreshCookie = cookies.find((c) => c.startsWith('refresh_token='));
|
||||
expect(refreshCookie).toBeDefined();
|
||||
|
||||
const refreshRes = await request(app.getHttpServer())
|
||||
.post('/auth/refresh')
|
||||
.set('Cookie', refreshCookie!);
|
||||
|
||||
expect(refreshRes.status).toBe(401);
|
||||
});
|
||||
|
||||
describe('refresh token rotation', () => {
|
||||
it('issues new tokens with valid refresh', async () => {
|
||||
const loginRes = await request(app.getHttpServer())
|
||||
.post('/auth/login')
|
||||
.send({ email: SENIOR_EMAIL, password: SENIOR_PASSWORD });
|
||||
const cookies = (loginRes.headers['set-cookie'] as unknown as string[]) ?? [];
|
||||
const refreshCookie = cookies.find((c) => c.startsWith('refresh_token='))!;
|
||||
|
||||
const refreshRes = await request(app.getHttpServer())
|
||||
.post('/auth/refresh')
|
||||
.set('Cookie', refreshCookie);
|
||||
|
||||
expect(refreshRes.status).toBe(200);
|
||||
const newCookies = (refreshRes.headers['set-cookie'] as unknown as string[]) ?? [];
|
||||
expect(newCookies.some((c) => c.startsWith('access_token='))).toBe(true);
|
||||
|
||||
// Старый refresh теперь невалиден — должен быть отозван.
|
||||
const reuseRes = await request(app.getHttpServer())
|
||||
.post('/auth/refresh')
|
||||
.set('Cookie', refreshCookie);
|
||||
expect(reuseRes.status).toBe(401);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user