fabro/apps/fabro-web/app/install-api.test.ts
Bryan Helmkamp 20e4ef32ae
refactor(install): collapse overlapping React state into discriminated unions
Two wins here. First, the `session`/`loadingSession`/`sessionError`
triple is replaced with a single `SessionState` discriminated union, so
the component can switch on `.status` instead of juggling three
correlated flags. Second, the seven flat `useState` calls for the
GitHub step are grouped into `githubStrategy` + `tokenForm` + `appForm`,
with `appForm.owner` typed as the generated `InstallGithubAppOwner`
tagged object. Invalid states like "token flow but org slug set" simply
stop existing.

\`buildInstallGithubAppOwner\` is deleted (unused) — form handlers build
the tagged object in place, which is small enough to stay readable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 13:59:09 -04:00

33 lines
955 B
TypeScript

import { describe, expect, test } from "bun:test";
import { readInstallError } from "./install-api";
describe("readInstallError", () => {
test("prefers the structured install error payload", async () => {
const response = new Response(
JSON.stringify({
errors: [{ status: "422", title: "Unprocessable Entity", detail: "invalid token" }],
}),
{
status: 422,
headers: { "Content-Type": "application/json" },
},
);
await expect(
readInstallError(response, "install request failed"),
).resolves.toBe("invalid token");
});
test("falls back to the provided message when the body is not structured JSON", async () => {
const response = new Response("boom", {
status: 500,
headers: { "Content-Type": "text/plain" },
});
await expect(
readInstallError(response, "install request failed"),
).resolves.toBe("install request failed (500)");
});
});