Files
ps5upload/client/src/lib/consoleSession.test.ts
T
phantomptrandClaude Opus 5.5 7a5608c6a9 Remove dead engine/payload code and the FTX2 migration shims
Engine: drop the unused /api/fakelibs/manifest, /api/collection/summary and
/api/ps5/content-db/backup routes, the payload FTP client (core ftp.rs, FTP_START/STATUS)
and NOTIF_SEND, and pub items only their own tests called. The DPI reason strings now come
from the payload_lifecycle constants everywhere.

Shims: the legacy helper replace flow (engine legacy_helper/legacy_guard, the helper/state
and helper/replace routes, the status-error fold), the client's helper_old banner/state and
the payload's legacy takeover and retired-folder removal are gone. An old helper that does
not speak AVA1 now reads as no helper, and the normal send-the-helper flow replaces it. The
6.0 console folder cleanup now starts from a successful status probe.

Payload: remove the FTP server and its self-tests, notif.send, ftp.start/ftp.status
(ids 119, 120, 123 retired in the schema), the unused ShellUI sensor/install RPCs,
runtime_reconcile_mounts, register_services_init, hw_temps_get_text and
mgmt_call_fs_mkdir. MGMT_METHODS.md describes the current method table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
2026-10-10 06:24:09 -07:00

91 lines
3.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
classifySession,
hostFromArgs,
isNotPairedError,
sessionNeedsAttention,
} from "./consoleSession";
describe("the one console status probe", () => {
it("reads a good STATUS reply as connected", () => {
expect(classifySession({ reachable: true, error: null })).toBe("connected");
});
it("maps the engine's tokens to the pairing state", () => {
expect(
classifySession({ reachable: false, error: "ava1_not_paired" }),
).toBe("needs_pairing");
expect(
classifySession({
reachable: false,
error: "payload rejected NOT_PAIRED: not_paired",
}),
).toBe("needs_pairing");
// No AVA1 listener at all (an older helper that does not speak AVA1 included): nothing to
// pair with, so the send-the-helper flow (down) is the right one.
expect(
classifySession({ reachable: false, error: "helper_not_ava1" }),
).toBe("down");
});
it("is down for anything else, including no error text", () => {
expect(classifySession({ reachable: false, error: "connect refused" })).toBe(
"down",
);
expect(classifySession({ reachable: false, error: null })).toBe("down");
});
it("flags the states a person has to act on", () => {
expect(sessionNeedsAttention("needs_pairing")).toBe(true);
expect(sessionNeedsAttention("connected")).toBe(false);
expect(sessionNeedsAttention("down")).toBe(false);
expect(sessionNeedsAttention(null)).toBe(false);
});
it("recognises a not-paired failure wherever its token appears", () => {
expect(isNotPairedError("ava1_not_paired")).toBe(true);
expect(isNotPairedError(new Error("engine HTTP 502: not_paired"))).toBe(true);
expect(isNotPairedError("the devices are not paired yet")).toBe(true);
expect(isNotPairedError("connect refused")).toBe(false);
expect(isNotPairedError(undefined)).toBe(false);
});
});
// Read as raw text at transform time (the client has no @types/node).
const SOURCES = import.meta.glob(["../state/connection.ts", "../layout/AppShell.tsx"], {
query: "?raw",
import: "default",
eager: true,
}) as Record<string, string>;
describe("status_pill_has_one_probe", () => {
const raw = (rel: string): string => SOURCES[rel] ?? "";
const src = raw("../state/connection.ts");
it("the per-console runtime carries one session state and no second liveness flag", () => {
expect(src.length).toBeGreaterThan(0);
expect(src).toContain("session: SessionState | null");
expect(src).not.toContain("transferAlive");
expect(src).not.toContain("PS5_PAYLOAD_PORT");
});
it("the poller no longer opens a second TCP probe against the old transfer port", () => {
const shell = raw("../layout/AppShell.tsx");
expect(shell.length).toBeGreaterThan(0);
expect(shell).not.toContain("transferAliveRef");
expect(shell).not.toContain("PS5_TRANSFER_PORT");
expect(shell).not.toContain("PS5_MGMT_PORT");
});
});
describe("which console a failure names", () => {
it("reads ip, addr and req.addr only, stripping any port; never a from/to path", () => {
expect(hostFromArgs({ ip: "10.0.0.2" })).toBe("10.0.0.2");
expect(hostFromArgs({ addr: "10.0.0.3:9114", path: "/x" })).toBe("10.0.0.3");
expect(hostFromArgs({ req: { addr: "10.0.0.4:9114", from: "/data/a" } })).toBe("10.0.0.4");
expect(hostFromArgs({ req: { from: "/data/a", to: "/data/b" } })).toBeUndefined();
expect(hostFromArgs({ from: "/data/a", to: "/mnt/usb0/b" })).toBeUndefined();
expect(hostFromArgs({ jobId: "j" })).toBeUndefined();
expect(hostFromArgs(undefined)).toBeUndefined();
});
});