Merge pull request 'Place account deletion in its own danger row' (#82) from adilallo/fix/CR-207-delete-account-danger into main
Reviewed-on: #82
This commit was merged in pull request #82.
This commit is contained in:
commit
2653ae4602
3 files changed
+166
-20
No files matched your search
@@ -6,6 +6,7 @@ import Rule from "../../../components/cards/Rule";
|
||||
import TextInput from "../../../components/controls/TextInput";
|
||||
import List from "../../../components/layout/List";
|
||||
import type { ListItem, ListSize } from "../../../components/layout/List";
|
||||
import ListEntry from "../../../components/layout/ListEntry";
|
||||
import Icon from "../../../components/asset/icon";
|
||||
import Dialog from "../../../components/modals/Dialog";
|
||||
import Alert from "../../../components/modals/Alert";
|
||||
@@ -237,17 +238,8 @@ export function ProfilePageView({
|
||||
leadingIcon: "mail",
|
||||
showDescription: false,
|
||||
},
|
||||
{
|
||||
id: "delete-account",
|
||||
title: t("deleteAccount"),
|
||||
description: "",
|
||||
onClick: onOpenDeleteAccount,
|
||||
leadingIcon: "warning",
|
||||
variant: "danger",
|
||||
showDescription: false,
|
||||
},
|
||||
];
|
||||
}, [t, onSignOut, onOpenDeleteAccount, onOpenEmailChange, onStartNewCustomRule]);
|
||||
}, [t, onSignOut, onOpenEmailChange, onStartNewCustomRule]);
|
||||
|
||||
const ruleCardShellClass =
|
||||
"w-full !max-w-full cursor-default !gap-3 !rounded-[12px] shadow-[0_0_48px_rgba(0,0,0,0.1)] lg:!rounded-[24px] lg:shadow-[0_0_24px_rgba(0,0,0,0.1)]";
|
||||
@@ -406,6 +398,22 @@ export function ProfilePageView({
|
||||
leadingIcon="edit"
|
||||
/>
|
||||
</nav>
|
||||
<section
|
||||
aria-label={t("deleteAccount")}
|
||||
className="w-full overflow-hidden rounded-[12px] border border-[var(--color-border-default-negative-primary)] bg-[var(--color-surface-default-negative-secondary)]"
|
||||
>
|
||||
<ListEntry
|
||||
title={t("deleteAccount")}
|
||||
description=""
|
||||
showDescription={false}
|
||||
onClick={onOpenDeleteAccount}
|
||||
size={profileListSize}
|
||||
leadingIcon="edit"
|
||||
variant="danger"
|
||||
topDivider={false}
|
||||
bottomDivider={false}
|
||||
/>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@@ -502,7 +510,7 @@ export function ProfilePageView({
|
||||
<Button
|
||||
type="button"
|
||||
size="medium"
|
||||
buttonType="filled"
|
||||
buttonType="danger"
|
||||
palette="default"
|
||||
onClick={onConfirmDeleteAccount}
|
||||
disabled={accountDeleteBusy}
|
||||
|
||||
@@ -51,15 +51,8 @@ const ListEntryRow = memo(function ListEntryRow({
|
||||
? `${layout.title} !text-[var(--color-content-default-negative-primary)]`
|
||||
: layout.title;
|
||||
|
||||
const leadingToneClass =
|
||||
variant === "danger"
|
||||
? "text-[var(--color-content-default-negative-primary)]"
|
||||
: "text-[var(--color-content-default-primary)]";
|
||||
|
||||
const chevronToneClass =
|
||||
variant === "danger"
|
||||
? "text-[var(--color-content-default-negative-primary)]"
|
||||
: "text-[var(--color-content-default-primary)]";
|
||||
const leadingToneClass = "text-[var(--color-content-default-primary)]";
|
||||
const chevronToneClass = "text-[var(--color-content-default-primary)]";
|
||||
|
||||
const leadingSlot = (
|
||||
<div className={`${leadingBoxClass} ${leadingToneClass}`}>
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
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> = {},
|
||||
): 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("puts delete account in its own danger area", () => {
|
||||
render(<ProfilePageView {...viewProps()} />);
|
||||
|
||||
const options = screen.getByRole("navigation", {
|
||||
name: copy.yourOptionsHeading,
|
||||
});
|
||||
expect(
|
||||
within(options).getByRole("button", { name: copy.optionCreateCustom }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
within(options).queryByRole("button", { name: copy.deleteAccount }),
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(copy.deleteAccountIntro)).not.toBeInTheDocument();
|
||||
|
||||
const danger = screen.getByRole("region", { name: copy.deleteAccount });
|
||||
expect(danger.className).toContain(
|
||||
"border-[var(--color-border-default-negative-primary)]",
|
||||
);
|
||||
const deleteAccount = within(danger).getByRole("button", {
|
||||
name: copy.deleteAccount,
|
||||
});
|
||||
const deleteTitle = within(deleteAccount).getByText(copy.deleteAccount);
|
||||
expect(deleteTitle.className).toContain(
|
||||
"!text-[var(--color-content-default-negative-primary)]",
|
||||
);
|
||||
expect(deleteAccount.firstElementChild?.className).not.toContain(
|
||||
"negative-primary",
|
||||
);
|
||||
expect(deleteAccount.lastElementChild?.className).not.toContain(
|
||||
"negative-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(
|
||||
<ProfilePageView {...viewProps({ onOpenDeleteAccount })} />,
|
||||
);
|
||||
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: copy.deleteAccount }),
|
||||
);
|
||||
expect(onOpenDeleteAccount).toHaveBeenCalledTimes(1);
|
||||
|
||||
rerender(
|
||||
<ProfilePageView
|
||||
{...viewProps({
|
||||
onOpenDeleteAccount,
|
||||
onConfirmDeleteAccount,
|
||||
accountDeleteOpen: true,
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user