mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 19:28:46 +01:00
test(e2e): bind secret proposal review to expanded card
This commit is contained in:
1 parent
8bbf313552
commit
e386933481
2 files changed
+32
-1
No files matched your search
@@ -30,6 +30,9 @@ export function truthfulPendingProposalDisplay(row:SecretProposalView,card:unkno
|
||||
&&(card as RequestConfirmationInteraction).status==="pending"&&!(card as RequestConfirmationInteraction).resolvedByUserId
|
||||
&&(!reply.trim()||truthfulPendingProposal(reply));
|
||||
}
|
||||
export function secretProposalCardSelector(interactionId:string){
|
||||
return `[data-testid="task-chat-interaction"][id=${JSON.stringify(`interaction-${interactionId}`)}]`;
|
||||
}
|
||||
async function recordPendingProposalDisplay(ctx:ChatCatalogContext,state:Record<string,unknown>,row:SecretProposalView){
|
||||
const cards=await ctx.input.api.get<RequestConfirmationInteraction[]>(`/api/issues/${ctx.issue()!.id}/interactions`);
|
||||
const card=cards.find(c=>c.kind==="request_confirmation"&&c.payload.secretProposal?.proposalId===row.id);
|
||||
@@ -38,7 +41,7 @@ async function recordPendingProposalDisplay(ctx:ChatCatalogContext,state:Record<
|
||||
const target=await ctx.input.api.get<AgentConfig>(`/api/agents/${state.morganId}`);
|
||||
const bindingAbsentBeforeDecision=(await bindings(ctx,String(state.secretId))).length===0&&!(target.adapterConfig.env as Record<string,unknown>|undefined)?.PUBLISHING_API_KEY;
|
||||
if(!bindingAbsentBeforeDecision)throw new Error("The pending proposal already changed Morgan's binding before human approval");
|
||||
const view=ctx.input.page.locator(`[id=${JSON.stringify(`interaction-${card!.id}`)}]`);
|
||||
const view=ctx.input.page.locator(secretProposalCardSelector(card!.id));
|
||||
await expect(view).toBeVisible();for(const text of [row.secretName!,row.target!.name,row.configPath!])await expect(view).toContainText(text);
|
||||
const displays=(state.pendingProposalDisplays??[]) as PendingProposalDisplay[];
|
||||
state.pendingProposalDisplays=[...displays,{proposalId:row.id,personId:String(state.personId),visible:true,bindingAbsentBeforeDecision,card:card!}];
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// @vitest-environment jsdom
|
||||
import { afterEach, expect, it, vi } from "vitest";
|
||||
vi.mock("@playwright/test", () => ({ expect: vi.fn() }));
|
||||
vi.mock("./api.js", () => ({ pollUntil: vi.fn() }));
|
||||
vi.mock("./run-observations.js", () => ({ collectRunEvents: vi.fn() }));
|
||||
vi.mock("./chat-catalog-domains/external-secret-scan.js", () => ({ scanReachableSecretOutputs: vi.fn(), privateScanJson: vi.fn(), bytesContainSecret: vi.fn(), sameSecretIdentity: vi.fn() }));
|
||||
// Isolate the CSS/DOM regression from unrelated Node-only runtime setup.
|
||||
vi.mock("./chat-flow.js", () => ({ sendChatMessage: vi.fn() }));
|
||||
vi.mock("./chat-catalog-domains/identity-support.js", () => ({ identityWorker: vi.fn(), openStandingChat: vi.fn(), probeAgentPermission: vi.fn() }));
|
||||
vi.mock("./chat-catalog-domains/external-support.js", () => ({ definition: () => ({}), observeExternal: vi.fn(), externalObservation: vi.fn(), checks: vi.fn(), root: vi.fn(), verifyRenderedReply: vi.fn() }));
|
||||
import { secretProposalCardSelector } from "./chat-catalog-domains/external-secret-proposal.js";
|
||||
afterEach(() => { document.body.innerHTML = ""; });
|
||||
it("selects the actual expanded proposal card when the pending trigger has the same production interaction ID", () => {
|
||||
document.body.innerHTML = `<button id="interaction-owned" data-testid="task-chat-pending-request" aria-label="Open request: Confirm secret binding">Confirm secret binding</button>
|
||||
<div id="interaction-owned" data-testid="task-chat-interaction"><p>Deployment publishing key</p><p>Morgan</p><p>env.PUBLISHING_API_KEY</p></div>
|
||||
<div id="interaction-other" data-testid="task-chat-interaction"><p>Other request</p></div>`;
|
||||
expect(document.querySelectorAll('[id="interaction-owned"]')).toHaveLength(2);
|
||||
const selected = document.querySelectorAll(secretProposalCardSelector("owned"));
|
||||
expect(selected).toHaveLength(1); expect(selected[0]?.tagName).toBe("DIV");
|
||||
for (const fact of ["Deployment publishing key", "Morgan", "env.PUBLISHING_API_KEY"]) expect(selected[0]?.textContent).toContain(fact);
|
||||
expect(document.querySelectorAll(secretProposalCardSelector("missing"))).toHaveLength(0);
|
||||
});
|
||||
it("a trigger, unrelated card or completed receipt cannot stand in for the bound proposal card", () => {
|
||||
document.body.innerHTML = `<button id="interaction-owned" data-testid="task-chat-pending-request">Confirm secret binding</button>
|
||||
<div id="interaction-foreign" data-testid="task-chat-interaction">Deployment publishing key Morgan env.PUBLISHING_API_KEY</div>
|
||||
<div id="interaction-owned" data-testid="task-chat-interaction-receipt">Approved</div>`;
|
||||
expect(document.querySelectorAll(secretProposalCardSelector("owned"))).toHaveLength(0);
|
||||
});
|
||||
Reference in new issue
Block a user