test: add jest test suite with controller specs and mocks
- add jest, ts-jest, supertest, and related dev dependencies - add test scripts (test, test:debug, test:watch) to package.json - add jest.config.js with ts-jest transform and module name mappers - add controller specs for auth, browser, environment, mcp, scenario, session - add mocks for jsdom, playwright, and readability - add test/tsconfig.json and exclude test dir from main tsconfig
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import request from 'supertest';
|
||||
import { buildTestApp } from './app.harness';
|
||||
import { SessionEntity } from '../src/session/session.entity';
|
||||
|
||||
describe('SessionController', () => {
|
||||
let app: INestApplication;
|
||||
let repo: Repository<SessionEntity>;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await buildTestApp();
|
||||
repo = app.get<Repository<SessionEntity>>(getRepositoryToken(SessionEntity));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
async function seedSession(name: string) {
|
||||
return repo.save(
|
||||
repo.create({
|
||||
sessionName: name,
|
||||
token: 'tok',
|
||||
cookies: '[]',
|
||||
localStorage: '{}',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// ── GET /sessions ──────────────────────────────────────────────────────────
|
||||
|
||||
describe('GET /sessions', () => {
|
||||
it('returns 200 with an array', async () => {
|
||||
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
|
||||
expect(Array.isArray(res.body)).toBe(true);
|
||||
});
|
||||
|
||||
it('includes seeded sessions', async () => {
|
||||
await seedSession('visible-session');
|
||||
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
|
||||
const names = res.body.map((s: any) => s.sessionName);
|
||||
expect(names).toContain('visible-session');
|
||||
});
|
||||
|
||||
it('does not expose token, cookies or localStorage fields', async () => {
|
||||
await seedSession('private-session');
|
||||
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
|
||||
const item = res.body.find((s: any) => s.sessionName === 'private-session');
|
||||
expect(item).toBeDefined();
|
||||
expect(item.token).toBeUndefined();
|
||||
expect(item.cookies).toBeUndefined();
|
||||
expect(item.localStorage).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ── DELETE /sessions/:id ───────────────────────────────────────────────────
|
||||
|
||||
describe('DELETE /sessions/:id', () => {
|
||||
it('deletes an existing session and returns 200', async () => {
|
||||
const s = await seedSession('delete-me-session');
|
||||
await request(app.getHttpServer()).delete(`/sessions/${s.id}`).expect(200);
|
||||
|
||||
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
|
||||
const names = res.body.map((sess: any) => sess.sessionName);
|
||||
expect(names).not.toContain('delete-me-session');
|
||||
});
|
||||
|
||||
it('returns 404 for unknown id', async () => {
|
||||
await request(app.getHttpServer()).delete('/sessions/99999').expect(404);
|
||||
});
|
||||
|
||||
it('returns 400 for non-numeric id', async () => {
|
||||
await request(app.getHttpServer()).delete('/sessions/abc').expect(400);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user