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; beforeAll(async () => { app = await buildTestApp(); repo = app.get>(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); }); }); });