Skip to content

Commit

Permalink
fix review
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan committed Nov 8, 2024
1 parent d4645ac commit a0b2a12
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 225 deletions.
308 changes: 84 additions & 224 deletions apps/web/src/components/AddContactModal/AddContactModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,231 +21,91 @@ beforeEach(() => {
});

describe("<AddContactModal />", () => {
describe("on adding contact", () => {
const contractPkh = mockContractAddress(0).pkh;

describe.each([
{ testCase: "new contact", modalComponent: <AddContactModal /> },
{
testCase: "pre-set contact",
modalComponent: <AddContactModal pkh={mockImplicitAddress(0).pkh} />,
},
])("for $testCase", ({ modalComponent }) => {
it("shows correct title & button label for new contact", async () => {
await renderInModal(modalComponent, store);

expect(screen.getByRole("dialog")).toHaveTextContent("Add Contact");
expect(screen.getByTestId("confirmation-button")).toHaveTextContent("Add to Address Book");
});

it("has editable address & name fields", async () => {
await renderInModal(modalComponent, store);

expect(screen.getByLabelText("Address")).toBeEnabled();
expect(screen.getByLabelText("Name")).toBeEnabled();
});

it("validates updated address", async () => {
const user = userEvent.setup();
await renderInModal(modalComponent, store);

const addressInput = screen.getByLabelText("Address");
await act(() => user.clear(addressInput));
await act(() => user.type(addressInput, "invalid pkh"));
// click outside of address input to trigger blur event
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(screen.getByTestId("address-error")).toHaveTextContent("Invalid address")
);
});

it("checks the name is unique", async () => {
const user = userEvent.setup();
store.dispatch(contactsActions.upsert(contact2));
await renderInModal(modalComponent, store);

const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, contact2.name));
// click outside of address input to trigger blur event
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(screen.getByTestId("name-error")).toHaveTextContent(
"Name must be unique across all accounts and contacts"
)
);
});

it("adds contact to address book", async () => {
const user = userEvent.setup();
store.dispatch(contactsActions.upsert(contact2));
await renderInModal(modalComponent, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Set address
const addressInput = screen.getByLabelText("Address");
await act(() => user.clear(addressInput));
await act(() => user.type(addressInput, mockImplicitAddress(5).pkh));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contact2.pkh]: contact2,
[mockImplicitAddress(5).pkh]: {
name: "Test Contact",
pkh: mockImplicitAddress(5).pkh,
},
})
);
});

it("fetches network for contract addresses", async () => {
jest
.mocked(getNetworksForContracts)
.mockResolvedValue(new Map([[contractPkh, "ghostnet"]]));
const user = userEvent.setup();
await renderInModal(modalComponent, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Set address
const addressInput = screen.getByLabelText("Address");
await act(() => user.clear(addressInput));
await act(() => user.type(addressInput, contractPkh));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contractPkh]: {
name: "Test Contact",
pkh: contractPkh,
network: "ghostnet",
},
})
);
});

it("shows error toast on unknown network for contract addresses", async () => {
jest.mocked(getNetworksForContracts).mockResolvedValue(new Map());
const user = userEvent.setup();
await renderInModal(modalComponent, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Set address
const addressInput = screen.getByLabelText("Address");
await act(() => user.clear(addressInput));
await act(() => user.type(addressInput, contractPkh));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

expect(mockToast).toHaveBeenCalledWith({
description: `Network not found for contract ${contractPkh}`,
status: "error",
isClosable: true,
});
expect(store.getState().contacts).toEqual({});
});
});
const contractPkh = mockContractAddress(0).pkh;

it("has pre-filled address field", async () => {
await renderInModal(<AddContactModal pkh={mockImplicitAddress(0).pkh} />, store);

expect(screen.getByLabelText("Address")).toHaveValue(mockImplicitAddress(0).pkh);
});

describe("for pre-set contact", () => {
it("has pre-filled address field", async () => {
await renderInModal(<AddContactModal pkh={mockImplicitAddress(0).pkh} />, store);

expect(screen.getByLabelText("Address")).toHaveValue(mockImplicitAddress(0).pkh);
});

it("validates initial address field", async () => {
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh="invalid pkh" />, store);

await act(() => user.click(screen.getByLabelText("Address")));
// click outside of address input to trigger blur event
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(screen.getByTestId("address-error")).toHaveTextContent("Invalid address")
);
});

it("adds contact to address book with pre-filled address", async () => {
const user = userEvent.setup();
store.dispatch(contactsActions.upsert(contact2));
await renderInModal(<AddContactModal pkh={contact1.pkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contact2.pkh]: contact2,
[contact1.pkh]: {
name: "Test Contact",
pkh: contact1.pkh,
},
})
);
});

it("fetches network for contract addresses", async () => {
jest
.mocked(getNetworksForContracts)
.mockResolvedValue(new Map([[contractPkh, "ghostnet"]]));
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh={contractPkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contractPkh]: {
name: "Test Contact",
pkh: contractPkh,
network: "ghostnet",
},
})
);
});

it("shows error toast on unknown network for contract addresses", async () => {
jest.mocked(getNetworksForContracts).mockResolvedValue(new Map());
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh={contractPkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

expect(mockToast).toHaveBeenCalledWith({
description: `Network not found for contract ${contractPkh}`,
status: "error",
isClosable: true,
});
expect(store.getState().contacts).toEqual({});
});
it("validates initial address field", async () => {
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh="invalid pkh" />, store);

await act(() => user.click(screen.getByLabelText("Address")));
// click outside of address input to trigger blur event
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(screen.getByTestId("address-error")).toHaveTextContent("Invalid address")
);
});

it("adds contact to address book with pre-filled address", async () => {
const user = userEvent.setup();
store.dispatch(contactsActions.upsert(contact2));
await renderInModal(<AddContactModal pkh={contact1.pkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contact2.pkh]: contact2,
[contact1.pkh]: {
name: "Test Contact",
pkh: contact1.pkh,
},
})
);
});

it("fetches network for contract addresses", async () => {
jest.mocked(getNetworksForContracts).mockResolvedValue(new Map([[contractPkh, "ghostnet"]]));
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh={contractPkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

await waitFor(() =>
expect(store.getState().contacts).toEqual({
[contractPkh]: {
name: "Test Contact",
pkh: contractPkh,
network: "ghostnet",
},
})
);
});

it("shows error toast on unknown network for contract addresses", async () => {
jest.mocked(getNetworksForContracts).mockResolvedValue(new Map());
const user = userEvent.setup();
await renderInModal(<AddContactModal pkh={contractPkh} />, store);

// Set name
const nameInput = screen.getByLabelText("Name");
await act(() => user.clear(nameInput));
await act(() => user.type(nameInput, "Test Contact"));
// Submit
await act(() => user.click(screen.getByTestId("confirmation-button")));

expect(mockToast).toHaveBeenCalledWith({
description: `Network not found for contract ${contractPkh}`,
status: "error",
isClosable: true,
});
expect(store.getState().contacts).toEqual({});
});
});

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { useForm } from "react-hook-form";
import { ModalCloseButton } from "../CloseButton";

export const AddContactModal: FC<{
pkh?: string;
pkh: string;
}> = ({ pkh }) => {
const { handleAsyncAction } = useAsyncActionHandler();
const dispatch = useAppDispatch();
Expand Down

0 comments on commit a0b2a12

Please sign in to comment.