import { INestApplication } from '@nestjs/common'; import request from 'supertest'; import { buildTestApp } from './app.harness'; describe('EnvironmentController', () => { let app: INestApplication; beforeAll(async () => { app = await buildTestApp(); }); afterAll(async () => { await app.close(); }); // ── POST /environments ───────────────────────────────────────────────────── describe('POST /environments', () => { it('creates an environment and returns 201', async () => { const res = await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-a', urls: { id_url: 'https://id.example.com' } }) .expect(201); expect(res.body.id).toBeDefined(); expect(res.body.name).toBe('env-a'); expect(res.body.urls.id_url).toBe('https://id.example.com'); }); it('returns 400 when name is missing', async () => { await request(app.getHttpServer()) .post('/environments') .send({ urls: { id_url: 'https://id.example.com' } }) .expect(400); }); it('returns 400 when urls is missing', async () => { await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-no-urls' }) .expect(400); }); it('returns 400 when urls is not an object', async () => { await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-bad-urls', urls: 'not-an-object' }) .expect(400); }); it('returns 409 when name already exists', async () => { await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-duplicate', urls: {} }) .expect(201); await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-duplicate', urls: {} }) .expect(409); }); }); // ── GET /environments ────────────────────────────────────────────────────── describe('GET /environments', () => { it('returns 200 with a paginated result', async () => { const res = await request(app.getHttpServer()).get('/environments').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('respects page and limit params', async () => { // seed two extra environments await request(app.getHttpServer()).post('/environments').send({ name: 'env-page-1', urls: {} }).expect(201); await request(app.getHttpServer()).post('/environments').send({ name: 'env-page-2', urls: {} }).expect(201); const res = await request(app.getHttpServer()).get('/environments?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('/environments?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('/environments?page=0').expect(400); }); it('orders by name ASC', async () => { await request(app.getHttpServer()).post('/environments').send({ name: 'zzz-env', urls: {} }); await request(app.getHttpServer()).post('/environments').send({ name: 'aaa-env', urls: {} }); const res = await request(app.getHttpServer()).get('/environments?orderBy=name&orderDir=ASC').expect(200); const names: string[] = res.body.data.map((e: any) => e.name); expect(names).toEqual([...names].sort()); }); it('orders by name DESC', async () => { const res = await request(app.getHttpServer()).get('/environments?orderBy=name&orderDir=DESC').expect(200); const names: string[] = res.body.data.map((e: any) => e.name); expect(names).toEqual([...names].sort().reverse()); }); it('returns 400 for invalid orderDir', async () => { await request(app.getHttpServer()).get('/environments?orderDir=SIDEWAYS').expect(400); }); }); // ── GET /environments/:id ────────────────────────────────────────────────── describe('GET /environments/:id', () => { it('returns the created environment', async () => { const created = await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-get-one', urls: { cabinet_url: 'https://cabinet.example.com' } }) .expect(201); const res = await request(app.getHttpServer()) .get(`/environments/${created.body.id}`) .expect(200); expect(res.body.name).toBe('env-get-one'); }); it('returns 404 for unknown id', async () => { await request(app.getHttpServer()).get('/environments/99999').expect(404); }); it('returns 400 for non-numeric id', async () => { await request(app.getHttpServer()).get('/environments/abc').expect(400); }); }); // ── PATCH /environments/:id ──────────────────────────────────────────────── describe('PATCH /environments/:id', () => { it('updates name and returns 200', async () => { const created = await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-patch-me', urls: {} }) .expect(201); const res = await request(app.getHttpServer()) .patch(`/environments/${created.body.id}`) .send({ name: 'env-patched' }) .expect(200); expect(res.body.name).toBe('env-patched'); }); it('returns 404 for unknown id', async () => { await request(app.getHttpServer()) .patch('/environments/99999') .send({ name: 'x' }) .expect(404); }); }); // ── DELETE /environments/:id ─────────────────────────────────────────────── describe('DELETE /environments/:id', () => { it('deletes and returns 204', async () => { const created = await request(app.getHttpServer()) .post('/environments') .send({ name: 'env-delete-me', urls: {} }) .expect(201); await request(app.getHttpServer()) .delete(`/environments/${created.body.id}`) .expect(204); await request(app.getHttpServer()) .get(`/environments/${created.body.id}`) .expect(404); }); it('returns 404 for unknown id', async () => { await request(app.getHttpServer()).delete('/environments/99999').expect(404); }); }); });