Skip to content

Commit

Permalink
feat(namadillo): writing tests for StakingRewards
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrorezende committed Sep 13, 2024
1 parent 9edfc7d commit 2faf613
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 4 deletions.
10 changes: 7 additions & 3 deletions apps/namadillo/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ module.exports = {
modulePathIgnorePatterns: ["e2e-tests"],
moduleDirectories: ["src", "node_modules"],
verbose: true,
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>/src/",
}),
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>/src/",
}),
"^.+\\.svg$": "jest-transformer-svg",
"\\.css": "identity-obj-proxy",
},
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
};
3 changes: 3 additions & 0 deletions apps/namadillo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"test:watch": "yarn wasm:build:test && yarn jest --watchAll=true",
"test:coverage": "yarn wasm:build:test && yarn test --coverage",
"test:ci": "jest",
"test:watch:only": "yarn test --watchAll=true",
"e2e-test": "PLAYWRIGHT_BASE_URL=http://localhost:3000 yarn playwright test",
"e2e-test:headed": "PLAYWRIGHT_BASE_URL=http://localhost:3000 yarn playwright test --project=chromium --headed",
"wasm:build": "node ./scripts/build.js --release",
Expand Down Expand Up @@ -106,10 +107,12 @@
"eslint-plugin-react-hooks": "^4.6.0",
"globals": "^15.9.0",
"history": "^5.3.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-create-mock-instance": "^2.0.0",
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"jest-transformer-svg": "^2.0.2",
"local-cors-proxy": "^1.1.0",
"postcss": "^8.4.32",
"release-it": "^17.0.1",
Expand Down
1 change: 1 addition & 0 deletions apps/namadillo/src/App/Staking/StakingRewards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const StakingRewards = (): JSX.Element => {
});

const availableRewards = useMemo(() => {
if (!rewards || Object.keys(rewards).length === 0) return BigNumber(0);
return BigNumber.sum(...Object.values(rewards || []));
}, [rewards]);

Expand Down
163 changes: 163 additions & 0 deletions apps/namadillo/src/App/Staking/__tests__/StakingRewards.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import BigNumber from "bignumber.js";
import { mockJotai } from "test-utils";
mockJotai();

import { fireEvent, render, screen } from "@testing-library/react";
import { StakingRewards } from "App/Staking/StakingRewards";
import { defaultAccountAtom } from "atoms/accounts";
import { claimableRewardsAtom } from "atoms/staking";
import { useTransaction } from "hooks/useTransaction";
import { useAtomValue } from "jotai";
import { AddressBalance } from "types";

jest.mock("hooks/useTransaction", () => ({
useTransaction: jest.fn(),
}));

jest.mock("hooks/useModalCloseEvent", () => ({
useModalCloseEvent: () => ({ onCloseModal: jest.fn() }),
}));

jest.mock("atoms/staking", () => ({
claimableRewardsAtom: jest.fn(),
claimAndStakeRewardsAtom: jest.fn(),
claimRewardsAtom: jest.fn(),
}));

const mockAtomValue = (
data: AddressBalance = {},
isLoading: boolean = true,
isSuccess: boolean = false
): void => {
(useAtomValue as jest.Mock).mockImplementation((atom) => {
if (atom === defaultAccountAtom) {
return { data: { address: "tnam1_test_account" } };
}

if (atom === claimableRewardsAtom) {
return { data, isLoading, isSuccess };
}

return null;
});
};

const mockTransaction = (
execute: jest.Mock = jest.fn(),
isEnabled: boolean = false,
isPending: boolean = false
): void => {
(useTransaction as jest.Mock).mockImplementation(() => {
return {
execute,
isEnabled,
isPending,
};
});
};

