diff --git a/package.json b/package.json index 98656622..d65fb6ba 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.3.0", "@tanstack/react-query-devtools": "^5.8.4", "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^14.1.2", "@testing-library/user-event": "14.4.3", "@types/jest": "^29.5.3", "@types/react-router-dom": "^5.3.3", diff --git a/src/components/__tests__/__snapshots__/actionMenu.test.tsx.snap b/src/components/__tests__/__snapshots__/actionMenu.test.tsx.snap new file mode 100644 index 00000000..8169d5e2 --- /dev/null +++ b/src/components/__tests__/__snapshots__/actionMenu.test.tsx.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders proper dom including elipse icon 1`] = ` + + + +`; + +exports[`snapshot matches after opening the action menu 1`] = ` + + +
+
+ +
+
+
+`; diff --git a/src/components/__tests__/actionMenu.test.tsx b/src/components/__tests__/actionMenu.test.tsx new file mode 100644 index 00000000..185f2f90 --- /dev/null +++ b/src/components/__tests__/actionMenu.test.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import ActionMenu from '../ActionMenu'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import '@testing-library/jest-dom'; + +test('renders proper dom including elipse icon', () => { + const item = { foo: 'bar' }; + const actionClicked = (_item: {foo: string}) => {}; + const { asFragment } = render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + expect(asFragment()).toMatchSnapshot(); + }); + + test('actions will not show before button is clicked', () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = (_item: {foo: string}) => {}; + const { queryByText } = render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + expect(queryByText("Delete")).toBeNull(); + }); + + test('actions will show after button is clicked', async () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = (_item: {foo: string}) => {}; + render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + const toggleButton = await screen.findByLabelText('Action Menu Toggle'); + await user.click(toggleButton); + expect(screen.getByText("Delete")).toBeVisible(); + }); + + test('snapshot matches after opening the action menu', async () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = (_item: {foo: string}) => {}; + const { asFragment } = render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + const toggleButton = await screen.findByLabelText('Action Menu Toggle'); + await user.click(toggleButton); + expect(asFragment()).toMatchSnapshot(); + }); + + test('action callback should get called when clicked', async () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = jest.fn(); + render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + expect(actionClicked).toHaveBeenCalledTimes(0); + const toggleButton = await screen.findByLabelText('Action Menu Toggle'); + await user.click(toggleButton); + const deleteButton = await screen.findByText("Delete"); + await user.click(deleteButton); + expect(actionClicked).toHaveBeenCalledTimes(1); + }); + + test('action menu closes after selection', async () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = jest.fn(); + render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + const toggleButton = await screen.findByLabelText('Action Menu Toggle'); + await user.click(toggleButton); + const deleteButton = await screen.findByText("Delete"); + expect(deleteButton).toBeVisible(); + await user.click(deleteButton); + expect(deleteButton).not.toBeVisible(); + }); + + test('action menu closes if toggle is clicked again', async () => { + const user = userEvent.setup(); + + const item = { foo: 'bar' }; + const actionClicked = jest.fn(); + render( + + item={item} + actions={[{ label: 'Delete', onClick: actionClicked }]} + /> + ); + const toggleButton = await screen.findByLabelText('Action Menu Toggle'); + await user.click(toggleButton); + const deleteButton = await screen.findByText("Delete"); + expect(deleteButton).toBeVisible(); + await user.click(toggleButton); + expect(deleteButton).not.toBeVisible(); + }); \ No newline at end of file