Assert rich ACP admission and notice disclosure behavior

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-09-28 12:22:23 -05:00
1 parent 04b88a97f5
commit f52baa537e
3 files changed
+41 -9

No files matched your search

@@ -30,7 +30,7 @@ describe("Paperclip Runner Codex configuration", () => {
expect(html).toContain('<option value="codex" selected="">Codex</option>');
expect(html).toContain("OpenCode 1.18.32");
expect(html).toContain("ACPX");
expect(html).toContain('<option value="acpx">ACP agents</option>');
expect(html).not.toContain("Permission mode");
expect(html).not.toContain("Ask when requested");
expect(html).not.toContain("Ask for untrusted operations");
@@ -54,15 +54,19 @@ describe("Paperclip Runner Codex configuration", () => {
expect(html).not.toContain("Ask for untrusted operations");
});
it("offers ACPX Claude without a redundant agent selector", () => {
it("offers qualified Claude and keeps candidate ACP agents visibly disabled", () => {
const html = renderRunner({
provider: "acpx",
acpxAgent: "claude",
acpxPermissionMode: "approve-reads",
});
expect(html).toContain('<option value="acpx" selected="">ACPX Claude</option>');
expect(html).not.toContain("ACP agent");
expect(html).toContain('<option value="acpx" selected="">ACP agents</option>');
expect(html).toContain("ACP agent");
expect(html).toContain('<option value="claude" selected="">Claude</option>');
expect(html).toContain('<option value="cursor" disabled="">Cursor — qualification pending</option>');
expect(html).toContain('<option value="copilot" disabled="">GitHub Copilot — qualification pending</option>');
expect(html).toContain('<option value="pi" disabled="">Pi — qualification pending</option>');
expect(html).not.toContain("Codex via ACPX");
expect(html).not.toContain("ACPX Codex");
expect(html).not.toContain("Pi via ACPX");
+15 -2
View File
@@ -60,13 +60,26 @@ describe("adapter configuration sections", () => {
"runPolicy",
config,
);
expect(adapter).toContain("ACPX Claude");
expect(adapter).toContain('<option value="acpx">ACP agents</option>');
expect(adapter).not.toContain("Runner lifecycle");
expect(configuration).not.toContain("Permission mode");
expect(configuration).not.toContain("Runner lifecycle");
expect(policy).toContain("Runner lifecycle");
expect(policy).toContain('value="45000"');
expect(policy).not.toContain("ACPX Claude");
expect(policy).not.toContain("ACP agents");
});
it("keeps ACP agent admission choices in the adapter section", () => {
const config = { provider: "acpx", acpxAgent: "claude" };
const adapter = renderSection(CodexLocalConfigFields, "paperclip_runner", "adapter", config);
const policy = renderSection(CodexLocalConfigFields, "paperclip_runner", "runPolicy", config);
expect(adapter).toContain('<option value="claude" selected="">Claude</option>');
expect(adapter).toContain('<option value="pi" disabled="">Pi — qualification pending</option>');
expect(adapter).not.toContain("Runner lifecycle");
expect(policy).toContain("Runner lifecycle");
expect(policy).not.toContain("ACP agent");
expect(policy).not.toContain("qualification pending");
});
it.each([
@@ -178,7 +178,7 @@ describe("TaskChatProtocolActivityRow", () => {
expect(row?.querySelector('[data-testid="task-chat-protocol-activity-icon"]')?.querySelectorAll("path")).toHaveLength(3);
});
it("shows a notice as a warning and full-width message without metadata or a disclosure", () => {
it("keeps a notice readable and preserves metadata in a collapsed disclosure", () => {
const summary = "Project-local configuration is disabled.\nTrust the repository to load its hooks.";
render({
id: "notice", kind: "protocol", surface: "provider_activity", family: "provider_notice",
@@ -186,12 +186,26 @@ describe("TaskChatProtocolActivityRow", () => {
details: [
{ label: "Category", value: "configWarning" },
{ label: "Recoverable", value: "Yes" },
{ label: "Provider", value: "pi" },
{ label: "Provenance", value: "provider_native" },
{ label: "Summary", value: summary },
], steps: [], links: [], children: [],
});
expect(container.textContent).toBe(`Warning${summary}`);
expect(container.textContent).toContain(`Warning${summary}`);
expect(container.querySelector("p")?.textContent).toBe(summary);
expect(container.querySelector("dl")).toBeNull();
const disclosure = container.querySelector("details");
expect(disclosure).not.toBeNull();
expect(disclosure?.open).toBe(false);
expect(disclosure?.querySelector("summary")?.textContent).toBe("Details");
expect(Array.from(disclosure?.querySelectorAll("dt") ?? [], (term) => term.textContent)).toEqual([
"Category", "Recoverable", "Provider", "Provenance",
]);
expect(Array.from(disclosure?.querySelectorAll("dd") ?? [], (value) => value.textContent)).toEqual([
"configWarning", "Yes", "pi", "provider_native",
]);
expect(disclosure?.textContent).not.toContain(summary);
act(() => disclosure?.querySelector("summary")?.click());
expect(disclosure?.open).toBe(true);
expect(container.querySelector("button")).toBeNull();
expect(container.querySelector('[data-testid="task-chat-protocol-activity-icon"]')).not.toBeNull();
});
@@ -214,6 +228,7 @@ describe("TaskChatProtocolActivityRow", () => {
const row = container.querySelector('[data-testid="task-chat-protocol-activity-row"]');
expect(row?.querySelector("button")).toBeNull();
expect(row?.querySelector("details")).toBeNull();
expect(row?.querySelector('[aria-expanded]')).toBeNull();
});
});