Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#295 Disable send transaction button when network is wrong #296

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions apps/web/src/components/layout/shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import CartesiLogo from "../../components/cartesiLogo";
import Footer from "../../components/layout/footer";
import SendTransaction from "../../components/sendTransaction";
import { CartesiScanChains } from "../networks/cartesiScanNetworks";
import getConfiguredChainId from "../../lib/getConfiguredChain";

const Shell: FC<{ children: ReactNode }> = ({ children }) => {
const [opened, { toggle: toggleMobileMenu, close: closeMobileMenu }] =
Expand All @@ -52,7 +53,9 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
const hideBalanceViewport = useMediaQuery(
`(min-width:${theme.breakpoints.sm}) and (max-width:${50}em)`,
);
const { isConnected } = useAccount();
const { isConnected, chainId } = useAccount();
const configuredChainId = getConfiguredChainId();
const isValidNetwork = chainId === Number(configuredChainId);
const { colorScheme, toggleColorScheme } = useMantineColorScheme({
keepTransitions: true,
});
Expand Down Expand Up @@ -96,7 +99,7 @@ const Shell: FC<{ children: ReactNode }> = ({ children }) => {
variant="subtle"
leftSection={<TbArrowsDownUp />}
onClick={openTransaction}
disabled={!isConnected}
disabled={!isConnected || !isValidNetwork}
visibleFrom="sm"
data-testid="transaction-button"
>
Expand Down
155 changes: 51 additions & 104 deletions apps/web/test/components/layout/shell.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,117 +8,34 @@ import {
within,
} from "@testing-library/react";
import { mainnet } from "viem/chains";
import { afterAll, describe, it } from "vitest";
import { afterAll, beforeEach, describe, it } from "vitest";
import Shell from "../../../src/components/layout/shell";
import withMantineTheme from "../../utils/WithMantineTheme";
import { useAccount, useConfig } from "wagmi";
import getConfiguredChainId from "../../../src/lib/getConfiguredChain";

const Component = withMantineTheme(Shell);

vi.mock("../../../src/graphql", async () => {
return {
useApplicationsQuery: () => [{ data: {}, fetching: false }],
useTokensQuery: () => [{ data: {}, fetching: false }],
};
});

vi.mock("@cartesi/rollups-wagmi", async () => {
return {
usePrepareInputBoxAddInput: () => ({
config: {},
}),
useInputBoxAddInput: () => ({
data: {},
wait: vi.fn(),
}),
};
});

vi.mock("viem", async () => {
const actual = await vi.importActual("viem");
return {
...(actual as any),
getAddress: (address: string) => address,
};
});
vi.mock("../../../src/lib/getConfiguredChain");
const getConfiguredChainIdMock = vi.mocked(getConfiguredChainId, true);

vi.mock("@rainbow-me/rainbowkit", async () => {
return {
ConnectButton: () => <></>,
};
});
vi.mock("wagmi");
const useConfigMock = vi.mocked(useConfig, { partial: true });
const useAccountMock = vi.mocked(useAccount, { partial: true });

vi.mock("@cartesi/rollups-wagmi", async () => {
const actual = await vi.importActual("@cartesi/rollups-wagmi");
return {
...(actual as any),
usePrepareErc20Approve: () => ({
config: {},
}),
useErc20Approve: () => ({
data: {},
wait: vi.fn(),
}),
usePrepareErc20PortalDepositErc20Tokens: () => ({
config: {},
}),
useErc20PortalDepositErc20Tokens: () => ({
data: {},
wait: vi.fn(),
}),
usePrepareEtherPortalDepositEther: () => ({
config: {},
}),
useEtherPortalDepositEther: () => ({
data: {},
wait: vi.fn(),
}),
};
});
const Component = withMantineTheme(Shell);

vi.mock("wagmi", async () => {
return {
useConfig: () => ({
describe("Shell component", () => {
beforeEach(() => {
useConfigMock.mockReturnValue({
chains: [mainnet],
}),
useContractReads: () => ({
isLoading: false,
isSuccess: true,
data: [
{
result: undefined,
error: undefined,
},
{
result: undefined,
error: undefined,
},
{
result: undefined,
error: undefined,
},
{
result: undefined,
error: undefined,
},
],
}),
useAccount: () => ({
});

useAccountMock.mockReturnValue({
address: "0x8FD78976f8955D13bAA4fC99043208F4EC020D7E",
}),
usePrepareContractWrite: () => ({}),
useWaitForTransaction: () => ({}),
useContractWrite: () => ({}),
useNetwork: () => ({
chain: {
nativeCurrency: {
decimals: 18,
},
},
}),
};
});
});

getConfiguredChainIdMock.mockReturnValue("31337");
});

describe("Shell component", () => {
afterAll(() => {
vi.restoreAllMocks();
});
Expand All @@ -134,7 +51,7 @@ describe("Shell component", () => {
});

describe("Header", () => {
it("should display transaction link in header", () => {
it("should display 'Send Transaction' button in header", () => {
render(<Component>Children</Component>);

expect(
Expand All @@ -144,6 +61,36 @@ describe("Shell component", () => {
).toBeInTheDocument();
});

it("should enable 'Send Transaction' button when network is correct", () => {
useAccountMock.mockReturnValue({
address: "0x8FD78976f8955D13bAA4fC99043208F4EC020D7E",
isConnected: true,
chainId: 31337,
});
getConfiguredChainIdMock.mockReturnValue("31337");
render(<Component>Children</Component>);

const button = within(screen.getByTestId("header")).getByTestId(
"transaction-button",
);
expect(button.hasAttribute("disabled")).toBe(false);
});

it("should display disable 'Send Transaction' button when network is wrong", () => {
useAccountMock.mockReturnValue({
address: "0x8FD78976f8955D13bAA4fC99043208F4EC020D7E",
isConnected: true,
chainId: 31337,
});
getConfiguredChainIdMock.mockReturnValue("");
render(<Component>Children</Component>);

const button = within(screen.getByTestId("header")).getByTestId(
"transaction-button",
);
expect(button.hasAttribute("disabled")).toBe(true);
});

it("should not display home and applications links in header", () => {
render(<Component>Children</Component>);

Expand All @@ -158,7 +105,7 @@ describe("Shell component", () => {
).toThrow("Unable to find an element");
});

it("should display the cartesiscan chain button", async () => {
it("should display the cartesiscan chain button", () => {
render(<Component>Children</Component>);

const headerEl = screen.getByTestId("header");
Expand Down
Loading