#11 Improve tests
This commit is contained in:
parent
587c0cdeba
commit
4ed8927522
|
@ -7,6 +7,7 @@ import {SnackbarProvider} from "notistack";
|
||||||
import {getAllQuestionsMock, questionNodesMock} from "../backend/queries/question.mock";
|
import {getAllQuestionsMock, questionNodesMock} from "../backend/queries/question.mock";
|
||||||
import {getAllCategoriesMock} from "../backend/queries/category.mock";
|
import {getAllCategoriesMock} from "../backend/queries/category.mock";
|
||||||
import {editQuestionMock} from "../backend/mutations/question.mock";
|
import {editQuestionMock} from "../backend/mutations/question.mock";
|
||||||
|
import {getDeleteIconPath, getEditIconPath} from "./test-helper";
|
||||||
|
|
||||||
|
|
||||||
function renderQuestionList() {
|
function renderQuestionList() {
|
||||||
|
@ -21,7 +22,7 @@ function renderQuestionList() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getInitialQuestionCards = async (): Promise<Array<HTMLElement>> => {
|
const waitForInitialQuestionsToRender = async (): Promise<Array<HTMLElement>> => {
|
||||||
const numberOfQuestionsInMockQuery = questionNodesMock.length;
|
const numberOfQuestionsInMockQuery = questionNodesMock.length;
|
||||||
let questionCards: Array<HTMLElement> = [];
|
let questionCards: Array<HTMLElement> = [];
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
|
@ -34,14 +35,38 @@ const getInitialQuestionCards = async (): Promise<Array<HTMLElement>> => {
|
||||||
// sorry, I found no better way to find a specific icon button...
|
// sorry, I found no better way to find a specific icon button...
|
||||||
const queryAllEditIconsButtons = (container?: HTMLElement): Array<HTMLElement> => {
|
const queryAllEditIconsButtons = (container?: HTMLElement): Array<HTMLElement> => {
|
||||||
return (container ? queryAllByRole(container, "button") : screen.queryAllByRole("button"))
|
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', () => {
|
describe('The QuestionList', () => {
|
||||||
test('displays the existing questions, but not the details of it', async () => {
|
test('displays the existing questions, but not the details of it', async () => {
|
||||||
renderQuestionList();
|
renderQuestionList();
|
||||||
|
|
||||||
const questionCards = await getInitialQuestionCards()
|
const questionCards = await waitForInitialQuestionsToRender()
|
||||||
questionCards.forEach(card => {
|
questionCards.forEach(card => {
|
||||||
expect(card.innerHTML).toMatch(/Question [1-3]\?/)
|
expect(card.innerHTML).toMatch(/Question [1-3]\?/)
|
||||||
})
|
})
|
||||||
|
@ -53,14 +78,10 @@ describe('The QuestionList', () => {
|
||||||
renderQuestionList();
|
renderQuestionList();
|
||||||
|
|
||||||
// Initial state: Every question card is not expanded
|
// Initial state: Every question card is not expanded
|
||||||
const questionCards = await getInitialQuestionCards()
|
const questionCards = await waitForInitialQuestionsToRender()
|
||||||
expect(queryAllEditIconsButtons()).toHaveLength(0)
|
|
||||||
|
|
||||||
// Expand first question card
|
// Expand first question card
|
||||||
fireEvent.click(questionCards[0])
|
await expandAccordionAndGetIconButtons(questionCards[0])
|
||||||
await waitFor(() => {
|
|
||||||
expect(queryAllEditIconsButtons()).toHaveLength(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Shrink first question card again
|
// Shrink first question card again
|
||||||
fireEvent.click(questionCards[0])
|
fireEvent.click(questionCards[0])
|
||||||
|
@ -72,19 +93,12 @@ describe('The QuestionList', () => {
|
||||||
test('enables editing a question title', async () => {
|
test('enables editing a question title', async () => {
|
||||||
renderQuestionList();
|
renderQuestionList();
|
||||||
|
|
||||||
const questionCards = await getInitialQuestionCards();
|
const questionCards = await waitForInitialQuestionsToRender();
|
||||||
|
const {editIconButton} = await expandAccordionAndGetIconButtons(questionCards[0]);
|
||||||
// Expand first card
|
|
||||||
fireEvent.click(questionCards[0]);
|
|
||||||
let editIcons: Array<HTMLElement> = [];
|
|
||||||
await waitFor(() => {
|
|
||||||
editIcons = queryAllEditIconsButtons();
|
|
||||||
expect(editIcons).toHaveLength(1);
|
|
||||||
})
|
|
||||||
|
|
||||||
// open edit dialog
|
// open edit dialog
|
||||||
expect(screen.queryByText(/Frage bearbeiten/)).toBeNull();
|
expect(screen.queryByText(/Frage bearbeiten/)).toBeNull();
|
||||||
fireEvent.click(editIcons[0]);
|
fireEvent.click(editIconButton);
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.queryByText(/Frage bearbeiten/)).not.toBeNull();
|
expect(screen.queryByText(/Frage bearbeiten/)).not.toBeNull();
|
||||||
})
|
})
|
||||||
|
|
26
redaktions-app/src/integration-tests/test-helper.tsx
Normal file
26
redaktions-app/src/integration-tests/test-helper.tsx
Normal 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/>)
|
||||||
|
|
Loading…
Reference in a new issue