grafana/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx

310 lines
11 KiB
TypeScript
Raw Normal View History

import { within } from '@testing-library/dom';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { PanelPluginMeta, PluginType } from '@grafana/data';
import { Panel } from '@grafana/schema';
import { backendSrv } from '../../../../core/services/backend_srv';
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
import * as panelUtils from '../../../panel/state/util';
import * as api from '../../state/api';
import { LibraryElementsSearchResult } from '../../types';
import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch';
jest.mock('@grafana/runtime', () => ({
...(jest.requireActual('@grafana/runtime') as unknown as object),
config: {
panels: {
timeseries: {
info: { logos: { small: '' } },
name: 'Time Series',
},
},
},
}));
jest.mock('debounce-promise', () => {
const debounce = (fn: any) => {
const debounced = () =>
Promise.resolve([
{ label: 'General', value: { uid: '', title: 'General' } },
{ label: 'Folder1', value: { id: 'xMsQdBfWz', title: 'Folder1' } },
{ label: 'Folder2', value: { id: 'wfTJJL5Wz', title: 'Folder2' } },
]);
return debounced;
};
return debounce;
});
async function getTestContext(
propOverrides: Partial<LibraryPanelsSearchProps> = {},
searchResult: LibraryElementsSearchResult = { elements: [], perPage: 40, page: 1, totalCount: 0 }
) {
jest.clearAllMocks();
const pluginInfo: any = { logos: { small: '', large: '' } };
const graph: PanelPluginMeta = {
name: 'Graph',
id: 'graph',
info: pluginInfo,
baseUrl: '',
type: PluginType.panel,
module: '',
sort: 0,
};
const timeseries: PanelPluginMeta = {
name: 'Time Series',
id: 'timeseries',
info: pluginInfo,
baseUrl: '',
type: PluginType.panel,
module: '',
sort: 1,
};
const getSpy = jest
.spyOn(backendSrv, 'get')
.mockResolvedValue({ sortOptions: [{ displaName: 'Desc', name: 'alpha-desc' }] });
const getLibraryPanelsSpy = jest.spyOn(api, 'getLibraryPanels').mockResolvedValue(searchResult);
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
const getAllPanelPluginMetaSpy = jest.spyOn(panelUtils, 'getAllPanelPluginMeta').mockReturnValue([graph, timeseries]);
const props: LibraryPanelsSearchProps = {
onClick: jest.fn(),
};
Object.assign(props, propOverrides);
const { rerender } = render(<LibraryPanelsSearch {...props} />);
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
jest.clearAllMocks();
return { rerender, getLibraryPanelsSpy, getSpy, getAllPanelPluginMetaSpy };
}
describe('LibraryPanelsSearch', () => {
describe('when mounted with default options', () => {
it('should show input filter and library panels view', async () => {
await getTestContext();
expect(screen.getByPlaceholderText(/search by name/i)).toBeInTheDocument();
expect(screen.getByText(/no library panels found./i)).toBeInTheDocument();
});
describe('and user searches for library panel by name or description', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext();
await userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
await waitFor(() =>
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: 'a',
folderFilterUIDs: [],
page: 0,
typeFilter: [],
perPage: 40,
})
);
});
});
});
describe('when mounted with showSort', () => {
it('should show input filter and library panels view and sort', async () => {
await getTestContext({ showSort: true });
expect(screen.getByPlaceholderText(/search by name/i)).toBeInTheDocument();
expect(screen.getByText(/no library panels found./i)).toBeInTheDocument();
expect(screen.getByText(/sort \(default az\)/i)).toBeInTheDocument();
});
describe('and user changes sorting', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
await userEvent.type(screen.getByText(/sort \(default az\)/i), 'Desc{enter}');
await waitFor(() =>
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '',
sortDirection: 'alpha-desc',
folderFilterUIDs: [],
page: 0,
typeFilter: [],
perPage: 40,
})
);
});
});
});
describe('when mounted with showPanelFilter', () => {
it('should show input filter and library panels view and panel filter', async () => {
await getTestContext({ showPanelFilter: true });
expect(screen.getByPlaceholderText(/search by name/i)).toBeInTheDocument();
expect(screen.getByText(/no library panels found./i)).toBeInTheDocument();
expect(screen.getByRole('combobox', { name: /panel type filter/i })).toBeInTheDocument();
});
describe('and user changes panel filter', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Graph{enter}');
await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Time Series{enter}');
await waitFor(() =>
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '',
folderFilterUIDs: [],
page: 0,
typeFilter: ['graph', 'timeseries'],
perPage: 40,
})
);
});
});
});
describe('when mounted with showPanelFilter', () => {
it('should show input filter and library panels view and folder filter', async () => {
await getTestContext({ showFolderFilter: true });
expect(screen.getByPlaceholderText(/search by name/i)).toBeInTheDocument();
expect(screen.getByText(/no library panels found./i)).toBeInTheDocument();
expect(screen.getByRole('combobox', { name: /folder filter/i })).toBeInTheDocument();
});
describe('and user changes folder filter', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext(
{ showFolderFilter: true, currentFolderUID: 'wXyZ1234' },
{
elements: [
{
name: 'Library Panel Name',
uid: 'uid',
description: 'Library Panel Description',
folderUid: '',
model: { type: 'timeseries', title: 'A title' } as Panel,
type: 'timeseries',
version: 1,
meta: {
folderName: 'General',
folderUid: '',
connectedDashboards: 0,
created: '2021-01-01 12:00:00',
createdBy: { id: 1, name: 'Admin', avatarUrl: '' },
updated: '2021-01-01 12:00:00',
updatedBy: { id: 1, name: 'Admin', avatarUrl: '' },
},
},
],
perPage: 40,
page: 1,
totalCount: 0,
}
);
await userEvent.click(screen.getByRole('combobox', { name: /folder filter/i }));
await userEvent.type(screen.getByRole('combobox', { name: /folder filter/i }), 'library', {
skipClick: true,
});
await waitFor(() => {
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '',
folderFilterUIDs: ['wXyZ1234'],
page: 0,
typeFilter: [],
perPage: 40,
});
});
});
});
});
describe('when mounted without showSecondaryActions and there is one panel', () => {
it('should show correct row and no delete button', async () => {
await getTestContext(
{},
{
page: 1,
totalCount: 1,
perPage: 40,
elements: [
{
name: 'Library Panel Name',
uid: 'uid',
description: 'Library Panel Description',
folderUid: '',
model: { type: 'timeseries', title: 'A title' } as Panel,
type: 'timeseries',
version: 1,
meta: {
folderName: 'General',
folderUid: '',
connectedDashboards: 0,
created: '2021-01-01 12:00:00',
createdBy: { id: 1, name: 'Admin', avatarUrl: '' },
updated: '2021-01-01 12:00:00',
updatedBy: { id: 1, name: 'Admin', avatarUrl: '' },
},
},
],
}
);
const card = () => screen.getByLabelText(/plugin visualization item time series/i);
expect(screen.queryByText(/no library panels found./i)).not.toBeInTheDocument();
expect(card()).toBeInTheDocument();
expect(within(card()).getByText(/library panel name/i)).toBeInTheDocument();
expect(within(card()).getByText(/library panel description/i)).toBeInTheDocument();
expect(within(card()).queryByLabelText(/delete button on panel type card/i)).not.toBeInTheDocument();
});
});
describe('when mounted with showSecondaryActions and there is one panel', () => {
it('should show correct row and delete button', async () => {
await getTestContext(
{ showSecondaryActions: true },
{
page: 1,
totalCount: 1,
perPage: 40,
elements: [
{
name: 'Library Panel Name',
uid: 'uid',
description: 'Library Panel Description',
folderUid: '',
model: { type: 'timeseries', title: 'A title' } as Panel,
type: 'timeseries',
version: 1,
meta: {
folderName: 'General',
folderUid: '',
connectedDashboards: 0,
created: '2021-01-01 12:00:00',
createdBy: { id: 1, name: 'Admin', avatarUrl: '' },
updated: '2021-01-01 12:00:00',
updatedBy: { id: 1, name: 'Admin', avatarUrl: '' },
},
},
],
}
);
const card = () => screen.getByLabelText(/plugin visualization item time series/i);
expect(screen.queryByText(/no library panels found./i)).not.toBeInTheDocument();
expect(card()).toBeInTheDocument();
expect(within(card()).getByText(/library panel name/i)).toBeInTheDocument();
expect(within(card()).getByText(/library panel description/i)).toBeInTheDocument();
expect(within(card()).getByLabelText(/delete button on panel type card/i)).toBeInTheDocument();
});
});
});