fix(mcp): preserve write opt-out across organization selection

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-03 06:59:46 -05:00
1 parent 024de57978
commit dba2caf2f6
3 files changed
+14 -3

No files matched your search

+9 -2
View File
@@ -20,7 +20,10 @@ vi.mock("../api/client", () => ({ api: {
get: vi.fn(async () => ({
id: route.id, clientName: "Assistant", redirectOrigin: "https://assistant.example.test",
requestedWrite: route.requestedWrite, offlineAccess: true, requiresSignIn: false, requestedCompanyId: route.companyId,
companies: route.unavailable ? [] : [{ id: route.companyId ?? "company-one", name: "Acme Research", logoUrl: "/api/assets/acme-logo/content", canWrite: route.canWrite }], setupUrl: null,
companies: route.unavailable ? [] : [
{ id: route.companyId ?? "company-one", name: "Acme Research", logoUrl: "/api/assets/acme-logo/content", canWrite: route.canWrite },
...(!route.companyId ? [{ id: "company-two", name: "Design Partners", logoUrl: null, canWrite: true }] : []),
], setupUrl: null,
})),
post: vi.fn(() => new Promise(() => {})),
} }));
@@ -45,7 +48,7 @@ function setup() {
};
}
it("defaults eligible writes on after selection, preserves opt-out on refetch, and submits read-only consent", async () => {
it("defaults eligible writes on and preserves opt-out across organization changes and refetch", async () => {
const page = setup();
try {
await vi.waitFor(() => expect(page.container.querySelector('input[type="radio"]')).not.toBeNull());
@@ -54,6 +57,10 @@ it("defaults eligible writes on after selection, preserves opt-out on refetch, a
flushSync(() => (page.container.querySelector('input[type="radio"]') as HTMLInputElement).click());
expect(page.checkbox().getAttribute("aria-checked")).toBe("true");
flushSync(() => page.checkbox().click());
flushSync(() => (page.container.querySelector('input[value="company-two"]') as HTMLInputElement).click());
expect(page.checkbox().getAttribute("aria-checked")).toBe("false");
flushSync(() => (page.container.querySelector('input[value="company-one"]') as HTMLInputElement).click());
expect(page.checkbox().getAttribute("aria-checked")).toBe("false");
await page.client.invalidateQueries({ queryKey: ["mcp-request", route.id] });
expect(page.checkbox().getAttribute("aria-checked")).toBe("false");
flushSync(() => page.connect().click());
+1 -1
View File
@@ -44,7 +44,7 @@ function McpConnectRequest({ id }: { id: string }) {
</div> : <fieldset className="space-y-2" disabled={consent.isPending}>
<legend className="mb-2 text-sm font-medium">Organization</legend>
{data.companies.map((item) => <label key={item.id} className="flex items-center gap-3 rounded-md border border-border p-3 text-sm">
<input type="radio" name="company" aria-label={item.name} value={item.id} checked={companyId === item.id} onChange={() => { setCompanyId(item.id); setWriteEnabled(true); }} />
<input type="radio" name="company" aria-label={item.name} value={item.id} checked={companyId === item.id} onChange={() => setCompanyId(item.id)} />
<CompanyPatternIcon companyName={item.name} logoUrl={item.logoUrl} className="size-12 shrink-0 rounded-lg" />
<span className="min-w-0 break-words font-medium">{item.name}</span>
</label>)}
@@ -27,10 +27,14 @@ export const AllowDelegation: Story = { play: async context => {
export const SwitchingOrganizationsResetsConsent: Story = { play: async context => {
await AllowDelegation.play!(context);
const c = within(context.canvasElement);
await userEvent.click(c.getByRole("checkbox"));
await userEvent.click(c.getByRole("radio", { name: "Design Partners" }));
await expect(c.getByRole("checkbox")).not.toBeChecked();
await expect(c.getByRole("checkbox")).toBeDisabled();
await expect(c.getByText("Your role in this organization is read-only.")).toBeVisible();
await userEvent.click(c.getByRole("radio", { name: "Acme Research" }));
await expect(c.getByRole("checkbox")).toBeEnabled();
await expect(c.getByRole("checkbox")).not.toBeChecked();
} };
export const ReadOnlyRequest: Story = { parameters: { fixture: { request: { clientName: "Claude", redirectOrigin: "https://claude.ai", requestedWrite: false, offlineAccess: false } } } };
export const SignInRequired: Story = { parameters: { fixture: { request: { requiresSignIn: true, companies: [] } } } };