diff --git a/public/app/features/explore/RichHistory/RichHistory.test.tsx b/public/app/features/explore/RichHistory/RichHistory.test.tsx new file mode 100644 index 00000000000..0948d178e9d --- /dev/null +++ b/public/app/features/explore/RichHistory/RichHistory.test.tsx @@ -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) => { + 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(); + 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'); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistory.tsx b/public/app/features/explore/RichHistory/RichHistory.tsx index 699a50457a2..ffe0fc0cbcc 100644 --- a/public/app/features/explore/RichHistory/RichHistory.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.tsx @@ -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; diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx new file mode 100644 index 00000000000..4e7f6b3b5ee --- /dev/null +++ b/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx @@ -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) => { + 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(); + 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'); + }); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.tsx index 602e0cfa82f..e2012ad80ea 100644 --- a/public/app/features/explore/RichHistory/RichHistoryCard.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryCard.tsx @@ -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) {
onChangeQuery(query)}> {query.queries.map((q, i) => { return ( -
+
{q}
); diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx new file mode 100644 index 00000000000..6dc3f559085 --- /dev/null +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx @@ -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) => { + 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(); + 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'); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx index 95dd5e38b21..32b016c58e2 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx @@ -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 */ diff --git a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.test.tsx b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.test.tsx new file mode 100644 index 00000000000..8b912d2913a --- /dev/null +++ b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.test.tsx @@ -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) => { + 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(); + 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"'); + }); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx index 7a4e581b1a7..440bbdde278 100644 --- a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx @@ -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 (
-
+
Filter history
between @@ -187,7 +187,7 @@ export function RichHistoryQueriesTab(props: Props) {
{!activeDatasourceOnly && ( -
+
) => { + 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(); + 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(''); + }); + it('should render component with correctly not checked toggleactiveDatasourceOnly settings', () => { + const wrapper = setup(); + expect(wrapper.html()).toContain(''); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistorySettings.tsx b/public/app/features/explore/RichHistory/RichHistorySettings.tsx index 55dfff5d47f..7ef75982d0e 100644 --- a/public/app/features/explore/RichHistory/RichHistorySettings.tsx +++ b/public/app/features/explore/RichHistory/RichHistorySettings.tsx @@ -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; diff --git a/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx b/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx new file mode 100644 index 00000000000..4c5d7de1da4 --- /dev/null +++ b/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx @@ -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) => { + 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(); + 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"'); + }); + }); +}); diff --git a/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx b/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx index 96274a5a30b..3812960753c 100644 --- a/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx @@ -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) {
{!activeDatasourceOnly && ( -
+