#11 Improve tests

This commit is contained in:
Christoph Lienhard 2020-12-30 11:07:37 +01:00
parent 587c0cdeba
commit 4ed8927522
Signed by: christoph.lienhard
GPG Key ID: 6B98870DDC270884
2 changed files with 59 additions and 19 deletions

View File

@ -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<Array<HTMLElement>> => {
const waitForInitialQuestionsToRender = async (): Promise<Array<HTMLElement>> => {
const numberOfQuestionsInMockQuery = questionNodesMock.length;
let questionCards: Array<HTMLElement> = [];
await waitFor(() => {
@ -34,14 +35,38 @@ const getInitialQuestionCards = async (): Promise<Array<HTMLElement>> => {
// sorry, I found no better way to find a specific icon button...
const queryAllEditIconsButtons = (container?: HTMLElement): Array<HTMLElement> => {
return (container ? queryAllByRole(container, "button") : screen.queryAllByRole("button"))
.filter(button => button.innerHTML.includes("svg") && button.innerHTML.includes("<title>Anpassen</title>"));
.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<HTMLElement> => {
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<HTMLElement> = [];
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();
})

View File

@ -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(/<path d="(.*)">/)?.[1]
if (!path) {
throw `Could not get path of MUI ${icon.type.displayName}`
}
cache.path = path
return path
}
}
}
export const getDeleteIconPath = memoizedGetIconPath(<DeleteIcon/>)
export const getEditIconPath = memoizedGetIconPath(<EditIcon/>)