kandimat/redaktions-app/src/integration-tests/category-list.integration.test.tsx
Christoph Lienhard ee263f52b1
Introduce routes to navigate as logged-in user
This also enables navigating to an empty user-management page
if logged-in as an editor.
2021-02-08 00:16:33 +01:00

165 lines
5.5 KiB
TypeScript

import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { MockedProvider, MockedResponse } from "@apollo/client/testing";
import { MemoryRouter } from "react-router-dom";
import CategoryList from "../components/CategoryList";
import { SnackbarProvider } from "notistack";
import {
categoryNodesMock,
getAllCategoriesMock,
getCategoryByIdMock,
} from "../backend/queries/category.mock";
import {
addCategoryMock,
deleteCategoryMock,
editCategoryMock,
} from "../backend/mutations/category.mock";
import {
expandAccordionAndGetIconButtons,
queryAllAddIconButtons,
queryAllEditIconButtons,
} from "./test-helper";
function renderCategoryList(additionalMocks?: Array<MockedResponse>) {
const initialMocks = [...getAllCategoriesMock, ...getCategoryByIdMock];
const allMocks = additionalMocks
? [...initialMocks, ...additionalMocks]
: initialMocks;
return render(
<MockedProvider mocks={allMocks}>
<MemoryRouter>
<SnackbarProvider>
<CategoryList />
</SnackbarProvider>
</MemoryRouter>
</MockedProvider>
);
}
const waitForInitialCategoriesToRender = async (): Promise<
Array<HTMLElement>
> => {
const numberOfCategoriesInMockQuery = categoryNodesMock.length;
let categoryCards: Array<HTMLElement> = [];
await waitFor(() => {
categoryCards = screen.queryAllByRole("button", { name: /Category [1-2]/ });
expect(categoryCards.length).toEqual(numberOfCategoriesInMockQuery);
});
return categoryCards;
};
describe("The CategoryList", () => {
test("displays the existing categories, but not the details of it", async () => {
renderCategoryList();
const categoryCards = await waitForInitialCategoriesToRender();
categoryCards.forEach((card) => {
expect(card.innerHTML).toMatch(/Category [1-2]/);
});
expect(queryAllEditIconButtons()).toHaveLength(0);
});
test("enables toggling details on each category", async () => {
renderCategoryList();
// Initial state: Every category card is not expanded
const categoryCards = await waitForInitialCategoriesToRender();
// Expand first category card
await expandAccordionAndGetIconButtons(categoryCards[0]);
// Shrink first category card again
fireEvent.click(categoryCards[0]);
await waitFor(() => {
expect(queryAllEditIconButtons()).toHaveLength(0);
});
});
test("enables editing a category title", async () => {
renderCategoryList(editCategoryMock);
const categoryCards = await waitForInitialCategoriesToRender();
const { editIconButton } = await expandAccordionAndGetIconButtons(
categoryCards[0]
);
// open edit dialog
expect(screen.queryByText(/Kategorie bearbeiten/)).toBeNull();
fireEvent.click(editIconButton);
await waitFor(() => {
expect(screen.queryByText(/Kategorie bearbeiten/)).not.toBeNull();
});
// change category title
const categoryTitleField = screen.getByDisplayValue(/Category 1/);
fireEvent.change(categoryTitleField, {
target: { value: "New title for Category 1" },
});
await waitFor(() => {
expect(screen.queryByDisplayValue(/New title for /)).not.toBeNull();
});
// call backend and assert apollo cache update
const confirmButton = screen.getByRole("button", { name: /Speichern/ });
fireEvent.click(confirmButton);
await waitFor(() => {
expect(screen.queryByText(/Kategorie bearbeiten/)).toBeNull();
expect(screen.queryByText(/New title for Category 1/)).not.toBeNull();
});
});
test("enables adding a category", async () => {
renderCategoryList(addCategoryMock);
await waitForInitialCategoriesToRender();
// open add dialog
const dialogIdentifier = /Neue Kategorie erstellen/;
expect(screen.queryByText(dialogIdentifier)).toBeNull();
const addButton = queryAllAddIconButtons()[0];
fireEvent.click(addButton);
await waitFor(() => {
expect(screen.queryByText(dialogIdentifier)).not.toBeNull();
});
// change category title
const categoryTitleField = screen.getByLabelText(/Zusammenfassung/);
fireEvent.change(categoryTitleField, { target: { value: "New category" } });
await waitFor(() => {
expect(screen.queryByDisplayValue(/New category/)).not.toBeNull();
});
// call backend and assert apollo cache update
const confirmButton = screen.getByRole("button", { name: /Erstellen/ });
fireEvent.click(confirmButton);
await waitFor(() => {
expect(screen.queryByText(dialogIdentifier)).toBeNull();
expect(screen.queryByText(/New category/)).not.toBeNull();
});
});
test("enables deleting a category", async () => {
renderCategoryList(deleteCategoryMock);
const categoryCards = await waitForInitialCategoriesToRender();
expect(screen.queryByText(/Category 2/)).not.toBeNull();
const { deleteIconButton } = await expandAccordionAndGetIconButtons(
categoryCards[1]
);
// open delete confirmation dialog
expect(screen.queryByText(/Kategorie löschen/)).toBeNull();
fireEvent.click(deleteIconButton);
await waitFor(() => {
expect(screen.queryByText(/Kategorie löschen/)).not.toBeNull();
});
// call backend and assert apollo cache update
const confirmButton = screen.getByRole("button", { name: /Löschen/ });
fireEvent.click(confirmButton);
await waitFor(() => {
expect(screen.queryByText(/Kategorie löschen/)).toBeNull();
expect(screen.queryByText(/Category 2/)).toBeNull();
});
});
});