Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan committed Sep 10, 2024
1 parent 743c928 commit 49e2501
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ import { useDynamicModalContext } from "@umami/components";
import { type ImplicitAccount, type MnemonicAccount, getAccountGroupLabel } from "@umami/core";
import { accountsActions, useGetAccountBalance, useImplicitAccounts } from "@umami/state";
import { prettyTezAmount } from "@umami/tezos";
import { capitalize } from "lodash";
import { capitalize, groupBy } from "lodash";
import { useDispatch } from "react-redux";

import { AccountSelectorPopover } from "./AccountSelectorPopover";
import { PlusIcon, TrashIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { AccountTile } from "../AccountTile";
import { ModalCloseButton } from "../CloseButton";
import { DeriveMnemonicAccountModal } from "../DeriveMnemonicAccountModal";
import { DeriveMnemonicAccountModal } from "./DeriveMnemonicAccountModal";
import { OnboardOptionsModal } from "../Onboarding/OnboardOptions";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow";

Expand All @@ -37,7 +37,7 @@ export const AccountSelectorModal = () => {

const dispatch = useDispatch();

const groupedAccounts = Object.groupBy(accounts, getAccountGroupLabel);
const groupedAccounts = groupBy(accounts, getAccountGroupLabel);

const handleDeriveAccount = (account?: ImplicitAccount) => {
if (!account) {
Expand All @@ -48,7 +48,7 @@ export const AccountSelectorModal = () => {
case "mnemonic":
return openWith(<DeriveMnemonicAccountModal account={account as MnemonicAccount} />);
default:
break;
return openWith(<OnboardOptionsModal />);
}
};

Expand Down Expand Up @@ -86,15 +86,15 @@ export const AccountSelectorModal = () => {
/>
<IconButton
color={color("500")}
aria-label={`Remove ${type} accounts`}
aria-label={`Add ${type} account`}
icon={<PlusIcon />}
onClick={() => handleDeriveAccount(accounts?.[0])}
onClick={() => handleDeriveAccount(accounts[0])}
size="sm"
variant="ghost"
/>
</Flex>
</Center>
{accounts?.map(account => {
{accounts.map(account => {
const address = account.address.pkh;
const balance = getBalance(address);
const onClick = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { mockMnemonicAccount } from "@umami/core";
import { type UmamiStore, addTestAccount, makeStore, useDeriveMnemonicAccount } from "@umami/state";

import { DeriveMnemonicAccountModal } from "./DeriveMnemonicAccountModal";
import { act, renderInModal, screen, userEvent, waitFor } from "../../../testUtils";

let store: UmamiStore;

jest.mock("@umami/state", () => ({
...jest.requireActual("@umami/state"),
useDeriveMnemonicAccount: jest.fn(),
}));

const mockDeriveMnemonicAccount = jest.fn();

beforeEach(() => {
store = makeStore();
addTestAccount(store, mockMnemonicAccount(0));

jest.mocked(useDeriveMnemonicAccount).mockImplementation(() => mockDeriveMnemonicAccount);
});

describe("<DeriveMnemonicAccountModal />", () => {
it("renders the NameAccountModal with correct subtitle", async () => {
const account = mockMnemonicAccount(0);
await renderInModal(<DeriveMnemonicAccountModal account={account} />, store);

await waitFor(() => {
expect(screen.getByText("Name Your Account")).toBeVisible();
});

expect(
screen.getByText(`Name the new account derived from seedphrase ${account.seedFingerPrint}`)
).toBeVisible();
});

it("handles name submission and opens confirm password modal", async () => {
const user = userEvent.setup();

const account = mockMnemonicAccount(0);
await renderInModal(<DeriveMnemonicAccountModal account={account} />, store);
await act(() => user.type(screen.getByLabelText("Account name"), "Test Account"));
await act(() => user.click(screen.getByRole("button", { name: "Continue" })));

await waitFor(() => {
expect(screen.getByTestId("master-password-modal")).toBeVisible();
});
});

it("derives mnemonic account on password submission", async () => {
const user = userEvent.setup();

const account = mockMnemonicAccount(0);
await renderInModal(<DeriveMnemonicAccountModal account={account} />, store);

await act(() => user.type(screen.getByLabelText("Account name"), "Test Account"));
await act(() => user.click(screen.getByRole("button", { name: "Continue" })));
await act(() => user.type(screen.getByLabelText("Password"), "test-password"));
await act(() => user.click(screen.getByRole("button", { name: "Submit" })));

expect(mockDeriveMnemonicAccount).toHaveBeenCalledWith({
fingerPrint: account.seedFingerPrint,
password: "test-password",
label: "Test Account",
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { useDynamicModalContext } from "@umami/components";
import { DEFAULT_ACCOUNT_LABEL, type MnemonicAccount } from "@umami/core";
import { useAsyncActionHandler, useDeriveMnemonicAccount } from "@umami/state";

import { MasterPasswordModal } from "../MasterPasswordModal";
import { NameAccountModal } from "../NameAccountModal";
import { MasterPasswordModal } from "../../MasterPasswordModal";
import { NameAccountModal } from "../../NameAccountModal";

type DeriveMnemonicAccountModalProps = {
account: MnemonicAccount;
Expand All @@ -14,8 +14,8 @@ export const DeriveMnemonicAccountModal = ({ account }: DeriveMnemonicAccountMod
const { goToIndex, openWith } = useDynamicModalContext();

const { handleAsyncAction } = useAsyncActionHandler();
const toast = useToast();
const deriveMnemonicAccount = useDeriveMnemonicAccount();
const toast = useToast();

const handleNameSubmit = ({ accountName }: { accountName: string }) => {
const handlePasswordSubmit = ({ password }: { password: string }) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MasterPasswordModal } from "./MasterPasswordModal";
import { renderInModal, screen, userEvent } from "../../testUtils";

const mockOnSubmit = jest.fn();

describe("<MasterPasswordModal />", () => {
it("calls onSubmit with entered password when form is submitted", async () => {
const user = userEvent.setup();
await renderInModal(<MasterPasswordModal onSubmit={mockOnSubmit} />);

await user.type(screen.getByLabelText("Password"), "testpassword");
await user.click(screen.getByRole("button", { name: "Submit" }));

expect(mockOnSubmit).toHaveBeenCalledWith({ password: "testpassword" });
});

it("shows validation error when submitting without a password", async () => {
const user = userEvent.setup();
await renderInModal(<MasterPasswordModal onSubmit={mockOnSubmit} />);

await user.click(screen.getByRole("button", { name: "Submit" }));

expect(screen.getByText("Password is required")).toBeInTheDocument();
expect(mockOnSubmit).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const MasterPasswordModal = ({ onSubmit }: MasterPasswordModalProps) => {
});

return (
<ModalContent>
<ModalContent data-testid="master-password-modal">
<ModalHeader>
<ModalBackButton />
<ModalCloseButton />
Expand Down
28 changes: 28 additions & 0 deletions apps/web/src/components/NameAccountModal/NameAccountModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { NameAccountModal } from "./NameAccountModal";
import { act, renderInModal, screen, userEvent, waitFor } from "../../testUtils";

const mockOnSubmit = jest.fn();

describe("NameAccountModal", () => {
it("renders with custom title and subtitle", async () => {
await renderInModal(
<NameAccountModal onSubmit={mockOnSubmit} subtitle="Custom Subtitle" title="Custom Title" />
);

await waitFor(() => {
expect(screen.getByText("Custom Title")).toBeVisible();
});
expect(screen.getByText("Custom Subtitle")).toBeVisible();
});

it("calls onSubmit with form data when submitted", async () => {
const user = userEvent.setup();

await renderInModal(<NameAccountModal onSubmit={mockOnSubmit} />);

await act(() => user.type(screen.getByLabelText("Account name"), "Test Account"));
await act(() => user.click(screen.getByRole("button", { name: "Continue" })));

expect(mockOnSubmit).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const NameAccountModal = ({
const { register, handleSubmit } = form;

return (
<ModalContent>
<ModalContent data-testid="name-account-modal">
<ModalHeader>
<ModalBackButton />
<ModalCloseButton />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ describe("<SetupPassword />", () => {

describe("mnemonic mode", () => {
let store: UmamiStore;
const allFormValues = { mnemonic: mnemonic1.split(" ").map(word => ({ val: word })) };
const allFormValues = {
current: { mnemonic: mnemonic1.split(" ").map(word => ({ val: word })) },
};
const mockRestoreFromMnemonic = jest.fn();

beforeEach(() => {
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/testUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ export const renderInModal = async (

if (allFormValues) {
await act(() =>
result.current.openWith(<DummyForm defaultValues={allFormValues} nextPage={component} />)
result.current.openWith(
<DummyForm defaultValues={allFormValues.current ?? allFormValues} nextPage={component} />
)
);
fireEvent.click(screen.getByRole("button"));
}
Expand Down

1 comment on commit 49e2501

@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.79% (1758/2098) 78.94% (825/1045) 78.45% (448/571)
apps/web Coverage: 83%
83.79% (1758/2098) 78.94% (825/1045) 78.45% (448/571)
packages/components Coverage: 97%
97.1% (134/138) 96.49% (55/57) 82.92% (34/41)
packages/core Coverage: 82%
82.89% (223/269) 73.18% (101/138) 81.35% (48/59)
packages/crypto Coverage: 100%
100% (28/28) 100% (3/3) 100% (5/5)
packages/data-polling Coverage: 98%
96.55% (140/145) 95.45% (21/22) 92.85% (39/42)
packages/multisig Coverage: 98%
98.4% (123/125) 89.47% (17/19) 100% (33/33)
packages/social-auth Coverage: 100%
100% (21/21) 100% (11/11) 100% (3/3)
packages/state Coverage: 84%
83.64% (772/923) 80.78% (164/203) 78.22% (291/372)
packages/tezos Coverage: 86%
85.57% (89/104) 89.47% (17/19) 82.75% (24/29)
packages/tzkt Coverage: 86%
84.05% (58/69) 81.25% (13/16) 76.92% (30/39)

Please sign in to comment.