feat(frontend): client web read-only pairing + snapshot état (#13)
Lot F2 du chantier server/client mode : client web read-only complétant le premier incrément livrable — pairing, liste des projets, ouverture et snapshot de l'état, sans PTY. - frontend/src/adapters/http/webSession.ts : session web (pairing/cookie). - frontend/src/features/web : PairingScreen, WebWorkspace, WebApp, index. - Câblage main.tsx et adaptations httpInvoker.ts / index.ts (cas 401). - Tests : webSession.test.ts, WebApp.test.tsx, cas 401 dans httpInvoker.test.ts. Validé : frontend 736 tests verts, build vert, garde no-direct-invoke verte, contrat B4↔F2 aligné, desktop non régressé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -77,6 +77,29 @@ describe("HttpInvoker", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("fires onUnauthorized on a 401 (and still throws)", async () => {
|
||||
const { fetchImpl } = fakeFetch(
|
||||
{ code: "UNAUTHENTICATED", message: "no session" },
|
||||
{ ok: false, status: 401 },
|
||||
);
|
||||
const onUnauthorized = vi.fn();
|
||||
const http = new HttpInvoker({ baseUrl: "https://host", fetchImpl, onUnauthorized });
|
||||
|
||||
await expect(http.invoke("list_projects")).rejects.toMatchObject({
|
||||
code: "UNAUTHENTICATED",
|
||||
});
|
||||
expect(onUnauthorized).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("does not fire onUnauthorized on a non-401 error", async () => {
|
||||
const { fetchImpl } = fakeFetch({ code: "NOT_FOUND", message: "x" }, { ok: false, status: 404 });
|
||||
const onUnauthorized = vi.fn();
|
||||
const http = new HttpInvoker({ baseUrl: "https://host", fetchImpl, onUnauthorized });
|
||||
|
||||
await expect(http.invoke("open_project", { projectId: "x" })).rejects.toBeTruthy();
|
||||
expect(onUnauthorized).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("wraps a network failure in a TRANSPORT_ERROR GatewayError", async () => {
|
||||
const fetchImpl: FetchLike = async () => {
|
||||
throw new Error("boom");
|
||||
|
||||
Reference in New Issue
Block a user