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", data: { id: "https://id.example.com" } }) .expect(201); expect(res.body.id).toBeDefined(); expect(res.body.name).toBe("env-a"); expect(res.body.data.id).toBe("https://id.example.com"); }); it("returns 400 when name is missing", async () => { await request(app.getHttpServer()) .post("/environments") .send({ data: { id: "https://id.example.com" } }) .expect(400); }); it("returns 400 when data is missing", async () => { await request(app.getHttpServer()) .post("/environments") .send({ name: "env-no-data" }) .expect(400); }); it("returns 400 when data is not an object", async () => { await request(app.getHttpServer()) .post("/environments") .send({ name: "env-bad-data", data: "not-an-object" }) .expect(400); }); it("returns 409 when name already exists", async () => { await request(app.getHttpServer()) .post("/environments") .send({ name: "env-duplicate", data: {} }) .expect(201); await request(app.getHttpServer()) .post("/environments") .send({ name: "env-duplicate", data: {} }) .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", data: {} }) .expect(201); await request(app.getHttpServer()) .post("/environments") .send({ name: "env-page-2", data: {} }) .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", data: {} }); await request(app.getHttpServer()) .post("/environments") .send({ name: "aaa-env", data: {} }); const res = await request(app.getHttpServer()) .get("/environments?orderBy=name&orderDir=ASC") .expect(200); const names: string[] = res.body.data.map( (e: { name: string }) => 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: { name: string }) => 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", data: { cabinet: "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/00000000-0000-0000-0000-000000000001") .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", data: {} }) .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/00000000-0000-0000-0000-000000000001") .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", data: {} }) .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/00000000-0000-0000-0000-000000000001") .expect(404); }); }); });