fix: streamline subscription connection dialogs and actions
This commit is contained in:
@@ -88,6 +88,9 @@ test("disconnected row uses shared Connect action; initial default is ON; cancel
|
||||
assert(!document.body.textContent?.includes(CHATGPT_NOTICE)); const trigger = byTest("chatgpt-login");
|
||||
assert.match(trigger.className, /cursor-pointer/); assert.match(trigger.className, /hover:bg-accent/); assert.match(trigger.className, /focus-visible:ring/);
|
||||
await click(trigger); assert.equal(f.calls.login.length, 0); assert(document.body.textContent?.includes(CHATGPT_NOTICE));
|
||||
assert.equal(byTest("chatgpt-account-dialog").querySelector("h2")?.textContent, "ChatGPT");
|
||||
assert.equal(byTest("chatgpt-proceed").textContent, "Continue with ChatGPT"); assert(byTest("chatgpt-proceed").querySelector('img[src="/siwc/chatgpt-logo-white.svg"]'));
|
||||
assert(!button("Continue", byTest("chatgpt-account-dialog")), "ChatGPT remains one step, with disclosure and toggle together");
|
||||
assert.equal(toggle().getAttribute("aria-checked"), "true");
|
||||
assert.equal(toggle().getAttribute("aria-label"), "Allow background use for all ChatGPT accounts");
|
||||
assert(byTest("chatgpt-global-background").textContent?.includes("Background work counts toward your ChatGPT plan usage."));
|
||||
@@ -180,23 +183,33 @@ test("email-only connected selector and Manage remain responsive; account select
|
||||
assert.deepEqual([...document.querySelectorAll('select[aria-label="ChatGPT account"] option')].map((o) => o.textContent), ["learner@example.invalid", "second@example.invalid", "ChatGPT account"]);
|
||||
assert.doesNotMatch(byTest("chatgpt-connection").textContent!, /private-registration|private-issued| · active|signed-out/);
|
||||
assert.match(byTest("chatgpt-connection").firstElementChild!.className, /items-center/);
|
||||
const row = byTest("chatgpt-connection").firstElementChild!;
|
||||
assert.equal(row.children[0]!.textContent, "ChatGPT"); assert.equal(row.children[1]!.tagName, "SELECT"); assert.equal(row.children[2]!.textContent, "Manage…");
|
||||
assert.match(row.children[2]!.className, /text-muted-foreground/); assert(!row.textContent?.includes("Connected"));
|
||||
await selectAccount("ChatGPT account", "second"); assert.deepEqual(f.calls.select, ["second"]); assert.equal(f.status.allowBackgroundUse, false);
|
||||
await click(button("Manage…")); assert(byTest("chatgpt-managed-identity").textContent?.includes("second@example.invalid"));
|
||||
assert.deepEqual([...byTest("chatgpt-account-footer").querySelectorAll("button")].map((b) => b.textContent), ["Add accounts", "Close"]);
|
||||
assert.deepEqual([...byTest("chatgpt-account-footer").querySelectorAll("button")].map((b) => b.textContent), ["Disconnect", "Close"]);
|
||||
const dialog = byTest("chatgpt-account-dialog").innerHTML;
|
||||
assert(dialog.indexOf('data-testid="chatgpt-managed-identity"') < dialog.indexOf('data-testid="chatgpt-account-actions"'));
|
||||
assert(dialog.indexOf('data-testid="chatgpt-account-actions"') < dialog.indexOf('data-testid="chatgpt-global-background"'));
|
||||
assert(dialog.indexOf('data-testid="chatgpt-global-background"') < dialog.indexOf('data-testid="chatgpt-managed-identity"'));
|
||||
assert(!byTest("chatgpt-account-dialog").querySelector('[data-testid="chatgpt-privacy-notice"]'));
|
||||
assert.equal(byTest("chatgpt-account-dialog").querySelector("h2")?.textContent, "ChatGPT");
|
||||
assert(byTest("chatgpt-account-dialog").querySelector('a[href="https://openai.com/policies/privacy-policy/"]'));
|
||||
assert(byTest("chatgpt-account-dialog").querySelector('a[href="https://chatgpt.com/settings/usage"]'));
|
||||
await click(toggle()); assert.deepEqual(f.calls.consent, [true]); assert.equal(toggle().getAttribute("aria-checked"), "true");
|
||||
await click(button("Close")); await selectAccount("ChatGPT account", "private-registration-id"); assert.equal(f.status.allowBackgroundUse, true);
|
||||
assert.equal(f.calls.logout, 0);
|
||||
});
|
||||
|
||||
test("Disconnect account stays under identity, outside the nondestructive Manage footer; confirmation Cancel never forgets", async () => {
|
||||
test("Disconnect is the quiet red left-footer action below identity; confirmation Cancel never forgets", async () => {
|
||||
assert.deepEqual(CHATGPT_DISCONNECT_COPY, { title: "Disconnect account?", body: "This removes the saved account and its credentials from this device." });
|
||||
const f = fixture(connected()); await mount(); await click(button("Manage…"));
|
||||
assert.equal(byTest("chatgpt-account-actions").textContent, "Disconnect account"); assert.match(byTest("chatgpt-disconnect").className, /text-red/);
|
||||
assert(!byTest("chatgpt-account-footer").contains(byTest("chatgpt-disconnect")));
|
||||
assert.equal(byTest("chatgpt-account-actions").textContent, "Disconnect"); assert.match(byTest("chatgpt-disconnect").className, /text-red/);
|
||||
assert.equal(byTest("chatgpt-account-footer").firstElementChild, byTest("chatgpt-account-actions"));
|
||||
assert.equal(byTest("chatgpt-account-footer").lastElementChild?.lastElementChild, button("Close"));
|
||||
assert(!byTest("chatgpt-account-footer").contains(byTest("chatgpt-add-accounts")));
|
||||
await click(byTest("chatgpt-disconnect")); assert.equal(f.calls.disconnect.length, 0);
|
||||
assert.equal(byTest("chatgpt-account-dialog").querySelector("h2")?.textContent, "ChatGPT");
|
||||
assert(byTest("chatgpt-disconnect-confirmation").textContent?.includes(CHATGPT_DISCONNECT_COPY.title));
|
||||
assert(byTest("chatgpt-disconnect-confirmation").textContent?.includes(CHATGPT_DISCONNECT_COPY.body));
|
||||
assert(!document.body.textContent?.includes("delete your OpenAI"));
|
||||
@@ -208,8 +221,9 @@ for (const count of [1, 3]) test(`Add accounts reuses the actual add flow with $
|
||||
const initial = connected(count === 3);
|
||||
initial.accounts = [account(), ...Array.from({ length: count - 1 }, (_, i) => account(`saved-${i}`, `saved-${i}@example.invalid`))];
|
||||
const f = fixture(initial); const before = structuredClone(initial); await mount(); await click(button("Manage…"));
|
||||
assert.deepEqual([...byTest("chatgpt-account-footer").querySelectorAll("button")].map((b) => b.textContent), ["Add accounts", "Close"]);
|
||||
assert.equal(byTest("chatgpt-add-accounts").getAttribute("data-variant"), "outline");
|
||||
assert.deepEqual([...byTest("chatgpt-account-footer").querySelectorAll("button")].map((b) => b.textContent), ["Disconnect", "Close"]);
|
||||
assert.equal(byTest("chatgpt-add-accounts").getAttribute("data-variant"), "ghost");
|
||||
assert.equal(byTest("chatgpt-add-accounts").parentElement, byTest("chatgpt-account-strip"));
|
||||
assert.match(byTest("chatgpt-add-accounts").className, /cursor-pointer/);
|
||||
await click(byTest("chatgpt-add-accounts"));
|
||||
assert(byTest("chatgpt-privacy-notice").textContent?.includes(CHATGPT_NOTICE)); assert(byTest("chatgpt-proceed"));
|
||||
@@ -226,6 +240,19 @@ for (const count of [1, 3]) test(`Add accounts reuses the actual add flow with $
|
||||
assert.deepEqual(f.status, before); assert.equal(f.calls.cancel, 1); assert.deepEqual(f.calls.consent, []); assert.deepEqual(f.calls.disconnect, []);
|
||||
});
|
||||
|
||||
test("ChatGPT Sign in again is reserved for a saved disconnected account and keeps its existing registration flow", async () => {
|
||||
const f = fixture(connected(false)); await mount(); await click(button("Manage…"));
|
||||
assert(!button("Sign in again")); await selectAccount("Manage ChatGPT account", "signed-out-record"); assert(button("Sign in again"));
|
||||
await click(button("Sign in again")); assert.equal(byTest("chatgpt-account-dialog").querySelector("h2")?.textContent, "ChatGPT");
|
||||
assert(byTest("chatgpt-privacy-notice")); assert(toggle()); assert.equal(toggle().getAttribute("aria-checked"), "false");
|
||||
assert.equal(document.querySelector<HTMLSelectElement>('select[aria-label="Saved ChatGPT account"]')?.value, "signed-out-record"); assert.deepEqual(f.calls.login, []);
|
||||
await click(byTest("chatgpt-proceed")); assert.deepEqual(f.calls.login, ["signed-out-record"]); assert.equal(f.status.activeId, "private-registration-id");
|
||||
await click(button("Cancel", byTest("chatgpt-account-dialog"))); assert.equal(f.calls.cancel, 1); assert.deepEqual(f.calls.disconnect, []); assert.deepEqual(f.calls.consent, []);
|
||||
});
|
||||
test("connected setup row retains the email dropdown before muted Manage", async () => {
|
||||
fixture(connected()); await mount(<ChatGPTConnection setup />);
|
||||
const row = byTest("chatgpt-connection").firstElementChild!; assert.equal(row.children[1]!.tagName, "SELECT"); assert.equal(row.children[2]!.textContent, "Manage…"); assert.match(row.children[2]!.className, /text-muted-foreground/);
|
||||
});
|
||||
test("Add accounts reuses the existing dialog's initial focus for the pre-auth transition", async () => {
|
||||
const previous = HTMLElement.prototype.focus; const focused: HTMLElement[] = [];
|
||||
HTMLElement.prototype.focus = function () { focused.push(this); };
|
||||
|
||||
Reference in New Issue
Block a user