grafana/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx
Jack Westbrook c9eff1892e
DashboardSettings: Migrates history diff view from angular to react (#31997)
* chore(dashboardsettings): introduce deep-diff for diffing dashboard models

* feat(dashboardsettings): initial commit of diff comparision react migration

* feat(dashboardsettings): wip - use json-source-map and monaco editor

* chore(deps): add react-diff-viewer to package.json

* feat(dashboardsettings): take the simplistic road for diff view

* refactor(dashboardsettings): clean up Version Settings components

* chore: delete angular historyListCtrl code

* refactor(dashboardsettings): styling fixes

* Small color tweaks

* refactor(versionhistory): fix issues around summary text. write tests

* test(versionhistory): add test for jsonDiff

* refactor(versionhistory): cleanup utils and reduce dom elements

* test(versionsettings): add tests for comparision view

* test(versionsettings): finialise tests for version history comparison view

* test(versionsettings): remove debug

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2021-03-25 11:51:09 +01:00

178 lines
7.7 KiB
TypeScript

import React from 'react';
import '@testing-library/jest-dom';
import { render, screen, waitFor } from '@testing-library/react';
import { within } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { historySrv } from '../VersionHistory/HistorySrv';
import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings';
import { versions, diffs } from './__mocks__/versions';
jest.mock('../VersionHistory/HistorySrv');
const queryByFullText = (text: string) =>
screen.queryByText((_, node: Element | undefined | null) => {
if (node) {
const nodeHasText = (node: HTMLElement | Element) => node.textContent?.includes(text);
const currentNodeHasText = nodeHasText(node);
const childrenDontHaveText = Array.from(node.children).every((child) => !nodeHasText(child));
return Boolean(currentNodeHasText && childrenDontHaveText);
}
return false;
});
describe('VersionSettings', () => {
const dashboard: any = {
id: 74,
version: 11,
formatDate: jest.fn(() => 'date'),
getRelativeTime: jest.fn(() => 'time ago'),
};
beforeEach(() => {
jest.resetAllMocks();
});
test('renders a header and a loading indicator followed by results in a table', async () => {
// @ts-ignore
historySrv.getHistoryList.mockResolvedValue(versions);
render(<VersionsSettings dashboard={dashboard} />);
expect(screen.getByRole('heading', { name: /versions/i })).toBeInTheDocument();
expect(screen.queryByText(/fetching history list/i)).toBeInTheDocument();
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
const tableBodyRows = within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row');
expect(tableBodyRows.length).toBe(versions.length);
const firstRow = within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row')[0];
expect(within(firstRow).getByText(/latest/i)).toBeInTheDocument();
expect(within(screen.getByRole('table')).getAllByText(/latest/i)).toHaveLength(1);
});
test('does not render buttons if versions === 1', async () => {
// @ts-ignore
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, 1));
render(<VersionsSettings dashboard={dashboard} />);
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
});
test('does not render show more button if versions < VERSIONS_FETCH_LIMIT', async () => {
// @ts-ignore
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT - 5));
render(<VersionsSettings dashboard={dashboard} />);
expect(screen.queryByRole('button', { name: /show more versions|/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /compare versions/i })).toBeInTheDocument();
});
test('renders buttons if versions >= VERSIONS_FETCH_LIMIT', async () => {
// @ts-ignore
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT));
render(<VersionsSettings dashboard={dashboard} />);
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
const compareButton = screen.getByRole('button', { name: /compare versions/i });
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
expect(showMoreButton).toBeInTheDocument();
expect(showMoreButton).toBeEnabled();
expect(compareButton).toBeInTheDocument();
expect(compareButton).toBeDisabled();
});
test('clicking show more appends results to the table', async () => {
historySrv.getHistoryList
// @ts-ignore
.mockImplementationOnce(() => Promise.resolve(versions.slice(0, VERSIONS_FETCH_LIMIT)))
.mockImplementationOnce(() => Promise.resolve(versions.slice(VERSIONS_FETCH_LIMIT, versions.length)));
render(<VersionsSettings dashboard={dashboard} />);
expect(historySrv.getHistoryList).toBeCalledTimes(1);
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(VERSIONS_FETCH_LIMIT);
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
userEvent.click(showMoreButton);
expect(historySrv.getHistoryList).toBeCalledTimes(2);
expect(screen.queryByText(/Fetching more entries/i)).toBeInTheDocument();
await waitFor(() =>
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(versions.length)
);
});
test('selecting two versions and clicking compare button should render compare view', async () => {
// @ts-ignore
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT));
historySrv.getDashboardVersion
// @ts-ignore
.mockImplementationOnce(() => Promise.resolve(diffs.lhs))
.mockImplementationOnce(() => Promise.resolve(diffs.rhs));
render(<VersionsSettings dashboard={dashboard} />);
expect(historySrv.getHistoryList).toBeCalledTimes(1);
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
const compareButton = screen.getByRole('button', { name: /compare versions/i });
const tableBody = screen.getAllByRole('rowgroup')[1];
userEvent.click(within(tableBody).getAllByRole('checkbox')[0]);
userEvent.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
expect(compareButton).toBeEnabled();
userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
expect(compareButton).toBeDisabled();
userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
userEvent.click(compareButton);
await waitFor(() => expect(screen.getByRole('heading', { name: /versions comparing 2 11/i })).toBeInTheDocument());
expect(queryByFullText('Version 11 updated by admin')).toBeInTheDocument();
expect(queryByFullText('Version 2 updated by admin')).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /restore to version 2/i })).toBeInTheDocument();
expect(screen.queryAllByTestId('diffGroup').length).toBe(5);
const diffGroups = screen.getAllByTestId('diffGroup');
expect(queryByFullText('description added The dashboard description')).toBeInTheDocument();
expect(queryByFullText('panels changed')).toBeInTheDocument();
expect(within(diffGroups[1]).queryByRole('list')).toBeInTheDocument();
expect(within(diffGroups[1]).queryByText(/added title/i)).toBeInTheDocument();
expect(within(diffGroups[1]).queryByText(/changed id/i)).toBeInTheDocument();
expect(queryByFullText('tags deleted item 0')).toBeInTheDocument();
expect(queryByFullText('timepicker added 1 refresh_intervals')).toBeInTheDocument();
expect(queryByFullText('version changed')).toBeInTheDocument();
expect(screen.queryByText(/view json diff/i)).toBeInTheDocument();
userEvent.click(screen.getByText(/view json diff/i));
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
});
});