mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 19:52:49 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70cd36d732 |
@@ -4440,3 +4440,49 @@ describe("HostRuntimeStore initial connection hint bootstrap", () => {
|
||||
expect(store.getHosts()).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
// Diagnostic coverage for #3817. Corrupt storage is injected explicitly;
|
||||
// these tests do not reproduce the macOS 0.5.1 -> 0.5.2 updater.
|
||||
describe("host registry preservation during startup (#3817 diagnostic)", () => {
|
||||
it("loads a valid saved remote host without changing its registry", async () => {
|
||||
const host = makeHost();
|
||||
const raw = JSON.stringify([host]);
|
||||
const storage = createMemoryHostRuntimeStorage({
|
||||
"@paseo:daemon-registry": raw,
|
||||
"@paseo:e2e": "1",
|
||||
});
|
||||
const store = createAppearanceStore(storage);
|
||||
try {
|
||||
await store.boot();
|
||||
expect(store.getHosts().map((entry) => entry.serverId)).toEqual([host.serverId]);
|
||||
expect(await storage.getItem("@paseo:daemon-registry")).toBe(raw);
|
||||
} finally {
|
||||
store.syncHosts([]);
|
||||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
["malformed JSON", "[{"],
|
||||
[
|
||||
"an unknown field beside a valid host",
|
||||
JSON.stringify([
|
||||
makeHost(),
|
||||
{ ...makeHost({ serverId: "srv_other" }), unexpectedField: true },
|
||||
]),
|
||||
],
|
||||
])("preserves saved bytes when startup encounters %s", async (_name, raw) => {
|
||||
const storage = createMemoryHostRuntimeStorage({
|
||||
"@paseo:daemon-registry": raw,
|
||||
"@paseo:e2e": "1",
|
||||
});
|
||||
const store = createAppearanceStore(storage);
|
||||
try {
|
||||
await store.boot();
|
||||
expect(store.getHostRegistryStatus()).toBe("ready");
|
||||
expect(store.getHosts()).toEqual([]);
|
||||
expect(await storage.getItem("@paseo:daemon-registry")).toBe(raw);
|
||||
} finally {
|
||||
store.syncHosts([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { createDaemonTestContext } from "../test-utils/index.js";
|
||||
import { DaemonClient } from "../test-utils/daemon-client.js";
|
||||
import type { SessionOutboundMessage } from "../messages.js";
|
||||
|
||||
test("deleting an agent removes it from every connected agent subscription", async () => {
|
||||
const ctx = await createDaemonTestContext();
|
||||
const observer = new DaemonClient({ url: `ws://127.0.0.1:${ctx.daemon.port}/ws` });
|
||||
const updates: SessionOutboundMessage[] = [];
|
||||
const requestorUpdates: SessionOutboundMessage[] = [];
|
||||
try {
|
||||
await observer.connect();
|
||||
const agent = await ctx.client.createAgent({
|
||||
provider: "codex",
|
||||
cwd: ctx.daemon.staticDir,
|
||||
title: "Cross-client deletion",
|
||||
});
|
||||
const snapshot = await observer.fetchAgents({ subscribe: {} });
|
||||
expect(snapshot.entries.some((entry) => entry.agent.id === agent.id)).toBe(true);
|
||||
observer.subscribeRawMessages((message) => updates.push(message));
|
||||
ctx.client.subscribeRawMessages((message) => requestorUpdates.push(message));
|
||||
|
||||
await ctx.client.deleteAgent(agent.id);
|
||||
|
||||
// The record is gone, and a fresh query sees that. An existing subscriber
|
||||
// must learn the same fact without reconnecting or fetching another list.
|
||||
const afterDelete = await ctx.client.fetchAgents();
|
||||
expect(afterDelete.entries.some((entry) => entry.agent.id === agent.id)).toBe(false);
|
||||
expect(
|
||||
requestorUpdates.some(
|
||||
(message) =>
|
||||
message.type === "agent_update" &&
|
||||
message.payload.kind === "remove" &&
|
||||
message.payload.agentId === agent.id,
|
||||
),
|
||||
).toBe(true);
|
||||
await expect(observer.fetchAgentTimeline(agent.id, { direction: "tail" })).rejects.toThrow(
|
||||
"Agent not found",
|
||||
);
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
updates.some(
|
||||
(message) =>
|
||||
message.type === "agent_update" &&
|
||||
message.payload.kind === "remove" &&
|
||||
message.payload.agentId === agent.id,
|
||||
),
|
||||
{ timeout: 2_000 },
|
||||
)
|
||||
.toBe(true);
|
||||
} finally {
|
||||
await observer.close();
|
||||
await ctx.cleanup();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user