Add unit test coverage
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { ExploreId } from '../../../types/explore';
|
||||
import { RichHistory, RichHistoryProps } from './RichHistory';
|
||||
import { Tabs } from './RichHistory';
|
||||
|
||||
jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() }));
|
||||
|
||||
const setup = (propOverrides?: Partial<RichHistoryProps>) => {
|
||||
const props: RichHistoryProps = {
|
||||
theme: {} as GrafanaTheme,
|
||||
exploreId: ExploreId.left,
|
||||
activeDatasourceInstance: 'Test datasource',
|
||||
richHistory: [],
|
||||
firstTab: Tabs.RichHistory,
|
||||
deleteRichHistory: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistory {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
describe('RichHistory', () => {
|
||||
it('should render component without errors', () => {
|
||||
setup();
|
||||
});
|
||||
it('should correctly render all tabs in tab bar', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('Query history');
|
||||
expect(wrapper.html()).toContain('Starred');
|
||||
expect(wrapper.html()).toContain('Settings');
|
||||
});
|
||||
it('should correctly render query history tab as active tab', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('slider');
|
||||
});
|
||||
it('should correctly render starred tab as active tab', () => {
|
||||
const wrapper = setup({ firstTab: Tabs.Starred });
|
||||
expect(wrapper.html()).not.toContain('slider');
|
||||
});
|
||||
});
|
||||
@@ -30,7 +30,7 @@ export const sortOrderOptions = [
|
||||
{ label: 'Data source Z-A', value: SortOrder.DatasourceZA },
|
||||
];
|
||||
|
||||
interface RichHistoryProps extends Themeable {
|
||||
export interface RichHistoryProps extends Themeable {
|
||||
richHistory: RichHistoryQuery[];
|
||||
activeDatasourceInstance: string;
|
||||
firstTab: Tabs;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { RichHistoryCard, Props } from './RichHistoryCard';
|
||||
import { ExploreId } from '../../../types/explore';
|
||||
import { DataSourceApi } from '@grafana/data';
|
||||
|
||||
const setup = (propOverrides?: Partial<Props>) => {
|
||||
const props: Props = {
|
||||
query: {
|
||||
ts: 1,
|
||||
datasourceName: 'Test datasource',
|
||||
datasourceId: 'datasource 1',
|
||||
starred: false,
|
||||
comment: '',
|
||||
queries: ['query1', 'query2', 'query3'],
|
||||
sessionName: '',
|
||||
},
|
||||
changeQuery: jest.fn(),
|
||||
changeDatasource: jest.fn(),
|
||||
clearQueries: jest.fn(),
|
||||
updateRichHistory: jest.fn(),
|
||||
exploreId: ExploreId.left,
|
||||
datasourceInstance: { name: 'Datasource' } as DataSourceApi,
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistoryCard {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
const starredQueryWithComment = {
|
||||
ts: 1,
|
||||
datasourceName: 'Test datasource',
|
||||
datasourceId: 'datasource 1',
|
||||
starred: true,
|
||||
comment: 'test comment',
|
||||
queries: ['query1', 'query2', 'query3'],
|
||||
sessionName: '',
|
||||
};
|
||||
|
||||
describe('RichHistoryCard', () => {
|
||||
it('should render without errors', () => {
|
||||
setup();
|
||||
});
|
||||
it('should render all queries', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('query1');
|
||||
expect(wrapper.html()).toContain('query2');
|
||||
expect(wrapper.html()).toContain('query3');
|
||||
});
|
||||
|
||||
describe('commenting', () => {
|
||||
it('should render comment, if comment present', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.html()).toContain('test comment');
|
||||
});
|
||||
it('should have title "Edit comment" at comment icon, if comment present', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.html()).toContain('Edit comment');
|
||||
});
|
||||
it('should have title "Add comment" at comment icon, if no comment present', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('Add comment');
|
||||
});
|
||||
});
|
||||
|
||||
describe('starring', () => {
|
||||
it('should render fa-star-o icon, if not starred', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('fa-star-o');
|
||||
});
|
||||
it('should have title "Star query", if not starred', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('Star query');
|
||||
});
|
||||
|
||||
it('should have fa-star icon, if starred', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.html()).toContain('fa-star');
|
||||
});
|
||||
|
||||
it('should have title "Unstar query", if starred', () => {
|
||||
const wrapper = setup({ query: starredQueryWithComment });
|
||||
expect(wrapper.html()).toContain('Unstar query');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,7 @@ import appEvents from 'app/core/app_events';
|
||||
import { StoreState } from 'app/types';
|
||||
|
||||
import { changeQuery, changeDatasource, clearQueries, updateRichHistory } from '../state/actions';
|
||||
interface Props {
|
||||
export interface Props {
|
||||
query: RichHistoryQuery;
|
||||
changeQuery: typeof changeQuery;
|
||||
changeDatasource: typeof changeDatasource;
|
||||
@@ -117,7 +117,7 @@ export function RichHistoryCard(props: Props) {
|
||||
<div className={styles.queryCardLeft} onClick={() => onChangeQuery(query)}>
|
||||
{query.queries.map((q, i) => {
|
||||
return (
|
||||
<div key={`${q}-${i}`} className={styles.queryRow}>
|
||||
<div title="query" key={`${q}-${i}`} className={styles.queryRow}>
|
||||
{q}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { Resizable } from 're-resizable';
|
||||
|
||||
import { ExploreId } from '../../../types/explore';
|
||||
import { RichHistoryContainer, Props } from './RichHistoryContainer';
|
||||
import { Tabs } from './RichHistory';
|
||||
|
||||
jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() }));
|
||||
|
||||
const setup = (propOverrides?: Partial<Props>) => {
|
||||
const props: Props = {
|
||||
width: 500,
|
||||
exploreId: ExploreId.left,
|
||||
activeDatasourceInstance: 'Test datasource',
|
||||
richHistory: [],
|
||||
firstTab: Tabs.RichHistory,
|
||||
deleteRichHistory: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistoryContainer {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
describe('RichHistoryContainer', () => {
|
||||
it('should render without errors', () => {
|
||||
setup();
|
||||
});
|
||||
it('should render reseizable component', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.find(Resizable)).toHaveLength(1);
|
||||
});
|
||||
it('should render component with correct width', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('width: 531.5px');
|
||||
});
|
||||
it('should render component with correct height', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('height: 400px');
|
||||
});
|
||||
});
|
||||
@@ -63,7 +63,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
};
|
||||
});
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
width: number;
|
||||
exploreId: ExploreId;
|
||||
activeDatasourceInstance: string;
|
||||
@@ -72,7 +72,7 @@ interface Props {
|
||||
deleteRichHistory: typeof deleteRichHistory;
|
||||
}
|
||||
|
||||
function RichHistoryContainer(props: Props) {
|
||||
export function RichHistoryContainer(props: Props) {
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
/* To create sliding animation for rich history drawer */
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { ExploreId } from '../../../types/explore';
|
||||
import { SortOrder } from 'app/core/utils/explore';
|
||||
import { RichHistoryQueriesTab, Props } from './RichHistoryQueriesTab';
|
||||
|
||||
jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() }));
|
||||
|
||||
const setup = (propOverrides?: Partial<Props>) => {
|
||||
const props: Props = {
|
||||
queries: [],
|
||||
sortOrder: SortOrder.Ascending,
|
||||
activeDatasourceOnly: false,
|
||||
datasourceFilters: null,
|
||||
retentionPeriod: 14,
|
||||
exploreId: ExploreId.left,
|
||||
onChangeSortOrder: jest.fn(),
|
||||
onSelectDatasourceFilters: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistoryQueriesTab {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
describe('RichHistoryQueriesTab', () => {
|
||||
it('should render without errors', () => {
|
||||
setup();
|
||||
});
|
||||
|
||||
describe('slider', () => {
|
||||
it('should render slider', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('aria-label="slider');
|
||||
});
|
||||
it('should render slider with correct timerange', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('today');
|
||||
expect(wrapper.html()).toContain('two weeks ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('sort options', () => {
|
||||
it('should render sorter', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('aria-label="sort queries"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('select datasource', () => {
|
||||
it('should render select datasource if activeDatasourceOnly is false', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('aria-label="filter datasources"');
|
||||
});
|
||||
|
||||
it('should not render select datasource if activeDatasourceOnly is true', () => {
|
||||
const wrapper = setup({ activeDatasourceOnly: true });
|
||||
expect(wrapper.html()).not.toContain('aria-label="filter datasources"');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -23,7 +23,7 @@ import RichHistoryCard from './RichHistoryCard';
|
||||
import { sortOrderOptions } from './RichHistory';
|
||||
import { Select, Slider } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
queries: RichHistoryQuery[];
|
||||
sortOrder: SortOrder;
|
||||
activeDatasourceOnly: boolean;
|
||||
@@ -162,7 +162,7 @@ export function RichHistoryQueriesTab(props: Props) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.containerSlider}>
|
||||
<div className={styles.slider}>
|
||||
<div className={styles.slider} aria-label="slider">
|
||||
<div className="label-slider">
|
||||
Filter history <br />
|
||||
between
|
||||
@@ -187,7 +187,7 @@ export function RichHistoryQueriesTab(props: Props) {
|
||||
<div className={styles.containerContent}>
|
||||
<div className={styles.selectors}>
|
||||
{!activeDatasourceOnly && (
|
||||
<div className={styles.multiselect}>
|
||||
<div className={styles.multiselect} aria-label="filter datasources">
|
||||
<Select
|
||||
isMulti={true}
|
||||
options={datasources}
|
||||
@@ -197,7 +197,7 @@ export function RichHistoryQueriesTab(props: Props) {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.sort}>
|
||||
<div className={styles.sort} aria-label="sort queries">
|
||||
<Select
|
||||
options={sortOrderOptions}
|
||||
placeholder="Sort queries by"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { RichHistorySettings, RichHistorySettingsProps } from './RichHistorySettings';
|
||||
|
||||
const setup = (propOverrides?: Partial<RichHistorySettingsProps>) => {
|
||||
const props: RichHistorySettingsProps = {
|
||||
retentionPeriod: 14,
|
||||
starredTabAsFirstTab: true,
|
||||
activeDatasourceOnly: false,
|
||||
onChangeRetentionPeriod: jest.fn(),
|
||||
toggleStarredTabAsFirstTab: jest.fn(),
|
||||
toggleactiveDatasourceOnly: jest.fn(),
|
||||
deleteRichHistory: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistorySettings {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
describe('RichHistorySettings', () => {
|
||||
it('whould render without errors', () => {
|
||||
setup();
|
||||
});
|
||||
it('should render component with correct retention period', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('2 weeks');
|
||||
});
|
||||
it('should render component with correctly checked starredTabAsFirstTab settings', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('<input type="checkbox" id="switch-5" checked="">');
|
||||
});
|
||||
it('should render component with correctly not checked toggleactiveDatasourceOnly settings', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('<input type="checkbox" id="switch-8">');
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,7 @@ import { stylesFactory, useTheme, Forms } from '@grafana/ui';
|
||||
import { GrafanaTheme, AppEvents } from '@grafana/data';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
interface RichHistorySettingsProps {
|
||||
export interface RichHistorySettingsProps {
|
||||
retentionPeriod: number;
|
||||
starredTabAsFirstTab: boolean;
|
||||
activeDatasourceOnly: boolean;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { ExploreId } from '../../../types/explore';
|
||||
import { SortOrder } from 'app/core/utils/explore';
|
||||
import { RichHistoryStarredTab, Props } from './RichHistoryStarredTab';
|
||||
|
||||
jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() }));
|
||||
|
||||
const setup = (propOverrides?: Partial<Props>) => {
|
||||
const props: Props = {
|
||||
queries: [],
|
||||
sortOrder: SortOrder.Ascending,
|
||||
activeDatasourceOnly: false,
|
||||
datasourceFilters: null,
|
||||
exploreId: ExploreId.left,
|
||||
onChangeSortOrder: jest.fn(),
|
||||
onSelectDatasourceFilters: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = mount(<RichHistoryStarredTab {...props} />);
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
describe('RichHistoryStarredTab', () => {
|
||||
it('should render without errors', () => {
|
||||
setup();
|
||||
});
|
||||
describe('sorter', () => {
|
||||
it('should render sorter', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('aria-label="sort queries"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('select datasource', () => {
|
||||
it('should render select datasource if activeDatasourceOnly is false', () => {
|
||||
const wrapper = setup();
|
||||
expect(wrapper.html()).toContain('aria-label="filter datasources"');
|
||||
});
|
||||
|
||||
it('should not render select datasource if activeDatasourceOnly is true', () => {
|
||||
const wrapper = setup({ activeDatasourceOnly: true });
|
||||
expect(wrapper.html()).not.toContain('aria-label="filter datasources"');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,7 +18,7 @@ import RichHistoryCard from './RichHistoryCard';
|
||||
import { sortOrderOptions } from './RichHistory';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
queries: RichHistoryQuery[];
|
||||
sortOrder: SortOrder;
|
||||
activeDatasourceOnly: boolean;
|
||||
@@ -111,7 +111,7 @@ export function RichHistoryStarredTab(props: Props) {
|
||||
<div className={styles.containerContent}>
|
||||
<div className={styles.selectors}>
|
||||
{!activeDatasourceOnly && (
|
||||
<div className={styles.multiselect}>
|
||||
<div className={styles.multiselect} aria-label="filter datasources">
|
||||
<Select
|
||||
isMulti={true}
|
||||
options={exploreDatasources}
|
||||
@@ -121,7 +121,7 @@ export function RichHistoryStarredTab(props: Props) {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.sort}>
|
||||
<div className={styles.sort} aria-label="sort queries">
|
||||
<Select
|
||||
options={sortOrderOptions}
|
||||
placeholder="Sort queries by"
|
||||
|
||||
Reference in New Issue
Block a user