041a19f060
* feat: add service-managed self-update * chore: add temporary self-update test scripts * chore: simplify temporary script markdown fences * chore: run frontend in temporary self-update scripts * fix: show self-update job progress after apply * chore: add real npm self-update test script * fix: isolate npm self-update prefix * fix: detect npm service installs from bin shim * chore: reset service before real npm update test * chore: expand real npm status diagnostics * fix: preserve service home during self-update * fix(cli): tee self-update helper output to a log file * fix(cli): avoid launchd bootstrap race when reloading the macOS service * fix(backend): run macOS self-update helper once via transient launchd plist * fix(web): show self-update progress and lock the apply button until the update lands * fix(cli): reinstall via the kandev wrapper on Homebrew self-update * chore: remove temp self-update test scripts * fix(web): drop unused apply path from useUpdates hook * fix(backend): snapshot install state once in apply preflight * docs: align self-update docs with transient LaunchAgent flow * chore(release): run cli bundle from apps workspace root * fix(backend): guard against concurrent self-update applies * fix(backend): check scheme and helper paths in self-update apply * fix(backend): drop duplicate binary name from npx manual command * fix(cli): allow --help for service self-update without --intent * fix(cli): harden self-update dir perms and darwin uid resolution * fix(web): set required POST fields last in applyUpdate * docs: use JSON body notation for the apply endpoint * fix(backend): expire self-update guard so a stuck helper cannot wedge apply * refactor(cli): collapse redundant writeSync branch in self-update log
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
import { cleanup, render, screen } from "@testing-library/react";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { SystemJob } from "@/lib/types/system";
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
useSystemJob: vi.fn(),
|
|
useSystemJobs: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@/hooks/domains/system/use-system-jobs", () => ({
|
|
useSystemJob: mocks.useSystemJob,
|
|
useSystemJobs: mocks.useSystemJobs,
|
|
}));
|
|
|
|
import { JobProgressIndicator } from "./job-progress-indicator";
|
|
|
|
function job(overrides: Partial<SystemJob> = {}): SystemJob {
|
|
return {
|
|
id: "job-1",
|
|
kind: "self-update",
|
|
state: "succeeded",
|
|
started_at: "2026-05-30T00:00:00.000Z",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe("JobProgressIndicator", () => {
|
|
beforeEach(() => {
|
|
mocks.useSystemJob.mockReset();
|
|
mocks.useSystemJobs.mockReset();
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
});
|
|
|
|
it("renders a pinned job fetched by id when the websocket list missed it", () => {
|
|
mocks.useSystemJob.mockReturnValue(job({ id: "job-42" }));
|
|
mocks.useSystemJobs.mockReturnValue([]);
|
|
|
|
render(<JobProgressIndicator kind="self-update" jobId="job-42" />);
|
|
|
|
const indicator = screen.getByTestId("system-job-self-update");
|
|
expect(indicator.getAttribute("data-state")).toBe("succeeded");
|
|
expect(indicator.textContent).toContain("Done");
|
|
});
|
|
|
|
it("falls back to the latest kind-matched job when no id is pinned", () => {
|
|
mocks.useSystemJob.mockReturnValue(undefined);
|
|
mocks.useSystemJobs.mockReturnValue([job({ id: "job-2", state: "failed" })]);
|
|
|
|
render(<JobProgressIndicator kind="self-update" />);
|
|
|
|
expect(screen.getByTestId("system-job-self-update").getAttribute("data-state")).toBe("failed");
|
|
});
|
|
|
|
it("allows a flow-specific success label", () => {
|
|
mocks.useSystemJob.mockReturnValue(job({ id: "job-42", state: "succeeded" }));
|
|
mocks.useSystemJobs.mockReturnValue([]);
|
|
|
|
render(
|
|
<JobProgressIndicator kind="self-update" jobId="job-42" successLabel="Restarting service" />,
|
|
);
|
|
|
|
expect(screen.getByText("Restarting service")).not.toBeNull();
|
|
expect(screen.queryByText("Done")).toBeNull();
|
|
});
|
|
});
|