refactor: dedupe repeated test helpers

This commit is contained in:
Peter Steinberger
2026-04-08 08:43:59 +01:00
parent 7834140bf9
commit 95e397a266
142 changed files with 6125 additions and 10524 deletions

View File

@@ -3,8 +3,7 @@ import type { OpenClawConfig } from "../config/config.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { getChannelSetupWizardAdapter } from "./channel-setup/registry.js";
import type { ChannelSetupWizardAdapter } from "./channel-setup/types.js";
import { patchChannelSetupWizardAdapter } from "./channel-test-helpers.js";
import {
createChannelOnboardingPostWriteHookCollector,
runCollectedChannelOnboardingPostWriteHooks,
@@ -43,73 +42,6 @@ function setMinimalTelegramOnboardingRegistryForTests(): void {
);
}
type ChannelSetupWizardAdapterPatch = Partial<
Pick<
ChannelSetupWizardAdapter,
| "afterConfigWritten"
| "configure"
| "configureInteractive"
| "configureWhenConfigured"
| "getStatus"
>
>;
type PatchedSetupAdapterFields = {
afterConfigWritten?: ChannelSetupWizardAdapter["afterConfigWritten"];
configure?: ChannelSetupWizardAdapter["configure"];
configureInteractive?: ChannelSetupWizardAdapter["configureInteractive"];
configureWhenConfigured?: ChannelSetupWizardAdapter["configureWhenConfigured"];
getStatus?: ChannelSetupWizardAdapter["getStatus"];
};
function patchChannelOnboardingAdapterForTest(patch: ChannelSetupWizardAdapterPatch): () => void {
const adapter = getChannelSetupWizardAdapter("telegram");
if (!adapter) {
throw new Error("missing setup adapter for telegram");
}
const previous: PatchedSetupAdapterFields = {};
if (Object.prototype.hasOwnProperty.call(patch, "getStatus")) {
previous.getStatus = adapter.getStatus;
adapter.getStatus = patch.getStatus ?? adapter.getStatus;
}
if (Object.prototype.hasOwnProperty.call(patch, "afterConfigWritten")) {
previous.afterConfigWritten = adapter.afterConfigWritten;
adapter.afterConfigWritten = patch.afterConfigWritten;
}
if (Object.prototype.hasOwnProperty.call(patch, "configure")) {
previous.configure = adapter.configure;
adapter.configure = patch.configure ?? adapter.configure;
}
if (Object.prototype.hasOwnProperty.call(patch, "configureInteractive")) {
previous.configureInteractive = adapter.configureInteractive;
adapter.configureInteractive = patch.configureInteractive;
}
if (Object.prototype.hasOwnProperty.call(patch, "configureWhenConfigured")) {
previous.configureWhenConfigured = adapter.configureWhenConfigured;
adapter.configureWhenConfigured = patch.configureWhenConfigured;
}
return () => {
if (Object.prototype.hasOwnProperty.call(patch, "getStatus")) {
adapter.getStatus = previous.getStatus!;
}
if (Object.prototype.hasOwnProperty.call(patch, "afterConfigWritten")) {
adapter.afterConfigWritten = previous.afterConfigWritten;
}
if (Object.prototype.hasOwnProperty.call(patch, "configure")) {
adapter.configure = previous.configure!;
}
if (Object.prototype.hasOwnProperty.call(patch, "configureInteractive")) {
adapter.configureInteractive = previous.configureInteractive;
}
if (Object.prototype.hasOwnProperty.call(patch, "configureWhenConfigured")) {
adapter.configureWhenConfigured = previous.configureWhenConfigured;
}
};
}
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
return createWizardPrompter(
{
@@ -159,7 +91,7 @@ describe("setupChannels post-write hooks", () => {
} as OpenClawConfig,
accountId: "acct-1",
}));
const restore = patchChannelOnboardingAdapterForTest({
const restore = patchChannelSetupWizardAdapter("telegram", {
configureInteractive,
afterConfigWritten,
getStatus: vi.fn(async ({ cfg }: { cfg: OpenClawConfig }) => ({

View File

@@ -6,158 +6,85 @@ import {
buildStatusOverviewSurfaceFromScan,
} from "./status-overview-surface.ts";
const baseCfg = { update: { channel: "stable" }, gateway: { bind: "loopback" } } as const;
const baseUpdate = { installKind: "git", git: { branch: "main", tag: "v1.2.3" } } as never;
const baseGatewaySnapshot = {
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
message: "Gateway target: wss://gateway.example.com",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
} as const;
const baseScanFields = {
cfg: baseCfg,
update: baseUpdate,
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
...baseGatewaySnapshot,
};
const baseGatewayService = {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
};
const baseNodeService = {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
};
const baseServices = {
gatewayService: baseGatewayService,
nodeService: baseNodeService,
nodeOnlyGateway: null,
};
const baseOverviewSurface = {
...baseScanFields,
...baseServices,
};
describe("status-overview-surface", () => {
it("builds the shared overview surface from a status scan result", () => {
expect(
buildStatusOverviewSurfaceFromScan({
scan: {
cfg: { update: { channel: "stable" }, gateway: { bind: "loopback" } },
update: { installKind: "git", git: { branch: "main", tag: "v1.2.3" } } as never,
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
message: "Gateway target: wss://gateway.example.com",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
},
gatewayService: {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
},
nodeService: {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
},
nodeOnlyGateway: null,
scan: baseScanFields,
...baseServices,
}),
).toEqual({
cfg: { update: { channel: "stable" }, gateway: { bind: "loopback" } },
update: { installKind: "git", git: { branch: "main", tag: "v1.2.3" } },
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
message: "Gateway target: wss://gateway.example.com",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
gatewayService: {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
},
nodeService: {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
},
nodeOnlyGateway: null,
});
).toEqual(baseOverviewSurface);
});
it("builds the shared overview surface from scan overview data", () => {
expect(
buildStatusOverviewSurfaceFromOverview({
overview: {
cfg: { update: { channel: "stable" }, gateway: { bind: "loopback" } },
update: { installKind: "git", git: { branch: "main", tag: "v1.2.3" } } as never,
cfg: baseCfg,
update: baseUpdate,
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
gatewaySnapshot: {
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
message: "Gateway target: wss://gateway.example.com",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
},
gatewaySnapshot: baseGatewaySnapshot,
} as never,
gatewayService: {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
},
nodeService: {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
},
nodeOnlyGateway: null,
...baseServices,
}),
).toEqual({
cfg: { update: { channel: "stable" }, gateway: { bind: "loopback" } },
update: { installKind: "git", git: { branch: "main", tag: "v1.2.3" } },
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
message: "Gateway target: wss://gateway.example.com",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
gatewayService: {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
},
nodeService: {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
},
nodeOnlyGateway: null,
});
).toEqual(baseOverviewSurface);
});
it("builds overview rows from the shared surface bundle", () => {
expect(
buildStatusOverviewRowsFromSurface({
surface: {
cfg: { update: { channel: "stable" }, gateway: { bind: "loopback" } },
...baseOverviewSurface,
cfg: baseCfg,
update: {
installKind: "git",
git: {
@@ -172,33 +99,11 @@ describe("status-overview-surface", () => {
registry: { latestVersion: "2026.4.9" },
} as never,
tailscaleMode: "off",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: null,
gatewayMode: "remote",
remoteUrlMissing: false,
gatewayConnection: {
url: "wss://gateway.example.com",
urlSource: "config",
},
gatewayReachable: true,
gatewayProbe: { connectLatencyMs: 42, error: null } as never,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn-text",
gatewaySelf: { host: "gateway", version: "1.2.3" },
gatewayService: {
label: "LaunchAgent",
installed: true,
managedByOpenClaw: true,
loadedText: "loaded",
runtimeShort: "running",
},
nodeService: {
label: "node",
installed: true,
loadedText: "loaded",
runtime: { status: "running", pid: 42 },
},
nodeOnlyGateway: null,
},
prefixRows: [{ Item: "OS", Value: "macOS · node 22" }],
suffixRows: [{ Item: "Secrets", Value: "none" }],

View File

@@ -4,111 +4,25 @@ import { buildColdStartStatusSummary } from "./status.scan.bootstrap-shared.ts";
describe("buildStatusScanResult", () => {
it("builds the full shared scan result shape", () => {
expect(
buildStatusScanResult({
cfg: { gateway: {} },
sourceConfig: { gateway: {} },
secretDiagnostics: ["diag"],
osSummary: {
platform: "linux",
arch: "x64",
release: "6.8.0",
label: "linux 6.8.0 (x64)",
},
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
update: {
root: "/tmp/openclaw",
installKind: "package",
packageManager: "npm",
},
gatewaySnapshot: {
gatewayConnection: {
url: "ws://127.0.0.1:18789",
urlSource: "config",
message: "Gateway target: ws://127.0.0.1:18789",
},
remoteUrlMissing: false,
gatewayMode: "local",
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn",
gatewayProbe: {
ok: true,
url: "ws://127.0.0.1:18789",
connectLatencyMs: 42,
error: null,
close: null,
health: null,
status: null,
presence: null,
configSnapshot: null,
},
gatewayReachable: true,
gatewaySelf: { host: "gateway" },
},
channelIssues: [
{
channel: "discord",
accountId: "default",
kind: "runtime",
message: "warn",
},
],
agentStatus: {
defaultId: "main",
totalSessions: 0,
bootstrapPendingCount: 0,
agents: [
{
id: "main",
workspaceDir: null,
bootstrapPending: false,
sessionsPath: "/tmp/main.json",
sessionsCount: 0,
lastUpdatedAt: null,
lastActiveAgeMs: null,
},
],
},
channels: { rows: [], details: [] },
summary: buildColdStartStatusSummary(),
memory: { agentId: "main", backend: "builtin", provider: "sqlite" },
memoryPlugin: { enabled: true, slot: "memory-core" },
pluginCompatibility: [
{
pluginId: "legacy",
code: "legacy-before-agent-start",
severity: "warn",
message: "warn",
},
],
}),
).toEqual({
cfg: { gateway: {} },
sourceConfig: { gateway: {} },
secretDiagnostics: ["diag"],
osSummary: {
platform: "linux",
arch: "x64",
release: "6.8.0",
label: "linux 6.8.0 (x64)",
},
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
update: {
root: "/tmp/openclaw",
installKind: "package",
packageManager: "npm",
},
const osSummary = {
platform: "linux" as const,
arch: "x64",
release: "6.8.0",
label: "linux 6.8.0 (x64)",
};
const update = {
root: "/tmp/openclaw",
installKind: "package" as const,
packageManager: "npm" as const,
};
const gatewaySnapshot = {
gatewayConnection: {
url: "ws://127.0.0.1:18789",
urlSource: "config",
urlSource: "config" as const,
message: "Gateway target: ws://127.0.0.1:18789",
},
remoteUrlMissing: false,
gatewayMode: "local",
gatewayMode: "local" as const,
gatewayProbeAuth: { token: "tok" },
gatewayProbeAuthWarning: "warn",
gatewayProbe: {
@@ -124,42 +38,87 @@ describe("buildStatusScanResult", () => {
},
gatewayReachable: true,
gatewaySelf: { host: "gateway" },
channelIssues: [
{
channel: "discord",
accountId: "default",
kind: "runtime",
message: "warn",
},
],
agentStatus: {
defaultId: "main",
totalSessions: 0,
bootstrapPendingCount: 0,
agents: [
{
id: "main",
workspaceDir: null,
bootstrapPending: false,
sessionsPath: "/tmp/main.json",
sessionsCount: 0,
lastUpdatedAt: null,
lastActiveAgeMs: null,
},
],
};
const channelIssues = [
{
channel: "discord",
accountId: "default",
kind: "runtime" as const,
message: "warn",
},
channels: { rows: [], details: [] },
summary: buildColdStartStatusSummary(),
memory: { agentId: "main", backend: "builtin", provider: "sqlite" },
memoryPlugin: { enabled: true, slot: "memory-core" },
pluginCompatibility: [
];
const agentStatus = {
defaultId: "main",
totalSessions: 0,
bootstrapPendingCount: 0,
agents: [
{
pluginId: "legacy",
code: "legacy-before-agent-start",
severity: "warn",
message: "warn",
id: "main",
workspaceDir: null,
bootstrapPending: false,
sessionsPath: "/tmp/main.json",
sessionsCount: 0,
lastUpdatedAt: null,
lastActiveAgeMs: null,
},
],
};
const channels = { rows: [], details: [] };
const summary = buildColdStartStatusSummary();
const memory = { agentId: "main", backend: "builtin" as const, provider: "sqlite" };
const memoryPlugin = { enabled: true, slot: "memory-core" };
const pluginCompatibility = [
{
pluginId: "legacy",
code: "legacy-before-agent-start" as const,
severity: "warn" as const,
message: "warn",
},
];
expect(
buildStatusScanResult({
cfg: { gateway: {} },
sourceConfig: { gateway: {} },
secretDiagnostics: ["diag"],
osSummary,
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
update,
gatewaySnapshot,
channelIssues,
agentStatus,
channels,
summary,
memory,
memoryPlugin,
pluginCompatibility,
}),
).toEqual({
cfg: { gateway: {} },
sourceConfig: { gateway: {} },
secretDiagnostics: ["diag"],
osSummary,
tailscaleMode: "serve",
tailscaleDns: "box.tail.ts.net",
tailscaleHttpsUrl: "https://box.tail.ts.net",
update,
gatewayConnection: gatewaySnapshot.gatewayConnection,
remoteUrlMissing: gatewaySnapshot.remoteUrlMissing,
gatewayMode: gatewaySnapshot.gatewayMode,
gatewayProbeAuth: gatewaySnapshot.gatewayProbeAuth,
gatewayProbeAuthWarning: gatewaySnapshot.gatewayProbeAuthWarning,
gatewayProbe: gatewaySnapshot.gatewayProbe,
gatewayReachable: gatewaySnapshot.gatewayReachable,
gatewaySelf: gatewaySnapshot.gatewaySelf,
channelIssues,
agentStatus,
channels,
summary,
memory,
memoryPlugin,
pluginCompatibility,
});
});
});