kandimat/redaktions-app/src/integration-tests/edit-question.integration.test.tsx
Christoph Lienhard 587c0cdeba
#11 Add integration test for editing a question
Also:
* introduce __typename to all response types
2020-12-30 01:10:30 +01:00

108 lines
3.8 KiB
TypeScript

import React from 'react';
import {fireEvent, queryAllByRole, render, screen, waitFor} from '@testing-library/react'
import {MockedProvider} from '@apollo/client/testing';
import {MemoryRouter} from 'react-router-dom';
import QuestionList from "../components/QuestionList";
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";
function renderQuestionList() {
return render(
<MockedProvider mocks={[...getAllQuestionsMock, ...getAllCategoriesMock, ...editQuestionMock]}>
<MemoryRouter>
<SnackbarProvider>
<QuestionList/>
</SnackbarProvider>
</MemoryRouter>
</MockedProvider>
);
}
const getInitialQuestionCards = async (): Promise<Array<HTMLElement>> => {
const numberOfQuestionsInMockQuery = questionNodesMock.length;
let questionCards: Array<HTMLElement> = [];
await waitFor(() => {
questionCards = screen.queryAllByRole("button", {name: /Question [1-3]\?/})
expect(questionCards.length).toEqual(numberOfQuestionsInMockQuery);
});
return questionCards;
}
// 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>"));
}
describe('The QuestionList', () => {
test('displays the existing questions, but not the details of it', async () => {
renderQuestionList();
const questionCards = await getInitialQuestionCards()
questionCards.forEach(card => {
expect(card.innerHTML).toMatch(/Question [1-3]\?/)
})
expect(questionCards[0].innerHTML).toMatch(/Category 1/);
expect(queryAllEditIconsButtons()).toHaveLength(0)
});
test('enables toggling details on each question', async () => {
renderQuestionList();
// Initial state: Every question card is not expanded
const questionCards = await getInitialQuestionCards()
expect(queryAllEditIconsButtons()).toHaveLength(0)
// Expand first question card
fireEvent.click(questionCards[0])
await waitFor(() => {
expect(queryAllEditIconsButtons()).toHaveLength(1)
});
// Shrink first question card again
fireEvent.click(questionCards[0])
await waitFor(() => {
expect(queryAllEditIconsButtons()).toHaveLength(0)
});
});
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);
})
// open edit dialog
expect(screen.queryByText(/Frage bearbeiten/)).toBeNull();
fireEvent.click(editIcons[0]);
await waitFor(() => {
expect(screen.queryByText(/Frage bearbeiten/)).not.toBeNull();
})
// change question title
const questionTitleField = screen.getByDisplayValue(/Question 1/);
fireEvent.change(questionTitleField, {target: {value: "New title for Question 1?"}});
await waitFor(() => {
expect(screen.queryByDisplayValue(/New title for /)).not.toBeNull();
})
const confirmButton = screen.getByRole("button", {name: /Speichern/});
// call backend and assert apollo cache update
fireEvent.click(confirmButton);
await waitFor(() => {
expect(screen.queryByText(/Frage bearbeiten/)).toBeNull();
expect(screen.queryByText(/New title for Question 1/)).not.toBeNull()
})
});
});