diff --git a/redaktions-app/src/integration-tests/edit-question.integration.test.tsx b/redaktions-app/src/integration-tests/edit-question.integration.test.tsx index 2828345..957a5f3 100644 --- a/redaktions-app/src/integration-tests/edit-question.integration.test.tsx +++ b/redaktions-app/src/integration-tests/edit-question.integration.test.tsx @@ -7,6 +7,7 @@ import {SnackbarProvider} from "notistack"; import {getAllQuestionsMock, questionNodesMock} from "../backend/queries/question.mock"; import {getAllCategoriesMock} from "../backend/queries/category.mock"; import {editQuestionMock} from "../backend/mutations/question.mock"; +import {getDeleteIconPath, getEditIconPath} from "./test-helper"; function renderQuestionList() { @@ -21,7 +22,7 @@ function renderQuestionList() { ); } -const getInitialQuestionCards = async (): Promise> => { +const waitForInitialQuestionsToRender = async (): Promise> => { const numberOfQuestionsInMockQuery = questionNodesMock.length; let questionCards: Array = []; await waitFor(() => { @@ -34,14 +35,38 @@ const getInitialQuestionCards = async (): Promise> => { // sorry, I found no better way to find a specific icon button... const queryAllEditIconsButtons = (container?: HTMLElement): Array => { return (container ? queryAllByRole(container, "button") : screen.queryAllByRole("button")) - .filter(button => button.innerHTML.includes("svg") && button.innerHTML.includes("Anpassen")); + .filter(button => button.innerHTML.includes("svg") && button.innerHTML.includes(getEditIconPath())); +} + +// sorry, I found no better way to find a specific icon button... +const queryAllDeleteIconsButtons = (container?: HTMLElement): Array => { + return (container ? queryAllByRole(container, "button") : screen.queryAllByRole("button")) + .filter(button => button.innerHTML.includes("svg") && button.innerHTML.includes(getDeleteIconPath())); +} + +const expandAccordionAndGetIconButtons = async (accordion: HTMLElement): Promise<{ editIconButton: HTMLElement, deleteIconButton: HTMLElement }> => { + let editIconsButtons = queryAllDeleteIconsButtons(); + let deleteIconsButtons = queryAllEditIconsButtons(); + expect(editIconsButtons).toHaveLength(0); + expect(deleteIconsButtons).toHaveLength(0); + fireEvent.click(accordion); + await waitFor(() => { + editIconsButtons = queryAllEditIconsButtons(); + deleteIconsButtons = queryAllDeleteIconsButtons(); + expect(editIconsButtons).toHaveLength(1); + expect(deleteIconsButtons).toHaveLength(1); + }) + return { + editIconButton: editIconsButtons[0], + deleteIconButton: deleteIconsButtons[0] + }; } describe('The QuestionList', () => { test('displays the existing questions, but not the details of it', async () => { renderQuestionList(); - const questionCards = await getInitialQuestionCards() + const questionCards = await waitForInitialQuestionsToRender() questionCards.forEach(card => { expect(card.innerHTML).toMatch(/Question [1-3]\?/) }) @@ -53,14 +78,10 @@ describe('The QuestionList', () => { renderQuestionList(); // Initial state: Every question card is not expanded - const questionCards = await getInitialQuestionCards() - expect(queryAllEditIconsButtons()).toHaveLength(0) + const questionCards = await waitForInitialQuestionsToRender() // Expand first question card - fireEvent.click(questionCards[0]) - await waitFor(() => { - expect(queryAllEditIconsButtons()).toHaveLength(1) - }); + await expandAccordionAndGetIconButtons(questionCards[0]) // Shrink first question card again fireEvent.click(questionCards[0]) @@ -72,19 +93,12 @@ describe('The QuestionList', () => { test('enables editing a question title', async () => { renderQuestionList(); - const questionCards = await getInitialQuestionCards(); - - // Expand first card - fireEvent.click(questionCards[0]); - let editIcons: Array = []; - await waitFor(() => { - editIcons = queryAllEditIconsButtons(); - expect(editIcons).toHaveLength(1); - }) + const questionCards = await waitForInitialQuestionsToRender(); + const {editIconButton} = await expandAccordionAndGetIconButtons(questionCards[0]); // open edit dialog expect(screen.queryByText(/Frage bearbeiten/)).toBeNull(); - fireEvent.click(editIcons[0]); + fireEvent.click(editIconButton); await waitFor(() => { expect(screen.queryByText(/Frage bearbeiten/)).not.toBeNull(); }) diff --git a/redaktions-app/src/integration-tests/test-helper.tsx b/redaktions-app/src/integration-tests/test-helper.tsx new file mode 100644 index 0000000..2799aca --- /dev/null +++ b/redaktions-app/src/integration-tests/test-helper.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import {render} from '@testing-library/react' +import DeleteIcon from '@material-ui/icons/Delete'; +import EditIcon from '@material-ui/icons/Edit'; + + +const memoizedGetIconPath = (icon: JSX.Element) => { + let cache: { path?: string } = {}; + return (): string => { + if (cache?.path) { + return cache.path + } else { + const {container} = render(icon) + const path = container.innerHTML.match(//)?.[1] + if (!path) { + throw `Could not get path of MUI ${icon.type.displayName}` + } + cache.path = path + return path + } + } +} + +export const getDeleteIconPath = memoizedGetIconPath() +export const getEditIconPath = memoizedGetIconPath() +