feat: let guests publish a CommunityRule and claim it on this browser later
Finalize no longer requires a magic link. Guest rows stay off the catalog until sign-in on the same browser attaches ownership, and the login modal kebab no longer acts as a second close. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,11 +28,13 @@ vi.mock("../../../lib/create/lastPublishedRule", () => ({
|
||||
}));
|
||||
|
||||
const emptyState = {} as CreateFlowState;
|
||||
const signedIn = { id: "user-1", email: "owner@example.com" };
|
||||
|
||||
describe("useCreateFlowFinalize", () => {
|
||||
const router = { push: vi.fn() };
|
||||
const updateState = vi.fn();
|
||||
const openLogin = vi.fn();
|
||||
const onGuestPublished = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(publishRule).mockReset();
|
||||
@@ -41,6 +43,7 @@ describe("useCreateFlowFinalize", () => {
|
||||
router.push.mockReset();
|
||||
updateState.mockReset();
|
||||
openLogin.mockReset();
|
||||
onGuestPublished.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -61,6 +64,7 @@ describe("useCreateFlowFinalize", () => {
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/final-review",
|
||||
sessionUser: signedIn,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -80,6 +84,99 @@ describe("useCreateFlowFinalize", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does not publish while the session is unresolved", async () => {
|
||||
const { result } = renderHook(() =>
|
||||
useCreateFlowFinalize({
|
||||
state: emptyState,
|
||||
router,
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/final-review",
|
||||
sessionUser: undefined,
|
||||
}),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.finalize();
|
||||
});
|
||||
|
||||
expect(publishRule).not.toHaveBeenCalled();
|
||||
expect(router.push).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("omits stakeholder emails when a guest publishes with invites in state", async () => {
|
||||
vi.mocked(publishRule).mockResolvedValue({
|
||||
ok: true,
|
||||
id: "guest-rule-id",
|
||||
title: "Published title",
|
||||
});
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCreateFlowFinalize({
|
||||
state: {
|
||||
...emptyState,
|
||||
stakeholderEmails: ["invitee@example.com"],
|
||||
},
|
||||
router,
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/final-review",
|
||||
sessionUser: null,
|
||||
onGuestPublished,
|
||||
}),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.finalize();
|
||||
});
|
||||
|
||||
expect(publishRule).toHaveBeenCalledWith({
|
||||
title: "Published title",
|
||||
summary: "Published summary",
|
||||
document: {},
|
||||
});
|
||||
expect(onGuestPublished).toHaveBeenCalledWith({ skippedInvites: true });
|
||||
expect(openLogin).not.toHaveBeenCalled();
|
||||
expect(router.push).toHaveBeenCalledWith(
|
||||
`/create/completed?${CREATE_FLOW_COMPLETED_CELEBRATE_QUERY}=${CREATE_FLOW_COMPLETED_CELEBRATE_VALUE}`,
|
||||
);
|
||||
});
|
||||
|
||||
it("hints to claim later when a guest publishes without stakeholder emails", async () => {
|
||||
vi.mocked(publishRule).mockResolvedValue({
|
||||
ok: true,
|
||||
id: "guest-rule-id",
|
||||
title: "Published title",
|
||||
});
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCreateFlowFinalize({
|
||||
state: emptyState,
|
||||
router,
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/final-review",
|
||||
sessionUser: null,
|
||||
onGuestPublished,
|
||||
}),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.finalize();
|
||||
});
|
||||
|
||||
expect(publishRule).toHaveBeenCalledWith({
|
||||
title: "Published title",
|
||||
summary: "Published summary",
|
||||
document: {},
|
||||
});
|
||||
expect(onGuestPublished).toHaveBeenCalledWith({ skippedInvites: false });
|
||||
expect(openLogin).not.toHaveBeenCalled();
|
||||
expect(router.push).toHaveBeenCalledWith(
|
||||
`/create/completed?${CREATE_FLOW_COMPLETED_CELEBRATE_QUERY}=${CREATE_FLOW_COMPLETED_CELEBRATE_VALUE}`,
|
||||
);
|
||||
});
|
||||
|
||||
it("passes stakeholderEmails to publishRule on initial publish", async () => {
|
||||
vi.mocked(publishRule).mockResolvedValue({
|
||||
ok: true,
|
||||
@@ -97,6 +194,7 @@ describe("useCreateFlowFinalize", () => {
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/final-review",
|
||||
sessionUser: signedIn,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -124,6 +222,7 @@ describe("useCreateFlowFinalize", () => {
|
||||
openLogin,
|
||||
updateState,
|
||||
loginReturnPath: "/create/edit-rule",
|
||||
sessionUser: signedIn,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user