Files
kandev/apps/web/components/session/prepare-progress.test.tsx
T
José Almeida 6609fe99d4 feat(web): friendlier header for sandbox-recovered prepare runs
When the only warning on a completed prepare is the missing-sandbox
fallback notice, render "Environment prepared on a fresh sandbox" in
the header instead of the generic "Environment prepared with warnings".
The fallback row still carries its own amber warning callout so the
user understands why a fresh sandbox was provisioned.
2026-05-05 21:19:47 +01:00

121 lines
3.7 KiB
TypeScript

import { cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { PrepareStepInfo } from "@/lib/state/slices/session-runtime/types";
let mockSteps: PrepareStepInfo[] = [];
let mockPrepareStatus: "preparing" | "completed" | "failed" = "preparing";
let mockSessionState: string = "STARTING";
vi.mock("@/components/state-provider", () => ({
useAppStore: (selector: (state: Record<string, unknown>) => unknown) =>
selector({
prepareProgress: {
bySessionId: {
"session-1": {
sessionId: "session-1",
status: mockPrepareStatus,
steps: mockSteps,
},
},
},
taskSessions: {
items: {
"session-1": {
id: "session-1",
state: mockSessionState,
},
},
},
sessionAgentctl: {
itemsBySessionId: {},
},
}),
}));
import { PrepareProgress } from "./prepare-progress";
describe("PrepareProgress", () => {
afterEach(() => cleanup());
it("hides skipped steps that have no useful details", () => {
mockPrepareStatus = "preparing";
mockSessionState = "STARTING";
mockSteps = [
{
name: "Uploading credentials",
status: "skipped",
},
{
name: "Waiting for agent controller",
status: "completed",
},
];
render(<PrepareProgress sessionId="session-1" />);
expect(screen.queryByText("Uploading credentials")).toBeNull();
expect(screen.getByText("Waiting for agent controller")).toBeTruthy();
});
it("keeps the fallback notice row visible because it carries a warning", () => {
mockPrepareStatus = "preparing";
mockSessionState = "STARTING";
mockSteps = [
{
name: "Reconnecting cloud sandbox",
status: "skipped",
warning:
"Previous sandbox is no longer available — provisioning a fresh one for this branch.",
warningDetail: "Old sandbox could not be reached.",
output: "Old sandbox: kandev-old\nNew sandbox: kandev-new\nBranch: feature/foo",
},
];
render(<PrepareProgress sessionId="session-1" />);
expect(screen.getByText("Reconnecting cloud sandbox")).toBeTruthy();
expect(
screen.getByText(
"Previous sandbox is no longer available — provisioning a fresh one for this branch.",
),
).toBeTruthy();
});
it("relabels the header when the only warning is the fallback notice", () => {
mockPrepareStatus = "completed";
mockSessionState = "RUNNING";
mockSteps = [
{
name: "Reconnecting cloud sandbox",
status: "skipped",
warning:
"Previous sandbox is no longer available — provisioning a fresh one for this branch.",
},
{ name: "Creating cloud sandbox", status: "completed" },
{ name: "Waiting for agent controller", status: "completed" },
];
render(<PrepareProgress sessionId="session-1" />);
expect(screen.getByText("Environment prepared on a fresh sandbox")).toBeTruthy();
expect(screen.queryByText("Environment prepared with warnings")).toBeNull();
});
it("uses the generic warnings header when warnings are unrelated to fallback", () => {
mockPrepareStatus = "completed";
mockSessionState = "RUNNING";
mockSteps = [
{
name: "Uploading credentials",
status: "completed",
warning: "Some credentials skipped",
},
];
render(<PrepareProgress sessionId="session-1" />);
expect(screen.getByText("Environment prepared with warnings")).toBeTruthy();
expect(screen.queryByText("Environment prepared on a fresh sandbox")).toBeNull();
});
});