fix(web): admin bibliothèques — correctifs complémentaires client et AdminPage

- web: AdminPage, client API (+ tests), styles

Refs: #15
This commit is contained in:
Git Agent
2026-08-23 11:36:17 +02:00
parent 39dd130c47
commit a30971f1e9
4 changed files with 53 additions and 7 deletions

View File

@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { ApiFallbackError, getApiFallback } from "./client";
import { afterEach, describe, expect, it, vi } from "vitest";
import { api, ApiFallbackError, getApiFallback } from "./client";
afterEach(() => {
vi.unstubAllGlobals();
});
describe("api fallback helpers", () => {
it("extracts typed fallback payloads", () => {
@ -9,4 +13,21 @@ describe("api fallback helpers", () => {
it("ignores non fallback errors", () => {
expect(getApiFallback<string[]>(new Error("boom"))).toBeUndefined();
});
it("does not send JSON content-type for bodyless delete requests", async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({ ok: true }), {
status: 200,
headers: { "Content-Type": "application/json" }
})
);
vi.stubGlobal("fetch", fetchMock);
await api.deleteLibrary(42);
const init = fetchMock.mock.calls[0][1] as RequestInit;
const headers = new Headers(init.headers);
expect(init.method).toBe("DELETE");
expect(headers.has("Content-Type")).toBe(false);
});
});

View File

@ -56,15 +56,20 @@ function apiErrorMessage(detail: string, fallback: string): string {
return fallback;
}
function requestHeaders(options: RequestOptions): Headers {
const headers = new Headers(options.headers);
if (options.body !== undefined && !headers.has("Content-Type")) {
headers.set("Content-Type", "application/json");
}
return headers;
}
async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
try {
const response = await fetch(`${API_BASE}${path}`, {
...options,
credentials: "include",
headers: {
"Content-Type": "application/json",
...options.headers
}
headers: requestHeaders(options)
});
if (!response.ok) {