describe("Component: StakingRewards", () => {
afterEach(() => {
jest.clearAllMocks();
});

const setup = (): void => {
render(<StakingRewards />);
};

const getButtons = (): HTMLElement[] => {
return screen.getAllByRole("button");
};

it("should render modal correctly", () => {
mockAtomValue();
mockTransaction();
setup();
expect(screen.getByText("Claimable Staking Rewards")).toBeInTheDocument();
expect(getButtons()).toHaveLength(2);
});

it("should render loading skeleton when rewards are loading", () => {
mockAtomValue({}, true);
mockTransaction();
render(<StakingRewards />);
expect(screen.getByRole("progressbar")).toBeInTheDocument();

const buttons = getButtons();
buttons.forEach((button) => expect(button).toBeDisabled());
});

it("should display available rewards when loaded", () => {
mockAtomValue(
{
validator1: new BigNumber(100),
validator2: new BigNumber(200),
},
false,
true
);
mockTransaction();
render(<StakingRewards />);
expect(screen.getByText("300")).toBeInTheDocument();
});

it("should enable buttons if claim rewards are available", () => {
mockAtomValue(
{
validator1: new BigNumber(100),
},
false,
true
);
mockTransaction(jest.fn(), true, false);
render(<StakingRewards />);
const buttons = getButtons();
buttons.forEach((button) => expect(button).toBeEnabled());
});

it("should disable buttons if claim rewards are not enabled", () => {
mockAtomValue(
{
validator1: new BigNumber(100),
},
false,
true
);
mockTransaction(jest.fn(), false, false);
render(<StakingRewards />);
const buttons = getButtons();
buttons.forEach((button) => expect(button).not.toBeEnabled());
});

it("should disable buttons while transaction is pending", () => {
mockAtomValue(
{
validator1: new BigNumber(100),
},
false,
true
);
mockTransaction(jest.fn(), true, true);
render(<StakingRewards />);
const buttons = getButtons();
buttons.forEach((button) => expect(button).not.toBeEnabled());
});

it("should call 'claimRewardsAndStake' when 'Claim & Stake' is clicked", async () => {
const executeMock = jest.fn();
mockTransaction(executeMock, true, false);
mockAtomValue(
{
validator1: new BigNumber(100),
},
false,
true
);
render(<StakingRewards />);
const buttons = getButtons();
fireEvent.click(buttons[0]);
expect(executeMock).toHaveBeenCalledTimes(1);
fireEvent.click(buttons[1]);
expect(executeMock).toHaveBeenCalledTimes(2);
});
});
2 changes: 1 addition & 1 deletion apps/namadillo/src/hooks/useTransaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type AtomType<T> = Atom<

type PartialNotification = Pick<ToastNotification, "title" | "description">;

type useTransactionProps<T> = {
export type useTransactionProps<T> = {
params: T[];
createTxAtom: AtomType<T>;
eventType: TransactionEventsClasses;
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/SkeletonLoading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const SkeletonLoading = ({
const { className, ...rest } = props;
return (
<span
role="progressbar"
className={twMerge(
"bg-neutral-800 animate-pulse block rounded-[2px]",
className
Expand Down
28 changes: 28 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3673,12 +3673,14 @@ __metadata:
globals: "npm:^15.9.0"
history: "npm:^5.3.0"
idb-keyval: "npm:^6.2.1"
identity-obj-proxy: "npm:^3.0.0"
invariant: "npm:^2.2.4"
io-ts: "npm:^2.2.21"
jest: "npm:^29.7.0"
jest-create-mock-instance: "npm:^2.0.0"
jest-environment-jsdom: "npm:^29.7.0"
jest-fetch-mock: "npm:^3.0.3"
jest-transformer-svg: "npm:^2.0.2"
jotai: "npm:^2.6.3"
jotai-tanstack-query: "npm:^0.8.5"
local-cors-proxy: "npm:^1.1.0"
Expand Down Expand Up @@ -11882,6 +11884,13 @@ __metadata:
languageName: node
linkType: hard

"harmony-reflect@npm:^1.4.6":
version: 1.6.2
resolution: "harmony-reflect@npm:1.6.2"
checksum: fa5b251fbeff0e2d925f0bfb5ffe39e0627639e998c453562d6a39e41789c15499649dc022178c807cf99bfb97e7b974bbbc031ba82078a26be7b098b9bc2b1a
languageName: node
linkType: hard

"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2":
version: 1.0.2
resolution: "has-bigints@npm:1.0.2"
Expand Down Expand Up @@ -12398,6 +12407,15 @@ __metadata:
languageName: node
linkType: hard

"identity-obj-proxy@npm:^3.0.0":
version: 3.0.0
resolution: "identity-obj-proxy@npm:3.0.0"
dependencies:
harmony-reflect: "npm:^1.4.6"
checksum: a3fc4de0042d7b45bf8652d5596c80b42139d8625c9cd6a8834e29e1b6dce8fccabd1228e08744b78677a19ceed7201a32fed8ca3dc3e4852e8fee24360a6cfc
languageName: node
linkType: hard

"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4, ieee754@npm:^1.2.1":
version: 1.2.1
resolution: "ieee754@npm:1.2.1"
Expand Down Expand Up @@ -13913,6 +13931,16 @@ __metadata:
languageName: node
linkType: hard

"jest-transformer-svg@npm:^2.0.2":
version: 2.0.2
resolution: "jest-transformer-svg@npm:2.0.2"
peerDependencies:
jest: ">= 28.1.0"
react: ^17.0.0 || ^18.0.0
checksum: f71a46b2fb35dc25df714005b2d36f82287ab518647eddbce9c9baa923478da2a25f3fd358703db01c52630f2733a375219d3d0896965856b3940788a2f2f68e
languageName: node
linkType: hard

"jest-util@npm:^29.0.0, jest-util@npm:^29.7.0":
version: 29.7.0
resolution: "jest-util@npm:29.7.0"
Expand Down

0 comments on commit 2faf613

Please sign in to comment.