mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-05 08:10:39 +00:00
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>
33 lines
955 B
TypeScript
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)");
|
|
});
|
|
});
|
|
|