f6c67bd3ff
Presentational ServiceTestPanel (props-driven, no internal hooks) wired into both CreateServiceDialog (ServicesPage.tsx) and ServiceConfigEditor (Settings.tsx). Parent owns testResult + saveAnyway state; store-previous pattern resets on input change (avoids setState-in-effect). Create/Save button gated on testPassed || saveAnyway. 7 panel tests (button states, success/failure pills, checkbox toggle). All gates: 158 vitest, build exit 0, lint 0 errors, 362 backend pytest (regression).
116 lines
2.7 KiB
TypeScript
116 lines
2.7 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import { ServiceTestPanel } from "../ServiceTestPanel";
|
|
import type { ServiceTestResult } from "../../types";
|
|
|
|
function noop() {}
|
|
|
|
describe("ServiceTestPanel", () => {
|
|
it("renders the Test credentials button", () => {
|
|
render(
|
|
<ServiceTestPanel
|
|
result={null}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
expect(screen.getByText("Test credentials")).toBeTruthy();
|
|
});
|
|
|
|
it("shows Testing… and disables button while pending", () => {
|
|
render(
|
|
<ServiceTestPanel
|
|
result={null}
|
|
isPending={true}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
expect(screen.getByText("Testing…")).toBeTruthy();
|
|
expect(screen.getByText("Testing…")).toBeDisabled();
|
|
});
|
|
|
|
it("renders green ✓ Connected pill with evidence on success", () => {
|
|
const result: ServiceTestResult = {
|
|
ok: true,
|
|
detail: "ok",
|
|
evidence: "v4.5.0",
|
|
};
|
|
render(
|
|
<ServiceTestPanel
|
|
result={result}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
expect(screen.getByText(/✓ Connected — v4.5.0/)).toBeTruthy();
|
|
});
|
|
|
|
it("renders red ✗ pill with detail on failure", () => {
|
|
const result: ServiceTestResult = {
|
|
ok: false,
|
|
detail: "Authentication failed",
|
|
evidence: null,
|
|
};
|
|
render(
|
|
<ServiceTestPanel
|
|
result={result}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
expect(screen.getByText(/✗ Authentication failed/)).toBeTruthy();
|
|
});
|
|
|
|
it("fires onTest when Test credentials is clicked", () => {
|
|
const onTest = vi.fn();
|
|
render(
|
|
<ServiceTestPanel
|
|
result={null}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={onTest}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
fireEvent.click(screen.getByText("Test credentials"));
|
|
expect(onTest).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("fires onSaveAnywayChange when checkbox is toggled", () => {
|
|
const onSaveAnywayChange = vi.fn();
|
|
render(
|
|
<ServiceTestPanel
|
|
result={null}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={onSaveAnywayChange}
|
|
/>,
|
|
);
|
|
const checkbox = screen.getByRole("checkbox");
|
|
fireEvent.click(checkbox);
|
|
expect(onSaveAnywayChange).toHaveBeenCalledWith(true);
|
|
});
|
|
|
|
it("renders the Save anyway checkbox", () => {
|
|
render(
|
|
<ServiceTestPanel
|
|
result={null}
|
|
isPending={false}
|
|
saveAnyway={false}
|
|
onTest={noop}
|
|
onSaveAnywayChange={noop}
|
|
/>,
|
|
);
|
|
expect(screen.getByRole("checkbox")).toBeTruthy();
|
|
});
|
|
});
|