From ec975fc7483b45f589375aa367e5af99e20337bb Mon Sep 17 00:00:00 2001 From: Djalim Simaila Date: Sun, 26 Apr 2026 00:02:16 +0200 Subject: [PATCH] test(users): add unit tests for users API --- tests/unit/users_test.ts | 208 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 tests/unit/users_test.ts diff --git a/tests/unit/users_test.ts b/tests/unit/users_test.ts new file mode 100644 index 0000000..c305dc5 --- /dev/null +++ b/tests/unit/users_test.ts @@ -0,0 +1,208 @@ +import { assertEquals } from "@std/assert"; +import { getFetchCalls, mockFetch, restoreFetch } from "../helpers/api_mock.ts"; + +const BASE = "http://localhost/apps/admin/api/users"; + +const users = [ + { id: "dupont.jean", nom: "Dupont", prenom: "Jean", idRole: 1 }, + { id: "martin.alice", nom: "Martin", prenom: "Alice", idRole: 2 }, +]; + +// --- GET /users --- + +Deno.test("GET /users - returns all users", async () => { + mockFetch({ [BASE]: users }); + try { + const res = await fetch(BASE); + assertEquals(res.status, 200); + const data = await res.json(); + assertEquals(data.length, 2); + assertEquals(data[0].id, "dupont.jean"); + } finally { + restoreFetch(); + } +}); + +Deno.test("GET /users - filters by idRole", async () => { + const filtered = users.filter((u) => u.idRole === 1); + mockFetch({ [`${BASE}?idRole=1`]: filtered }); + try { + const res = await fetch(`${BASE}?idRole=1`); + assertEquals(res.status, 200); + const data = await res.json(); + assertEquals(data.length, 1); + assertEquals(data[0].idRole, 1); + } finally { + restoreFetch(); + } +}); + +// --- POST /users --- + +Deno.test("POST /users - creates a user and returns 201", async () => { + const newUser = { id: "durand.claire", nom: "Durand", prenom: "Claire", idRole: 1 }; + mockFetch({ [BASE]: { method: "POST", status: 201, body: newUser } }); + try { + const res = await fetch(BASE, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify(newUser), + }); + assertEquals(res.status, 201); + const data = await res.json(); + assertEquals(data.id, "durand.claire"); + assertEquals(data.nom, "Durand"); + } finally { + restoreFetch(); + } +}); + +Deno.test("POST /users - returns 409 on duplicate id", async () => { + mockFetch({ + [BASE]: { + method: "POST", + status: 409, + body: { error: "Un utilisateur avec cet identifiant existe déjà" }, + }, + }); + try { + const res = await fetch(BASE, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify(users[0]), + }); + assertEquals(res.status, 409); + const data = await res.json(); + assertEquals(typeof data.error, "string"); + } finally { + restoreFetch(); + } +}); + +Deno.test("POST /users - returns 400 on missing fields", async () => { + mockFetch({ [BASE]: { method: "POST", status: 400 } }); + try { + const res = await fetch(BASE, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ id: "x" }), + }); + assertEquals(res.status, 400); + } finally { + restoreFetch(); + } +}); + +// --- GET /users/{id} --- + +Deno.test("GET /users/{id} - returns a user by id", async () => { + mockFetch({ [`${BASE}/dupont.jean`]: users[0] }); + try { + const res = await fetch(`${BASE}/dupont.jean`); + assertEquals(res.status, 200); + const data = await res.json(); + assertEquals(data.id, "dupont.jean"); + assertEquals(data.prenom, "Jean"); + } finally { + restoreFetch(); + } +}); + +Deno.test("GET /users/{id} - returns 404 for unknown id", async () => { + mockFetch({ + [`${BASE}/inconnu`]: { status: 404, body: { error: "Ressource introuvable" } }, + }); + try { + const res = await fetch(`${BASE}/inconnu`); + assertEquals(res.status, 404); + const data = await res.json(); + assertEquals(typeof data.error, "string"); + } finally { + restoreFetch(); + } +}); + +// --- PUT /users/{id} --- + +Deno.test("PUT /users/{id} - updates a user", async () => { + const updated = { ...users[0], prenom: "Jean-Pierre" }; + mockFetch({ + [`${BASE}/dupont.jean`]: { method: "PUT", status: 200, body: updated }, + }); + try { + const res = await fetch(`${BASE}/dupont.jean`, { + method: "PUT", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ nom: "Dupont", prenom: "Jean-Pierre", idRole: 1 }), + }); + assertEquals(res.status, 200); + const data = await res.json(); + assertEquals(data.prenom, "Jean-Pierre"); + } finally { + restoreFetch(); + } +}); + +Deno.test("PUT /users/{id} - returns 404 for unknown id", async () => { + mockFetch({ + [`${BASE}/inconnu`]: { + method: "PUT", + status: 404, + body: { error: "Ressource introuvable" }, + }, + }); + try { + const res = await fetch(`${BASE}/inconnu`, { + method: "PUT", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ nom: "X", prenom: "Y", idRole: 1 }), + }); + assertEquals(res.status, 404); + } finally { + restoreFetch(); + } +}); + +// --- DELETE /users/{id} --- + +Deno.test("DELETE /users/{id} - deletes a user and returns 204", async () => { + mockFetch({ + [`${BASE}/dupont.jean`]: { method: "DELETE", status: 204 }, + }); + try { + const res = await fetch(`${BASE}/dupont.jean`, { method: "DELETE" }); + assertEquals(res.status, 204); + } finally { + restoreFetch(); + } +}); + +Deno.test("DELETE /users/{id} - returns 404 for unknown id", async () => { + mockFetch({ + [`${BASE}/inconnu`]: { + method: "DELETE", + status: 404, + body: { error: "Ressource introuvable" }, + }, + }); + try { + const res = await fetch(`${BASE}/inconnu`, { method: "DELETE" }); + assertEquals(res.status, 404); + } finally { + restoreFetch(); + } +}); + +// --- getFetchCalls --- + +Deno.test("GET /users - call is tracked", async () => { + mockFetch({ [BASE]: users }); + try { + await fetch(BASE); + const calls = getFetchCalls(); + assertEquals(calls.length, 1); + assertEquals(calls[0].method, "GET"); + } finally { + restoreFetch(); + } +});