714486f43c
Check Deno code / Check Deno code (pull_request) Successful in 5s
Tests / Unit tests (pull_request) Successful in 12s
Tests / Integration tests (pull_request) Successful in 1m9s
Check Deno code / Check Deno code (push) Successful in 6s
Tests / Unit tests (push) Successful in 12s
Tests / Integration tests (push) Successful in 1m13s
225 lines
6.5 KiB
TypeScript
225 lines
6.5 KiB
TypeScript
// Unit tests for /notes endpoints — fixtures, mock API, mock DB
|
|
|
|
import { assertEquals, assertExists } from "@std/assert";
|
|
import { mockFetch, restoreFetch } from "../helpers/api_mock.ts";
|
|
import { createMockDb } from "../helpers/db_mock.ts";
|
|
import { type Note, notes } from "../helpers/fixtures.ts";
|
|
|
|
// --- Fixtures ---
|
|
|
|
Deno.test("notes: fixtures have correct shape", () => {
|
|
assertEquals(notes.length, 4);
|
|
assertEquals(typeof notes[0].note, "number");
|
|
assertEquals(typeof notes[0].numEtud, "number");
|
|
assertEquals(typeof notes[0].idModule, "string");
|
|
});
|
|
|
|
Deno.test("notes: fixtures use decimal values", () => {
|
|
assertEquals(notes[0].note, 15.5);
|
|
});
|
|
|
|
// --- Mock API ---
|
|
|
|
Deno.test("mock API: GET /notes returns list", async () => {
|
|
mockFetch({ "/notes": notes });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes");
|
|
assertEquals(res.status, 200);
|
|
const data: Note[] = await res.json();
|
|
assertEquals(data.length, 4);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: GET /notes?numEtud filters by student", async () => {
|
|
const filtered = notes.filter((n) => n.numEtud === 21212006);
|
|
mockFetch({ "/notes": filtered });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes?numEtud=21212006");
|
|
const data: Note[] = await res.json();
|
|
assertEquals(data.length, 2);
|
|
assertEquals(data.every((n) => n.numEtud === 21212006), true);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: GET /notes?idModule filters by module", async () => {
|
|
const filtered = notes.filter((n) => n.idModule === "JIN702C");
|
|
mockFetch({ "/notes": filtered });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes?idModule=JIN702C");
|
|
const data: Note[] = await res.json();
|
|
assertEquals(data.length, 2);
|
|
assertEquals(data.every((n) => n.idModule === "JIN702C"), true);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: GET /notes?numEtud=NaN returns 400", async () => {
|
|
mockFetch({ "/notes": { status: 400 } });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes?numEtud=abc");
|
|
assertEquals(res.status, 400);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: POST /notes creates note (201)", async () => {
|
|
const newNote: Note = { note: 14.0, numEtud: 21212006, idModule: "JIN704C" };
|
|
mockFetch({ "/notes": { method: "POST", status: 201, body: newNote } });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify(newNote),
|
|
});
|
|
assertEquals(res.status, 201);
|
|
const data: Note = await res.json();
|
|
assertEquals(data.note, 14.0);
|
|
assertEquals(data.numEtud, 21212006);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: POST /notes 400 on missing fields", async () => {
|
|
mockFetch({ "/notes": { method: "POST", status: 400 } });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ numEtud: 21212006 }),
|
|
});
|
|
assertEquals(res.status, 400);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: GET /notes/:numEtud/:idModule returns note", async () => {
|
|
mockFetch({ "/notes/21212006/JIN702C": notes[0] });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes/21212006/JIN702C");
|
|
assertEquals(res.status, 200);
|
|
const data: Note = await res.json();
|
|
assertEquals(data.note, 15.5);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: GET /notes/:numEtud/:idModule 404 when not found", async () => {
|
|
mockFetch({
|
|
"/notes/99999/GHOST": {
|
|
status: 404,
|
|
body: { error: "Ressource introuvable" },
|
|
},
|
|
});
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes/99999/GHOST");
|
|
assertEquals(res.status, 404);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: PUT /notes/:numEtud/:idModule updates note", async () => {
|
|
const updated: Note = { ...notes[0], note: 17.0 };
|
|
mockFetch({
|
|
"/notes/21212006/JIN702C": { method: "PUT", status: 200, body: updated },
|
|
});
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes/21212006/JIN702C", {
|
|
method: "PUT",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ note: 17.0 }),
|
|
});
|
|
assertEquals(res.status, 200);
|
|
const data: Note = await res.json();
|
|
assertEquals(data.note, 17.0);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: DELETE /notes/:numEtud/:idModule returns 204", async () => {
|
|
mockFetch({ "/notes/21212006/JIN702C": { method: "DELETE", status: 204 } });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes/21212006/JIN702C", {
|
|
method: "DELETE",
|
|
});
|
|
assertEquals(res.status, 204);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
Deno.test("mock API: DELETE /notes/:numEtud/:idModule 404 when not found", async () => {
|
|
mockFetch({ "/notes/99999/GHOST": { method: "DELETE", status: 404 } });
|
|
try {
|
|
const res = await fetch("http://localhost/api/notes/99999/GHOST", {
|
|
method: "DELETE",
|
|
});
|
|
assertEquals(res.status, 404);
|
|
} finally {
|
|
restoreFetch();
|
|
}
|
|
});
|
|
|
|
// --- Mock DB ---
|
|
|
|
Deno.test("mock DB: find note by composite key", () => {
|
|
const db = createMockDb({ tables: { notes: [...notes] } });
|
|
const n = db.findOne<Note>(
|
|
"notes",
|
|
(n) => n.numEtud === 21212006 && n.idModule === "JIN702C",
|
|
);
|
|
assertExists(n);
|
|
assertEquals(n.note, 15.5);
|
|
});
|
|
|
|
Deno.test("mock DB: filter notes by numEtud", () => {
|
|
const db = createMockDb({ tables: { notes: [...notes] } });
|
|
const rows = db.findMany<Note>("notes", (n) => n.numEtud === 21212006);
|
|
assertEquals(rows.length, 2);
|
|
});
|
|
|
|
Deno.test("mock DB: insert note", () => {
|
|
const db = createMockDb({ tables: { notes: [...notes] } });
|
|
db.insert<Note>("notes", {
|
|
note: 10.0,
|
|
numEtud: 21212006,
|
|
idModule: "JIN704C",
|
|
});
|
|
assertEquals(db.getTable("notes").length, 5);
|
|
});
|
|
|
|
Deno.test("mock DB: update note value", () => {
|
|
const db = createMockDb({ tables: { notes: [...notes] } });
|
|
db.updateWhere<Note>(
|
|
"notes",
|
|
(n) => n.numEtud === 21212006 && n.idModule === "JIN702C",
|
|
{ note: 20.0 },
|
|
);
|
|
assertEquals(
|
|
db.findOne<Note>(
|
|
"notes",
|
|
(n) => n.numEtud === 21212006 && n.idModule === "JIN702C",
|
|
)?.note,
|
|
20.0,
|
|
);
|
|
});
|
|
|
|
Deno.test("mock DB: delete note", () => {
|
|
const db = createMockDb({ tables: { notes: [...notes] } });
|
|
db.deleteWhere<Note>(
|
|
"notes",
|
|
(n) => n.numEtud === 21212006 && n.idModule === "JIN702C",
|
|
);
|
|
assertEquals(db.getTable("notes").length, 3);
|
|
});
|