fix: carry the value convention to the badges, and pin the layout it claims

Copilot review round 1 on #2329. Four findings, all correct.

The whole-modal claim was false for the three rows whose value is a Badge:
`ThemeBadge` defaults to `fw: 600`, so Transport, Era and Status still rendered
bold-label/bold-value. A `ValueBadge` constant carries the normal weight for
Transport and Status, and `EraBadge` takes an optional `fw` so Connection Info
can ask for it without changing the standalone chip in ProtocolListPanel. The
chip still reads as a chip — its emphasis is the outline and colour, not the
font weight.

Three test weaknesses, each of which let a regression through:

- The weight assertion used `queryByText(...)?.style.fontWeight ?? ""`, which
  passes vacuously when the row is absent entirely. Now `getByText`, and
  deleting a value row fails three tests instead of none.
- The full-width test asserted only the transparent background, so swapping
  `FullWidthField` back for the two-column `SimpleGrid` would still have passed.
  It now asserts the structure: label and value are siblings, and the value is
  in no SimpleGrid.
- `OAuthTokenField`'s bold caption was asserted nowhere — the weight test
  renders no token. A case now covers Access Token and ID Token through it.

Note for anyone asserting a Badge's weight later: `getByText` lands on the
inner label span and `fw` is applied to the root, so the assertion has to walk
up or it reads an empty string and passes against anything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GfHQ8vMm5NBgzbUJ6UwxmB
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-11 10:07:22 -04:00
commit c3d9c665a6

View file

@ -590,8 +590,22 @@ describe("ConnectionInfoContent", () => {
for (const label of ["Name", "Protocol", "Client ID", "Scopes"]) {
expect(screen.getAllByText(label)[0]).toHaveStyle({ fontWeight: "600" });
}
// `getByText`, not `queryByText` + `?? ""`: an absent value would make the
// optional form pass vacuously (undefined → "" → not "600"), so the test
// would go green on a row that had stopped rendering at all.
for (const value of ["Everything Server", "read"]) {
expect(screen.queryByText(value)?.style.fontWeight ?? "").not.toBe("600");
expect(screen.getByText(value).style.fontWeight).not.toBe("600");
}
// Badge values count too. `ThemeBadge` defaults to `fw: 600`, so Status,
// Transport and Era read bold-label/bold-value unless overridden — the
// whole-modal claim is false without this.
for (const badge of ["streamable-http", "Legacy", "Authorized"]) {
// `getByText` lands on the Badge's inner label span; `fw` is applied to
// the root, so walk up to it or the assertion reads an empty string and
// passes against anything.
const root = screen.getByText(badge).closest('[class*="Badge-root"]');
expect((root as HTMLElement | null)?.style.fontWeight).toBe("400");
}
});
@ -623,6 +637,45 @@ describe("ConnectionInfoContent", () => {
backgroundColor: "transparent",
});
}
// The background alone does not pin the *layout*: swapping FullWidthField
// back for the two-column SimpleGrid would keep it transparent and still
// pass. Assert the structure that makes the value full width — label and
// value are siblings in a column, and neither sits in a SimpleGrid.
for (const [label, value] of [
[
"Client ID",
"http://127.0.0.1:8093/client-metadata.json?profile=long-enough-to-wrap",
],
["Auth URL", "https://auth.example.com/authorize"],
]) {
const labelNode = screen.getByText(label);
const valueNode = screen.getByText(value);
expect(valueNode.parentElement).toBe(labelNode.parentElement);
expect(valueNode.closest('[class*="SimpleGrid"]')).toBeNull();
}
});
it("bolds the token captions, which are field labels in the same list", () => {
renderWithMantine(
<ConnectionInfoContent
initializeResult={fullResult}
clientCapabilities={fullClientCaps}
transport="streamable-http"
oauth={{
protocol: "standard",
authorized: true,
accessToken: "token-123",
idToken: "id-token-456",
}}
/>,
);
// OAuthTokenField renders its own caption, so the weight convention has to
// be asserted through it — the other weight test renders no token at all.
for (const caption of ["Access Token", "ID Token"]) {
expect(screen.getByText(caption).style.fontWeight).toBe("600");
}
});
it("groups the full-width fields at the end, Client ID directly above Access Token", () => {