





























@@ -54,6 +54,12 @@ function makeGatewayService(
5454} as unknown as GatewayService;
5555}
565657+function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }): T {
58+const call = mock.mock.calls[0];
59+expect(call).toBeDefined();
60+return call?.[0] as T;
61+}
62+5763async function inspectGatewayRestartWithSnapshot(params: {
5864runtime: { status: "running"; pid: number } | { status: "stopped" };
5965portUsage: PortUsage;
@@ -235,9 +241,7 @@ describe("inspectGatewayRestart", () => {
235241});
236242237243expect(snapshot.healthy).toBe(true);
238-expect(probeGateway).toHaveBeenCalledWith(
239-expect.objectContaining({ url: "ws://127.0.0.1:18789" }),
240-);
244+expect(firstCallArg<{ url?: string }>(probeGateway).url).toBe("ws://127.0.0.1:18789");
241245});
242246243247it("treats a busy port as healthy when runtime status lags but the probe succeeds", async () => {
@@ -335,15 +339,11 @@ describe("inspectGatewayRestart", () => {
335339},
336340});
337341338-expect(snapshot).toMatchObject({
339-healthy: false,
340-gatewayVersion: "2026.4.23",
341-expectedVersion: "2026.4.24",
342-versionMismatch: {
343-expected: "2026.4.24",
344-actual: "2026.4.23",
345-},
346-});
342+expect(snapshot.healthy).toBe(false);
343+expect(snapshot.gatewayVersion).toBe("2026.4.23");
344+expect(snapshot.expectedVersion).toBe("2026.4.24");
345+expect(snapshot.versionMismatch?.expected).toBe("2026.4.24");
346+expect(snapshot.versionMismatch?.actual).toBe("2026.4.23");
347347});
348348349349it("accepts the restarted gateway when the expected version matches", async () => {
@@ -364,11 +364,9 @@ describe("inspectGatewayRestart", () => {
364364},
365365});
366366367-expect(snapshot).toMatchObject({
368-healthy: true,
369-gatewayVersion: "2026.4.24",
370-expectedVersion: "2026.4.24",
371-});
367+expect(snapshot.healthy).toBe(true);
368+expect(snapshot.gatewayVersion).toBe("2026.4.24");
369+expect(snapshot.expectedVersion).toBe("2026.4.24");
372370expect(snapshot.versionMismatch).toBeUndefined();
373371});
374372@@ -393,11 +391,9 @@ describe("inspectGatewayRestart", () => {
393391},
394392});
395393396-expect(snapshot).toMatchObject({
397-healthy: true,
398-gatewayVersion: "2026.4.24",
399-expectedVersion: "2026.4.24",
400-});
394+expect(snapshot.healthy).toBe(true);
395+expect(snapshot.gatewayVersion).toBe("2026.4.24");
396+expect(snapshot.expectedVersion).toBe("2026.4.24");
401397expect(snapshot.versionMismatch).toBeUndefined();
402398});
403399@@ -434,23 +430,23 @@ describe("inspectGatewayRestart", () => {
434430env: serviceEnv,
435431});
436432437-expect(snapshot).toMatchObject({
438- healthy: true,
439- gatewayVersion: "2026.4.24",
440- expectedVersion: "2026.4.24",
441-});
442-expect(resolveGatewayProbeAuthSafeWithSecretInputs).toHaveBeenCalledWith(
443- expect.objectContaining({
444- cfg: { gateway: { auth: { mode: "token", token: "probe-token" } } },
445- mode: "local",
446- }),
447-);
448-expect(probeGateway).toHaveBeenCalledWith(
449-expect.objectContaining({
450- auth: { token: "probe-token", password: undefined },
451- env: serviceEnv,
452- }),
453-);
433+expect(snapshot.healthy).toBe(true);
434+expect(snapshot.gatewayVersion).toBe("2026.4.24");
435+expect(snapshot.expectedVersion).toBe("2026.4.24");
436+const authResolveInput = firstCallArg<{
437+ cfg?: { gateway?: { auth?: { mode?: string; token?: string } } };
438+ mode?: string;
439+}>(resolveGatewayProbeAuthSafeWithSecretInputs);
440+expect(authResolveInput.cfg?.gateway?.auth?.mode).toBe("token");
441+expect(authResolveInput.cfg?.gateway?.auth?.token).toBe("probe-token");
442+expect(authResolveInput.mode).toBe("local");
443+const probeInput = firstCallArg<{
444+ auth?: { token?: string; password?: string };
445+env?: NodeJS.ProcessEnv;
446+}>(probeGateway);
447+expect(probeInput.auth?.token).toBe("probe-token");
448+expect(probeInput.auth?.password).toBeUndefined();
449+expect(probeInput.env).toBe(serviceEnv);
454450});
455451456452it("stops waiting once the restarted gateway reports the wrong version", async () => {
@@ -473,15 +469,11 @@ describe("inspectGatewayRestart", () => {
473469expectedVersion: "2026.4.24",
474470});
475471476-expect(snapshot).toMatchObject({
477-healthy: false,
478-waitOutcome: "version-mismatch",
479-elapsedMs: 0,
480-versionMismatch: {
481-expected: "2026.4.24",
482-actual: "2026.4.23",
483-},
484-});
472+expect(snapshot.healthy).toBe(false);
473+expect(snapshot.waitOutcome).toBe("version-mismatch");
474+expect(snapshot.elapsedMs).toBe(0);
475+expect(snapshot.versionMismatch?.expected).toBe("2026.4.24");
476+expect(snapshot.versionMismatch?.actual).toBe("2026.4.23");
485477expect(sleep).not.toHaveBeenCalled();
486478});
487479@@ -522,21 +514,19 @@ describe("inspectGatewayRestart", () => {
522514},
523515});
524516525-expect(snapshot).toMatchObject({
526-healthy: false,
527-gatewayVersion: "2026.4.24",
528-expectedVersion: "2026.4.24",
529-activatedPluginErrors: [
530-{
531-id: "telegram",
532-origin: "bundled",
533-activated: true,
534-error: "failed to load plugin dependency: ENOSPC",
535-},
536-],
537-});
517+expect(snapshot.healthy).toBe(false);
518+expect(snapshot.gatewayVersion).toBe("2026.4.24");
519+expect(snapshot.expectedVersion).toBe("2026.4.24");
520+expect(snapshot.activatedPluginErrors).toEqual([
521+{
522+id: "telegram",
523+origin: "bundled",
524+activated: true,
525+error: "failed to load plugin dependency: ENOSPC",
526+},
527+]);
538528expect(snapshot.versionMismatch).toBeUndefined();
539-expect(probeGateway).toHaveBeenCalledWith(expect.objectContaining({ includeDetails: true }));
529+expect(firstCallArg<{ includeDetails?: boolean }>(probeGateway).includeDetails).toBe(true);
540530541531const { renderRestartDiagnostics } = await import("./restart-health.js");
542532expect(renderRestartDiagnostics(snapshot).join("\n")).toContain(
@@ -577,12 +567,10 @@ describe("inspectGatewayRestart", () => {
577567expectedVersion: "2026.4.24",
578568});
579569580-expect(snapshot).toMatchObject({
581-healthy: false,
582-waitOutcome: "plugin-errors",
583-elapsedMs: 0,
584-activatedPluginErrors: [expect.objectContaining({ id: "telegram" })],
585-});
570+expect(snapshot.healthy).toBe(false);
571+expect(snapshot.waitOutcome).toBe("plugin-errors");
572+expect(snapshot.elapsedMs).toBe(0);
573+expect(snapshot.activatedPluginErrors?.[0]?.id).toBe("telegram");
586574expect(sleep).not.toHaveBeenCalled();
587575});
588576@@ -615,12 +603,12 @@ describe("inspectGatewayRestart", () => {
615603expectedVersion: "2026.4.24",
616604});
617605618-expect(snapshot).toMatchObject({
619- healthy: false,
620- waitOutcome: "channel-errors",
621- elapsedMs: 0,
622-channelProbeErrors: [{ id: "telegram", error: "This operation was aborted" }],
623-});
606+expect(snapshot.healthy).toBe(false);
607+expect(snapshot.waitOutcome).toBe("channel-errors");
608+expect(snapshot.elapsedMs).toBe(0);
609+expect(snapshot.channelProbeErrors).toEqual([
610+{ id: "telegram", error: "This operation was aborted" },
611+]);
624612expect(sleep).not.toHaveBeenCalled();
625613});
626614@@ -649,13 +637,11 @@ describe("inspectGatewayRestart", () => {
649637it("annotates stopped-free early exits with the actual elapsed time", async () => {
650638const snapshot = await waitForStoppedFreeGatewayRestart();
651639652-expect(snapshot).toMatchObject({
653-healthy: false,
654-runtime: { status: "stopped" },
655-portUsage: { status: "free" },
656-waitOutcome: "stopped-free",
657-elapsedMs: 12_500,
658-});
640+expect(snapshot.healthy).toBe(false);
641+expect(snapshot.runtime.status).toBe("stopped");
642+expect(snapshot.portUsage.status).toBe("free");
643+expect(snapshot.waitOutcome).toBe("stopped-free");
644+expect(snapshot.elapsedMs).toBe(12_500);
659645expect(sleep).toHaveBeenCalledTimes(25);
660646});
661647@@ -664,13 +650,11 @@ describe("inspectGatewayRestart", () => {
664650665651const snapshot = await waitForStoppedFreeGatewayRestart();
666652667-expect(snapshot).toMatchObject({
668-healthy: false,
669-runtime: { status: "stopped" },
670-portUsage: { status: "free" },
671-waitOutcome: "stopped-free",
672-elapsedMs: 92_500,
673-});
653+expect(snapshot.healthy).toBe(false);
654+expect(snapshot.runtime.status).toBe("stopped");
655+expect(snapshot.portUsage.status).toBe("free");
656+expect(snapshot.waitOutcome).toBe("stopped-free");
657+expect(snapshot.elapsedMs).toBe(92_500);
674658expect(sleep).toHaveBeenCalledTimes(185);
675659});
676660@@ -704,13 +688,11 @@ describe("inspectGatewayRestart", () => {
704688delayMs: 1_000,
705689});
706690707-expect(snapshot).toMatchObject({
708-healthy: true,
709-gatewayVersion: "2026.4.26",
710-expectedVersion: "2026.4.26",
711-waitOutcome: "healthy",
712-elapsedMs: 1_000,
713-});
691+expect(snapshot.healthy).toBe(true);
692+expect(snapshot.gatewayVersion).toBe("2026.4.26");
693+expect(snapshot.expectedVersion).toBe("2026.4.26");
694+expect(snapshot.waitOutcome).toBe("healthy");
695+expect(snapshot.elapsedMs).toBe(1_000);
714696expect(snapshot.versionMismatch).toBeUndefined();
715697expect(sleep).toHaveBeenCalledTimes(1);
716698});
@@ -732,13 +714,12 @@ describe("inspectGatewayRestart", () => {
732714delayMs: 1_000,
733715});
734716735-expect(snapshot).toMatchObject({
736-healthy: false,
737-runtime: { status: "running", pid: 8000 },
738-portUsage: { status: "free" },
739-waitOutcome: "timeout",
740-elapsedMs: 4_000,
741-});
717+expect(snapshot.healthy).toBe(false);
718+expect(snapshot.runtime.status).toBe("running");
719+expect(snapshot.runtime.pid).toBe(8000);
720+expect(snapshot.portUsage.status).toBe("free");
721+expect(snapshot.waitOutcome).toBe("timeout");
722+expect(snapshot.elapsedMs).toBe(4_000);
742723expect(sleep).toHaveBeenCalledTimes(4);
743724});
744725});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。