import { afterEach, describe, expect, test, vi } from "vitest"; import userEvent from "@testing-library/user-event"; import { within } from "@testing-library/react"; import { cleanup, renderWithProviders as render, screen, } from "../utils/test-utils"; import { ProfilePageView, type ProfilePageViewProps, } from "../../app/(app)/profile/_components/ProfilePage.view"; import messages from "../../messages/en/index"; const copy = messages.pages.profile; afterEach(() => { cleanup(); }); function viewProps( overrides: Partial = {}, ): ProfilePageViewProps { return { userEmail: "dani@example.com", ruleCardSize: "M", profileLgUp: true, profileListSize: "l", rules: [], rulesError: false, draft: null, showDraftCard: false, ruleDeleteOpen: false, ruleDeleteBusy: false, draftDeleteOpen: false, draftDeleteBusy: false, accountDeleteOpen: false, accountDeleteBusy: false, actionError: null, profileSuccessMessage: null, emailChangeOpen: false, emailChangeValue: "", onEmailChangeValueChange: vi.fn(), emailChangeBusy: false, emailChangeRequestSent: false, emailChangeModalError: null, onDismissEmailChangeModalError: vi.fn(), onOpenEmailChange: vi.fn(), onCloseEmailChange: vi.fn(), onSubmitEmailChange: vi.fn(), onSignOut: vi.fn(), onDeleteRule: vi.fn(), onCloseDeleteRule: vi.fn(), onConfirmDeleteRule: vi.fn(), onDuplicateRule: vi.fn(), onContinueDraft: vi.fn(), onDeleteDraft: vi.fn(), onCloseDeleteDraft: vi.fn(), onConfirmDeleteDraft: vi.fn(), onOpenDeleteAccount: vi.fn(), onCloseDeleteAccount: vi.fn(), onConfirmDeleteAccount: vi.fn(), onDismissProfileSuccess: vi.fn(), onDismissActionError: vi.fn(), onDismissRulesError: vi.fn(), onStartNewCustomRule: vi.fn(), ...overrides, }; } describe("ProfilePageView", () => { test("keeps account deletion out of the routine options list", () => { render(); const options = screen.getByRole("navigation", { name: copy.yourOptionsHeading, }); const createRule = within(options).getByRole("button", { name: copy.optionCreateCustom, }); expect(createRule.closest("ul")).not.toBeNull(); expect( within(options).queryByRole("button", { name: copy.deleteAccountConfirm }), ).not.toBeInTheDocument(); expect( within(options).queryByRole("heading", { name: copy.deleteAccount }), ).not.toBeInTheDocument(); const danger = screen.getByRole("region", { name: copy.deleteAccount }); expect(danger).toHaveTextContent(copy.deleteAccountIntro); const deleteAccount = within(danger).getByRole("button", { name: copy.deleteAccountConfirm, }); expect(deleteAccount.closest("ul")).toBeNull(); expect(deleteAccount.className).toContain( "border-[var(--color-border-default-negative-primary)]", ); expect(deleteAccount.className).not.toContain( "bg-[var(--color-surface-inverse-primary)]", ); }); test("asks for confirmation before deleting the account", async () => { const user = userEvent.setup(); const onOpenDeleteAccount = vi.fn(); const onConfirmDeleteAccount = vi.fn(); const { rerender } = render( , ); await user.click( screen.getByRole("button", { name: copy.deleteAccountConfirm }), ); expect(onOpenDeleteAccount).toHaveBeenCalledTimes(1); rerender( , ); const dialog = screen.getByRole("dialog", { name: copy.deleteAccountModalTitle, }); expect(dialog).toHaveTextContent(copy.deleteAccountModalBody); const confirm = within(dialog).getByRole("button", { name: copy.deleteAccountConfirm, }); expect(confirm.className).toContain( "border-[var(--color-border-default-negative-primary)]", ); expect(confirm.className).not.toContain( "bg-[var(--color-surface-inverse-primary)]", ); await user.click(confirm); expect(onConfirmDeleteAccount).toHaveBeenCalledTimes(1); }); });