Files
kooltab-backoffice/apps/api/test/app.e2e-spec.ts
T
brammie15 fa38ac7617
CI / build-and-test (push) Canceled after 0s
fix: alot
2026-10-19 21:41:07 +02:00

125 lines
3.8 KiB
TypeScript

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import request = require('supertest');
import { AppModule } from '../src/app.module';
import { PrismaService } from '../src/prisma/prisma.service';
import { HttpExceptionFilter } from '../src/common/filters/http-exception.filter';
describe('KoolTap API (e2e)', () => {
let app: INestApplication;
let prisma: PrismaService;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
app.setGlobalPrefix('api/v1');
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
app.useGlobalFilters(new HttpExceptionFilter());
prisma = app.get(PrismaService);
await app.init();
});
afterAll(async () => {
await app.close();
});
describe('Health', () => {
it('GET /api/v1/health should return ok', () => {
return request(app.getHttpServer())
.get('/api/v1/health')
.expect(200)
.expect((res) => {
expect(res.body.status).toBe('ok');
});
});
});
describe('Auth', () => {
it('POST /api/v1/auth/login with invalid credentials should return 401', () => {
return request(app.getHttpServer())
.post('/api/v1/auth/login')
.send({ email: 'nonexistent@test.com', password: 'wrong-password' })
.expect(401);
});
it('POST /api/v1/auth/login with valid credentials should return tokens', async () => {
// First create a user via seed or directly
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash('Test123!', 10);
const { v4: uuid } = require('uuid');
const venueId = uuid();
const email = `test-${venueId}@test.com`;
await prisma.venue.create({
data: { id: venueId, name: 'Test Venue' },
});
await prisma.clientUser.create({
data: {
id: uuid(),
venueId,
email,
passwordHash: hash,
name: 'Test User',
role: 'admin',
},
});
return request(app.getHttpServer())
.post('/api/v1/auth/login')
.send({ email, password: 'Test123!' })
.expect(200)
.expect((res) => {
expect(res.body.accessToken).toBeDefined();
expect(res.body.refreshToken).toBeDefined();
expect(res.body.user.email).toBe(email);
});
});
});
describe('Venue isolation', () => {
it('should not allow cross-venue access', async () => {
const bcrypt = require('bcrypt');
const { v4: uuid } = require('uuid');
const venueAId = uuid();
const venueBId = uuid();
const email = `venuea-${venueAId}@test.com`;
await prisma.venue.create({ data: { id: venueAId, name: 'Venue A' } });
await prisma.venue.create({ data: { id: venueBId, name: 'Venue B' } });
const hash = await bcrypt.hash('Pass123!', 10);
await prisma.clientUser.create({
data: {
id: uuid(),
venueId: venueAId,
email,
passwordHash: hash,
name: 'Venue A User',
role: 'admin',
},
});
// Login as Venue A user
const loginRes = await request(app.getHttpServer())
.post('/api/v1/auth/login')
.send({ email, password: 'Pass123!' })
.expect(200);
const token = loginRes.body.accessToken;
// Try to access Venue B data
await request(app.getHttpServer())
.get(`/api/v1/venues/${venueBId}/tabs`)
.set('Authorization', `Bearer ${token}`)
.expect(403)
.expect((res) => {
expect(res.body.error.code).toBe('venue_forbidden');
});
});
});
});