Skip to content

Commit

Permalink
Add tests for Batch components
Browse files Browse the repository at this point in the history
  • Loading branch information
serjonya-trili committed Sep 5, 2023
1 parent 44c23a7 commit d71e509
Show file tree
Hide file tree
Showing 10 changed files with 458 additions and 299 deletions.
2 changes: 2 additions & 0 deletions src/mocks/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ export const mockNftOperation = (index: number): FA2Transfer => ({
tokenId: String(index),
});

export const mockFA2Operation = mockNftOperation;

export const mockDelegationOperation = (index: number): Delegation => {
return {
type: "delegation",
Expand Down
2 changes: 1 addition & 1 deletion src/mocks/nftTokens.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RawTokenBalance } from "../types/TokenBalance";

export const ghotnetThezard: RawTokenBalance = {
export const ghostnetThezard: RawTokenBalance = {
id: 139206711050241,
account: {
address: "KT1MYis2J1hpjxVcfF92Mf7AfXouzaxsYfKm",
Expand Down
2 changes: 1 addition & 1 deletion src/types/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const tokenNameSafe = (token: Token): string => {

export const tokenName = (token: Token): string | undefined => token.metadata?.name;

const defaultTokenSymbol = (token: Token): string => {
export const defaultTokenSymbol = (token: Token): string => {
switch (token.type) {
case "fa1.2":
return DEFAULT_FA1_SYMBOL;
Expand Down
219 changes: 75 additions & 144 deletions src/views/batch/BatchPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { TezosToolkit } from "@taquito/taquito";
import { makeAccountOperations } from "../../components/sendForm/types";
import { mockImplicitAccount, mockImplicitAddress } from "../../mocks/factories";
import { mockImplicitAccount, mockTezOperation } from "../../mocks/factories";
import { dispatchMockAccounts, mockEstimatedFee } from "../../mocks/helpers";
import { act, fireEvent, render, screen, waitFor, within } from "../../mocks/testUtils";
import { TezosNetwork } from "../../types/TezosNetwork";
import { useGetSecretKey } from "../../utils/hooks/accountUtils";
import store from "../../utils/redux/store";
import { estimateAndUpdateBatch } from "../../utils/redux/thunks/estimateAndUpdateBatch";
import { executeOperations, makeToolkit } from "../../utils/tezos";
import { executeOperations } from "../../utils/tezos";
import BatchPage from "./BatchPage";

// These tests might take long in the CI
jest.setTimeout(10000);
import { assetsActions } from "../../utils/redux/slices/assetsSlice";

jest.mock("../../utils/hooks/accountUtils");
jest.mock("../../utils/tezos");
Expand All @@ -27,166 +22,102 @@ beforeEach(() => {
});

describe("<BatchPage />", () => {
describe("Given no batch has beed added", () => {
it("a message 'no batches are present' is displayed", () => {
it("shows empty batch message by default", () => {
render(<BatchPage />);

expect(screen.getByText(/your batch is currently empty/i)).toBeInTheDocument();
});

describe("pending", () => {
it("shows 0 when no batches exist", () => {
render(<BatchPage />);

expect(screen.getByText(/0 pending/i)).toBeInTheDocument();
expect(screen.getByText(/your batch is currently empty/i)).toBeInTheDocument();
});
});

describe("Given batches have been added", () => {
const MOCK_TEZOS_TOOLKIT = {};
beforeEach(async () => {
await store.dispatch(
estimateAndUpdateBatch(
it("shows the number of different pending batches", () => {
store.dispatch(
assetsActions.addToBatch(
makeAccountOperations(mockImplicitAccount(1), mockImplicitAccount(1), [
{
type: "tez",
recipient: mockImplicitAddress(1),
amount: "1000000",
},
{
type: "tez",
recipient: mockImplicitAddress(2),
amount: "2000000",
},
{
type: "tez",
recipient: mockImplicitAddress(3),
amount: "3000000",
},
]),
TezosNetwork.MAINNET
mockTezOperation(0),
mockTezOperation(0),
])
)
);
render(<BatchPage />);

expect(screen.getByText(/1 pending/i)).toBeInTheDocument();
act(() => {
store.dispatch(
assetsActions.addToBatch(
makeAccountOperations(mockImplicitAccount(2), mockImplicitAccount(2), [
mockTezOperation(0),
mockTezOperation(0),
])
)
);
});
expect(screen.getByText(/2 pending/i)).toBeInTheDocument();
});
});

it("renders all the batches", () => {
store.dispatch(
assetsActions.addToBatch(
makeAccountOperations(mockImplicitAccount(1), mockImplicitAccount(1), [
mockTezOperation(0),
mockTezOperation(0),
])
)
);
store.dispatch(
assetsActions.addToBatch(
makeAccountOperations(mockImplicitAccount(2), mockImplicitAccount(2), [
mockTezOperation(0),
mockTezOperation(0),
])
)
);

render(<BatchPage />);

expect(screen.getAllByTestId(/batch-table/i)).toHaveLength(2);
});

describe("action buttons", () => {
beforeEach(() => {
store.dispatch(
estimateAndUpdateBatch(
assetsActions.addToBatch(
makeAccountOperations(mockImplicitAccount(2), mockImplicitAccount(2), [
{
type: "tez",
recipient: mockImplicitAddress(9),
amount: "4",
},
{
type: "tez",
recipient: mockImplicitAddress(4),
amount: "5",
},
{
type: "tez",
recipient: mockImplicitAddress(5),
amount: "6",
},
]),
TezosNetwork.MAINNET
mockTezOperation(0),
mockTezOperation(0),
])
)
);
jest.mocked(makeToolkit).mockResolvedValue(MOCK_TEZOS_TOOLKIT as TezosToolkit);
});

test("a batch can be deleted by clicking the delete button and confirming", () => {
test("delete batch", () => {
render(<BatchPage />);
const firstBatch = screen.getAllByTestId(/batch-table/i)[0];
const { getByLabelText } = within(firstBatch);
const deleteBtn = getByLabelText(/Delete Batch/i);
fireEvent.click(deleteBtn);
expect(screen.getByText(/Are you sure/i)).toBeTruthy();
const confirmBtn = screen.getByRole("button", { name: /confirm/i });
fireEvent.click(confirmBtn);
expect(screen.getAllByTestId(/batch-table/i)).toHaveLength(1);
});

const clickSubmitOnFirstBatch = () => {
const batchTable = screen.getAllByTestId(/batch-table/i)[0];

const { getByRole } = within(batchTable);
const submitBatchBtn = getByRole("button", { name: /submit batch/i });
fireEvent.click(submitBatchBtn);
};
const deleteButton = screen.getByTestId("remove-batch");
fireEvent.click(deleteButton);
expect(screen.getByText(/Are you sure/i)).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Clear" }));
expect(screen.queryByTestId(/batch-table/i)).not.toBeInTheDocument();
});

test("clicking submit batch button displays 'preview' form", () => {
// TODO: write a complete test after migration to dynamic modal
test("submit batch", async () => {
render(<BatchPage />);
act(() => {
clickSubmitOnFirstBatch();
});
const submitBatchButton = screen.getByRole("button", { name: /confirm batch/i });
fireEvent.click(submitBatchButton);
const modal = screen.getByRole("dialog");
const { getByText, getByLabelText } = within(modal);
expect(getByText(/transaction details/i)).toBeInTheDocument();

const txsAmount = getByLabelText(/transactions-amount/i);
expect(txsAmount).toHaveTextContent("3");

expect(screen.getByRole("button", { name: /preview/i })).toBeInTheDocument();
});

test("estimating and submiting a batch executes the batch of transactions and empties it after successful submition", async () => {
mockEstimatedFee(10);
render(<BatchPage />);
act(() => {
clickSubmitOnFirstBatch();
});

expect(
screen.getByTestId("batch-table-" + mockImplicitAccount(2).address.pkh)
).toBeInTheDocument();
expect(
screen.getByTestId("batch-table-" + mockImplicitAccount(1).address.pkh)
).toBeInTheDocument();

const previewBtn = screen.getByRole("button", { name: /preview/i });
fireEvent.click(previewBtn);

const passwordInput = await screen.findByLabelText(/password/i);
fireEvent.change(passwordInput, { target: { value: "mockPass" } });

const submit = screen.getByRole("button", {
name: /submit transaction/i,
});
fireEvent.click(within(modal).getByRole("button", { name: "Preview" }));

await waitFor(() => {
expect(submit).toBeEnabled();
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
});
fireEvent.click(submit);

await waitFor(() => {
expect(screen.getByText(/Operation Submitted/i)).toBeInTheDocument();
});

expect(screen.getByTestId(/tzkt-link/i)).toHaveProperty(
"href",
"https://mainnet.tzkt.io/foo"
);

expect(jest.mocked(executeOperations)).toHaveBeenCalledWith(
makeAccountOperations(mockImplicitAccount(1), mockImplicitAccount(1), [
{
amount: "1000000",
recipient: { pkh: "tz1UZFB9kGauB6F5c2gfJo4hVcvrD8MeJ3Vf", type: "implicit" },
type: "tez",
},
{
amount: "2000000",
recipient: { pkh: "tz1ikfEcj3LmsmxpcC1RMZNzBHbEmybCc43D", type: "implicit" },
type: "tez",
},
{
amount: "3000000",
recipient: { pkh: "tz1g7Vk9dxDALJUp4w1UTnC41ssvRa7Q4XyS", type: "implicit" },
type: "tez",
},
]),
MOCK_TEZOS_TOOLKIT
);

expect(
screen.getByTestId("batch-table-" + mockImplicitAccount(2).address.pkh)
).toBeInTheDocument();
expect(
screen.queryByTestId("batch-table-" + mockImplicitAccount(1).address.pkh)
).not.toBeInTheDocument();
});
});
});
51 changes: 48 additions & 3 deletions src/views/batch/BatchView.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,56 @@
import { makeAccountOperations } from "../../components/sendForm/types";
import { mockImplicitAccount, mockTezOperation } from "../../mocks/factories";
import { render, screen, within } from "../../mocks/testUtils";
import { ghostFA2, ghostTezzard } from "../../mocks/tokens";
import { tokenTitle } from "./BatchView";
import { Operation } from "../../types/Operation";
import { BatchView, tokenTitle } from "./BatchView";

describe("<BatchView />", () => {});
describe("<BatchView />", () => {
test("header", () => {
const operations = makeAccountOperations(mockImplicitAccount(0), mockImplicitAccount(0), [
mockTezOperation(0),
]);
render(<BatchView operations={operations} />);
const header = screen.getByTestId("header");
expect(header).toBeInTheDocument();
expect(within(header).getByTestId("right-header")).toBeInTheDocument();
});

test("body", () => {
const operations = makeAccountOperations(mockImplicitAccount(0), mockImplicitAccount(0), [
mockTezOperation(0),
mockTezOperation(0),
mockTezOperation(0),
]);
render(<BatchView operations={operations} />);
expect(screen.getAllByTestId("operation").length).toEqual(3);
});

describe("footer", () => {
it("is hidden until there are > 9 operations", () => {
const operations = makeAccountOperations(mockImplicitAccount(0), mockImplicitAccount(0), [
mockTezOperation(0),
]);
render(<BatchView operations={operations} />);
expect(screen.queryByTestId("footer")).not.toBeInTheDocument();
});

it("shows up when there are too many operations", () => {
const ops: Operation[] = [];
for (let i = 0; i < 10; i++) {
ops.push(mockTezOperation(i));
}
const operations = makeAccountOperations(mockImplicitAccount(0), mockImplicitAccount(0), ops);
render(<BatchView operations={operations} />);
const footer = screen.getByTestId("footer");
expect(within(footer).getByTestId("right-header")).toBeInTheDocument();
});
});
});

describe("tokenTitle", () => {
it("returns raw amount if token is missing", () => {
expect(tokenTitle(undefined, "1000000")).toBe("1000000");
expect(tokenTitle(undefined, "1000000")).toBe("1000000 Unknown Token");
});

it("doesn't return symbol if token name is absent", () => {
Expand Down
Loading

0 comments on commit d71e509

Please sign in to comment.