Skip to content

Commit

Permalink
Expand DeleteCell testing (#2823)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Dec 4, 2023
1 parent 2525ccd commit 0771f05
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/goals/ReviewEntries/ReviewEntriesTable/CellColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ const columns: Column<ReviewEntriesWord>[] = [

// Delete Entry column
{
id: ColumnId.Delete,
title: ColumnTitle.Delete,
filtering: false,
sorting: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Delete } from "@mui/icons-material";
import { IconButton, Tooltip } from "@mui/material";
import React, { ReactElement, useState } from "react";
import { ReactElement, useState } from "react";
import { useTranslation } from "react-i18next";

import { deleteFrontierWord as deleteFromBackend } from "backend";
Expand All @@ -10,6 +10,10 @@ import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreState } from "types";
import { useAppDispatch, useAppSelector } from "types/hooks";

export const buttonId = (wordId: string): string => `row-${wordId}-delete`;
export const buttonIdCancel = "delete-cancel";
export const buttonIdConfirm = "delete-confirm";

interface DeleteCellProps {
rowData: ReviewEntriesWord;
}
Expand Down Expand Up @@ -40,15 +44,15 @@ export default function DeleteCell(props: DeleteCellProps): ReactElement {
}

return (
<React.Fragment>
<>
<Tooltip
title={disabled ? t("reviewEntries.deleteDisabled") : ""}
placement={document.body.dir === "rtl" ? "right" : "left"}
>
<span>
<IconButton
onClick={handleOpen}
id={`row-${props.rowData.id}-delete`}
id={buttonId(props.rowData.id)}
size="large"
disabled={disabled}
>
Expand All @@ -61,9 +65,9 @@ export default function DeleteCell(props: DeleteCellProps): ReactElement {
textId={"reviewEntries.deleteWordWarning"}
handleCancel={handleClose}
handleConfirm={deleteFrontierWord}
buttonIdCancel="row-delete-cancel"
buttonIdConfirm="row-delete-confirm"
buttonIdCancel={buttonIdCancel}
buttonIdConfirm={buttonIdConfirm}
/>
</React.Fragment>
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,103 @@
import { Provider } from "react-redux";
import renderer from "react-test-renderer";
import { ReactTestRenderer, act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import "tests/reactI18nextMock";

import { CancelConfirmDialog } from "components/Dialogs";
import { defaultState as reviewEntriesState } from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import DeleteCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell";
import DeleteCell, {
buttonId,
buttonIdCancel,
buttonIdConfirm,
} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell";
import mockWords from "goals/ReviewEntries/tests/WordsMock";

// Dialog uses portals, which are not supported in react-test-renderer.
jest.mock("@mui/material", () => {
const materialUiCore = jest.requireActual("@mui/material");
return {
...jest.requireActual("@mui/material"),
Dialog: materialUiCore.Container,
};
});

jest.mock("backend", () => ({
deleteFrontierWord: () => mockDeleteFrontierWord(),
}));
jest.mock("types/hooks", () => {
return {
...jest.requireActual("types/hooks"),
useAppDispatch:
() =>
(...args: any[]) =>
Promise.resolve(args),
};
});

const mockDeleteFrontierWord = jest.fn();

const mockStore = configureMockStore()({ reviewEntriesState });
const mockWord = mockWords()[0];
const buttonIdDelete = buttonId(mockWord.id);

let cellHandle: ReactTestRenderer;

const renderDeleteCell = async (): Promise<void> => {
await act(async () => {
cellHandle = create(
<Provider store={mockStore}>
<DeleteCell rowData={mockWord} />
</Provider>
);
});
};

beforeEach(async () => {
jest.clearAllMocks();
await renderDeleteCell();
});

describe("DeleteCell", () => {
it("renders", () => {
renderer.act(() => {
renderer.create(
<Provider store={mockStore}>
<DeleteCell rowData={mockWord} />
</Provider>
);
it("has working dialog buttons", async () => {
const dialog = cellHandle.root.findByType(CancelConfirmDialog);
const deleteButton = cellHandle.root.findByProps({ id: buttonIdDelete });
const cancelButton = cellHandle.root.findByProps({ id: buttonIdCancel });
const confButton = cellHandle.root.findByProps({ id: buttonIdConfirm });

expect(dialog.props.open).toBeFalsy();
await act(async () => {
deleteButton.props.onClick();
});
expect(dialog.props.open).toBeTruthy();
await act(async () => {
cancelButton.props.onClick();
});
expect(dialog.props.open).toBeFalsy();
await act(async () => {
deleteButton.props.onClick();
});
expect(dialog.props.open).toBeTruthy();
await act(async () => {
await confButton.props.onClick();
});
expect(dialog.props.open).toBeFalsy();
});

it("only deletes after confirmation", async () => {
const deleteButton = cellHandle.root.findByProps({ id: buttonIdDelete });
const cancelButton = cellHandle.root.findByProps({ id: buttonIdCancel });
const confButton = cellHandle.root.findByProps({ id: buttonIdConfirm });

await act(async () => {
deleteButton.props.onClick();
cancelButton.props.onClick();
deleteButton.props.onClick();
});
expect(mockDeleteFrontierWord).not.toBeCalled();
await act(async () => {
await confButton.props.onClick();
});
expect(mockDeleteFrontierWord).toBeCalled();
});
});
1 change: 1 addition & 0 deletions src/goals/ReviewEntries/ReviewEntriesTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum ColumnId {
Pronunciations,
Note,
Flag,
Delete,
}

export class ReviewEntries extends Goal {
Expand Down

0 comments on commit 0771f05

Please sign in to comment.