Skip to content

Commit

Permalink
Fix menu for having both verified & unverified accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
asiia-trilitech committed Feb 10, 2025
1 parent 1de9e55 commit d42ab8d
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 50 deletions.
106 changes: 105 additions & 1 deletion apps/web/src/components/Menu/Menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,115 @@ describe("<Menu />", () => {

expect(screen.getByText("Advanced")).toBeVisible();
expect(screen.queryByText("Address Book")).not.toBeInTheDocument();
expect(screen.queryByText("Add Account")).not.toBeInTheDocument();
expect(screen.queryByText("Add Account")).toBeVisible();
expect(screen.queryByText("Save Backup")).not.toBeInTheDocument();
expect(screen.queryByText("Apps")).not.toBeInTheDocument();
expect(screen.getByText("Light mode")).toBeVisible();
expect(screen.getByText("Logout")).toBeVisible();
});

it("opens Add Account modal when Add Account button is clicked", async () => {
const { openWith } = dynamicModalContextMock;
const user = userEvent.setup();
await renderInDrawer(<Menu />, store);

await user.click(screen.getByText("Add Account"));

expect(openWith).toHaveBeenCalledWith(<OnboardOptionsModal />);
});
});

describe.each([
{ selectedAccount: "verified", isVerifiedSelected: true },
{ selectedAccount: "unverified", isVerifiedSelected: false },
])("when user has both and %selectedAccount account selected, ", ({ isVerifiedSelected }) => {
const unverifiedAccount = mockImplicitAccount(1);

beforeEach(() => {
addTestAccount(store, unverifiedAccount);
store.dispatch(
accountsActions.setIsVerified({
pkh: unverifiedAccount.address.pkh,
isVerified: false,
})
);
if (isVerifiedSelected) {
store.dispatch(accountsActions.setCurrent(account.address.pkh));
} else {
store.dispatch(accountsActions.setCurrent(unverifiedAccount.address.pkh));
}
});

it("renders menu items correctly", async () => {
await renderInDrawer(<Menu />, store);

expect(screen.getByText("Advanced")).toBeVisible();
expect(screen.getByText("Address Book")).toBeVisible();
expect(screen.getByText("Add Account")).toBeVisible();
expect(screen.getByText("Save Backup")).toBeVisible();
expect(screen.getByText("Apps")).toBeVisible();
expect(screen.getByText("Light mode")).toBeVisible();
expect(screen.getByText("Logout")).toBeVisible();
});

it.each([
["Advanced", AdvancedMenu],
["Address Book", AddressBookMenu],
["Apps", AppsMenu],
])("opens %label menu correctly", async (label, Component) => {
const user = userEvent.setup();
const { openWith } = dynamicDrawerContextMock;
jest.spyOn(walletKit, "getActiveSessions").mockImplementation(() => ({}));

await renderInDrawer(<Menu />, store);

await user.click(screen.getByText(label));
expect(openWith).toHaveBeenCalledWith(<Component />);
});

it("opens Logout menu correctly", async () => {
const user = userEvent.setup();
const { openWith } = dynamicModalContextMock;

await renderInDrawer(<Menu />, store);

await user.click(screen.getByText("Logout"));
expect(openWith).toHaveBeenCalledWith(<LogoutModal />);
});

it("calls downloadBackupFile function when Save Backup is clicked", async () => {
const user = userEvent.setup();
const mockDownloadBackupFile = jest.fn();
jest.mocked(useDownloadBackupFile).mockReturnValue(mockDownloadBackupFile);

await renderInDrawer(<Menu />, store);

await user.click(screen.getByText("Save Backup"));

await user.type(screen.getByLabelText("Set Password"), password);
await user.type(screen.getByLabelText("Confirm Password"), password);
await user.click(screen.getByRole("button", { name: "Save Backup" }));

expect(mockDownloadBackupFile).toHaveBeenCalled();
});

it("calls toggleColorMode function when Light mode is clicked", async () => {
const user = userEvent.setup();
await renderInDrawer(<Menu />, store);

await user.click(screen.getByText("Light mode"));

expect(useColorMode().toggleColorMode).toHaveBeenCalled();
});

it("opens Add Account modal when Add Account button is clicked", async () => {
const { openWith } = dynamicModalContextMock;
const user = userEvent.setup();
await renderInDrawer(<Menu />, store);

await user.click(screen.getByText("Add Account"));

expect(openWith).toHaveBeenCalledWith(<OnboardOptionsModal />);
});
});
});
98 changes: 49 additions & 49 deletions apps/web/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,68 +18,68 @@ import {
UserPlusIcon,
} from "../../assets/icons";
import { OnboardOptionsModal } from "../Onboarding/OnboardOptions";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow";
import { useHasVerifiedAccounts } from "../Onboarding/VerificationFlow";

