Let guests keep a published rule via Save & Exit and a post-finalize sign-in prompt.

Email is optional so they can continue without saving; skip from Save & Exit leaves the flow instead of returning to completed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilallo
2026-09-02 16:18:41 -06:00
co-authored by Cursor
parent 84ef943df4
commit db34a1f0df
17 changed files with 521 additions and 60 deletions
+105 -1
View File
@@ -1,4 +1,4 @@
import { Suspense } from "react";
import { Suspense, useState } from "react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
@@ -47,6 +47,7 @@ import { setTransferPendingFlag } from "../../app/(app)/create/utils/anonymousDr
function LoginTrigger() {
const { openLogin, closeLogin } = useAuthModal();
const [leftCompleted, setLeftCompleted] = useState(false);
return (
<div>
<button type="button" onClick={() => openLogin()}>
@@ -63,9 +64,33 @@ function LoginTrigger() {
>
Open save progress
</button>
<button
type="button"
onClick={() =>
openLogin({
variant: "keepRule",
nextPath: "/create/completed",
})
}
>
Open keep rule
</button>
<button
type="button"
onClick={() =>
openLogin({
variant: "keepRule",
nextPath: "/create/completed",
onDismiss: () => setLeftCompleted(true),
})
}
>
Open keep rule then leave
</button>
<button type="button" onClick={() => closeLogin()}>
Close from outside
</button>
{leftCompleted ? <p>Left completed</p> : null}
</div>
);
}
@@ -133,6 +158,9 @@ describe("AuthModalProvider (header overlay)", () => {
await waitFor(() => {
expect(screen.getByRole("dialog")).toBeInTheDocument();
});
expect(
screen.queryByRole("button", { name: /continue without saving/i }),
).not.toBeInTheDocument();
await user.type(
screen.getByRole("textbox", { name: /email address/i }),
"guest@example.com",
@@ -149,4 +177,80 @@ describe("AuthModalProvider (header overlay)", () => {
});
expect(setTransferPendingFlag).toHaveBeenCalled();
});
it("keepRule openLogin does not set transfer pending", async () => {
const user = userEvent.setup();
vi.mocked(requestMagicLink).mockResolvedValue({ ok: true });
renderWithProviders(
<Suspense fallback={null}>
<LoginTrigger />
</Suspense>,
);
await user.click(screen.getByRole("button", { name: /^open keep rule$/i }));
await waitFor(() => {
expect(screen.getByRole("dialog")).toBeInTheDocument();
});
expect(
screen.getByRole("heading", {
name: /sign in to keep this rule on your profile/i,
}),
).toBeInTheDocument();
await user.type(
screen.getByRole("textbox", { name: /email address/i }),
"guest@example.com",
);
await user.click(
screen.getByRole("button", { name: /send me a magic link/i }),
);
await waitFor(() => {
expect(requestMagicLink).toHaveBeenCalledWith(
"guest@example.com",
"/create/completed",
undefined,
);
});
expect(setTransferPendingFlag).not.toHaveBeenCalled();
});
it("keepRule continue without saving closes the overlay", async () => {
const user = userEvent.setup();
renderWithProviders(
<Suspense fallback={null}>
<LoginTrigger />
</Suspense>,
);
await user.click(screen.getByRole("button", { name: /^open keep rule$/i }));
await waitFor(() => {
expect(screen.getByRole("dialog")).toBeInTheDocument();
});
await user.click(
screen.getByRole("button", { name: /continue without saving/i }),
);
await waitFor(() => {
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
});
expect(screen.queryByText("Left completed")).not.toBeInTheDocument();
});
it("keepRule onDismiss runs when continue without saving is pressed", async () => {
const user = userEvent.setup();
renderWithProviders(
<Suspense fallback={null}>
<LoginTrigger />
</Suspense>,
);
await user.click(
screen.getByRole("button", { name: /open keep rule then leave/i }),
);
await waitFor(() => {
expect(screen.getByRole("dialog")).toBeInTheDocument();
});
await user.click(
screen.getByRole("button", { name: /continue without saving/i }),
);
await waitFor(() => {
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
});
expect(screen.getByText("Left completed")).toBeInTheDocument();
});
});