Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { cloudAgentBlockFromPayload, cloudAgentHttpsUrl } from "./cloud-agent.js";
|
|
import { projectMessages } from "./events.js";
|
|
|
|
describe("shared cloud agent projection", () => {
|
|
it("updates an existing card when replaying durable events", () => {
|
|
const base = { threadId: "thread", createdAt: "2026-01-01T00:00:00Z", botId: "bot" };
|
|
const block = cloudAgentBlockFromPayload({
|
|
agentId: "agent",
|
|
title: "Task",
|
|
status: "running",
|
|
url: "https://example.test/agent",
|
|
});
|
|
const messages = projectMessages([
|
|
{
|
|
...base,
|
|
id: "first",
|
|
seq: 1,
|
|
type: "thread.message.created",
|
|
payload: { messageId: "card", role: "bot", blocks: [block] },
|
|
},
|
|
{
|
|
...base,
|
|
id: "second",
|
|
seq: 2,
|
|
type: "thread.cloud_agent",
|
|
payload: {
|
|
...block,
|
|
messageId: "card",
|
|
status: "finished",
|
|
prUrl: "https://example.test/pr",
|
|
},
|
|
},
|
|
]);
|
|
expect(messages[0]?.blocks[0]).toMatchObject({
|
|
status: "finished",
|
|
prUrl: "https://example.test/pr",
|
|
});
|
|
});
|
|
it("normalizes invalid statuses and excludes unsafe links on every surface", () => {
|
|
expect(
|
|
cloudAgentBlockFromPayload({
|
|
status: "invalid",
|
|
url: "javascript:alert(1)",
|
|
prUrl: "http://example.test/pr",
|
|
}),
|
|
).toMatchObject({ status: "running", url: "" });
|
|
for (const url of [
|
|
"javascript:alert(1)",
|
|
"file:///tmp/fake",
|
|
"https://user:password@example.test",
|
|
"invalid",
|
|
])
|
|
expect(cloudAgentHttpsUrl(url)).toBeUndefined();
|
|
});
|
|
});
|