export const Menu = () => {
const { openWith: openModal } = useDynamicModalContext();
const { openWith: openDrawer } = useDynamicDrawerContext();
const { colorMode, toggleColorMode } = useColorMode();
const isVerified = useIsAccountVerified();
const hasVerified = useHasVerifiedAccounts();
const saveBackup = useSaveBackup();

const colorModeSwitchLabel = colorMode === "light" ? "Light mode" : "Dark mode";

const menuItemsForVerifiedUser = [
{
label: "Address Book",
icon: <BookIcon />,
onClick: () => openDrawer(<AddressBookMenu />),
hasArrow: true,
},
{
label: "Add Account",
icon: <UserPlusIcon />,
onClick: () => openModal(<OnboardOptionsModal />),
},
{
label: "Save Backup",
icon: <DownloadIcon />,
onClick: saveBackup,
},
const advanced = {
label: "Advanced",
icon: <SettingsIcon />,
onClick: () => openDrawer(<AdvancedMenu />),
hasArrow: true,
};
const addressBook = {
label: "Address Book",
icon: <BookIcon />,
onClick: () => openDrawer(<AddressBookMenu />),
hasArrow: true,
};
const addAccount = {
label: "Add Account",
icon: <UserPlusIcon />,
onClick: () => openModal(<OnboardOptionsModal />),
hasArrow: false,
};
const backup = {
label: "Save Backup",
icon: <DownloadIcon />,
onClick: saveBackup,
hasArrow: false,
};
const apps = {
label: "Apps",
icon: <CodeSandboxIcon />,
onClick: () => openDrawer(<AppsMenu />),
hasArrow: true,
};

const coreMenuItems = hasVerified
? [advanced, addressBook, addAccount, backup, apps]
: [advanced, addAccount];

const themeMenuItems = [
{
label: "Apps",
icon: <CodeSandboxIcon />,
onClick: () => openDrawer(<AppsMenu />),
hasArrow: true,
label: colorModeSwitchLabel,
icon: <MoonIcon />,
onClick: toggleColorMode,
rightElement: <Switch isChecked={colorMode === "dark"} onChange={toggleColorMode} />,
},
];

const menuItems = [
[
{
label: "Advanced",
icon: <SettingsIcon />,
onClick: () => openDrawer(<AdvancedMenu />),
hasArrow: true,
},
...(isVerified ? menuItemsForVerifiedUser : []),
],
[
{
label: colorModeSwitchLabel,
icon: <MoonIcon />,
onClick: toggleColorMode,
rightElement: <Switch isChecked={colorMode === "dark"} onChange={toggleColorMode} />,
},
],
[
{
label: "Logout",
icon: <LogoutIcon />,
onClick: () => openModal(<LogoutModal />),
},
],
const logoutMenuItems = [
{
label: "Logout",
icon: <LogoutIcon />,
onClick: () => openModal(<LogoutModal />),
},
];

return <GenericMenu menuItems={menuItems} />;
return <GenericMenu menuItems={[coreMenuItems, themeMenuItems, logoutMenuItems]} />;
};

1 comment on commit d42ab8d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Title Lines Statements Branches Functions
apps/desktop Coverage: 83%
83.74% (1788/2135) 79.43% (850/1070) 78.27% (454/580)
apps/web Coverage: 83%
83.74% (1788/2135) 79.43% (850/1070) 78.27% (454/580)
packages/components Coverage: 97%
97.51% (196/201) 95.91% (94/98) 88.13% (52/59)
packages/core Coverage: 81%
82.37% (215/261) 72.51% (95/131) 81.66% (49/60)
packages/crypto Coverage: 100%
100% (43/43) 90.9% (10/11) 100% (7/7)
packages/data-polling Coverage: 96%
94.66% (142/150) 87.5% (21/24) 92.85% (39/42)
packages/multisig Coverage: 98%
98.47% (129/131) 85.71% (18/21) 100% (36/36)
packages/social-auth Coverage: 95%
95.45% (21/22) 91.66% (11/12) 100% (3/3)
packages/state Coverage: 83%
83.21% (833/1001) 79.58% (191/240) 76.7% (303/395)
packages/tezos Coverage: 89%
88.72% (118/133) 94.59% (35/37) 86.84% (33/38)
packages/tzkt Coverage: 89%
87.32% (62/71) 87.5% (14/16) 80.48% (33/41)

Please sign in to comment.