Files
liqa/test/session.controller.spec.ts
T
ars9 36f8b8c0ca feat(pagination): add generic typed pagination with ordering to all list endpoints
- add PaginationQueryDto<TOrderBy> generic with orderBy and orderDir fields
- add SessionOrderBy, EnvironmentOrderBy, ScenarioOrderBy type aliases
- update session, environment, scenario services and controllers to use typed pagination
- update MCP list_sessions, list_environments, list_scenarios tools to expose orderBy/orderDir
- update tests for all list endpoints to cover page, limit, ordering, and invalid param rejection
2026-04-07 17:54:23 +03:00

120 lines
4.6 KiB
TypeScript

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 a paginated result', async () => {
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
expect(Array.isArray(res.body.data)).toBe(true);
expect(typeof res.body.total).toBe('number');
expect(res.body).toHaveProperty('page');
expect(res.body).toHaveProperty('limit');
});
it('includes seeded sessions', async () => {
await seedSession('visible-session');
const res = await request(app.getHttpServer()).get('/sessions').expect(200);
const names = res.body.data.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.data.find((s: any) => s.sessionName === 'private-session');
expect(item).toBeDefined();
expect(item.token).toBeUndefined();
expect(item.cookies).toBeUndefined();
expect(item.localStorage).toBeUndefined();
});
it('respects page and limit params', async () => {
await seedSession('paged-session-a');
await seedSession('paged-session-b');
const res = await request(app.getHttpServer()).get('/sessions?page=1&limit=1').expect(200);
expect(res.body.data).toHaveLength(1);
expect(res.body.page).toBe(1);
expect(res.body.limit).toBe(1);
});
it('returns empty data array for out-of-range page', async () => {
const res = await request(app.getHttpServer()).get('/sessions?page=9999&limit=20').expect(200);
expect(res.body.data).toHaveLength(0);
});
it('returns 400 for invalid page param', async () => {
await request(app.getHttpServer()).get('/sessions?page=0').expect(400);
});
it('orders by sessionName ASC', async () => {
await seedSession('zzz-sort-session');
await seedSession('aaa-sort-session');
const res = await request(app.getHttpServer()).get('/sessions?orderBy=sessionName&orderDir=ASC').expect(200);
const names: string[] = res.body.data.map((s: any) => s.sessionName);
expect(names).toEqual([...names].sort());
});
it('orders by sessionName DESC', async () => {
const res = await request(app.getHttpServer()).get('/sessions?orderBy=sessionName&orderDir=DESC').expect(200);
const names: string[] = res.body.data.map((s: any) => s.sessionName);
expect(names).toEqual([...names].sort().reverse());
});
it('returns 400 for invalid orderDir', async () => {
await request(app.getHttpServer()).get('/sessions?orderDir=SIDEWAYS').expect(400);
});
});
// ── 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.data.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);
});
});
});