import { addToRichHistory, updateStarredInRichHistory, updateCommentInRichHistory, mapNumbertoTimeInSlider, createDateStringFromTs, createQueryHeading, deleteAllFromRichHistory, deleteQueryInRichHistory, filterAndSortQueries, SortOrder, } from './richHistory'; import store from 'app/core/store'; import { dateTime, DataQuery } from '@grafana/data'; const mock: any = { storedHistory: [ { comment: '', datasourceId: 'datasource historyId', datasourceName: 'datasource history name', queries: [ { expr: 'query1', maxLines: null, refId: '1' }, { expr: 'query2', refId: '2' }, ], sessionName: '', starred: true, ts: 1, }, ], testComment: '', testDatasourceId: 'datasourceId', testDatasourceName: 'datasourceName', testQueries: [ { expr: 'query3', refId: 'B' }, { expr: 'query4', refId: 'C' }, ], testSessionName: '', testStarred: false, }; const key = 'grafana.explore.richHistory'; describe('addToRichHistory', () => { beforeEach(() => { deleteAllFromRichHistory(); expect(store.exists(key)).toBeFalsy(); }); const expectedResult = [ { comment: mock.testComment, datasourceId: mock.testDatasourceId, datasourceName: mock.testDatasourceName, queries: mock.testQueries, sessionName: mock.testSessionName, starred: mock.testStarred, ts: 2, }, mock.storedHistory[0], ]; it('should append query to query history', () => { Date.now = jest.fn(() => 2); const newHistory = addToRichHistory( mock.storedHistory, mock.testDatasourceId, mock.testDatasourceName, mock.testQueries, mock.testStarred, mock.testComment, mock.testSessionName ); expect(newHistory).toEqual(expectedResult); }); it('should save query history to localStorage', () => { Date.now = jest.fn(() => 2); addToRichHistory( mock.storedHistory, mock.testDatasourceId, mock.testDatasourceName, mock.testQueries, mock.testStarred, mock.testComment, mock.testSessionName ); expect(store.exists(key)).toBeTruthy(); expect(store.getObject(key)).toMatchObject(expectedResult); }); it('should not append duplicated query to query history', () => { Date.now = jest.fn(() => 2); const newHistory = addToRichHistory( mock.storedHistory, mock.storedHistory[0].datasourceId, mock.storedHistory[0].datasourceName, [{ expr: 'query1', maxLines: null, refId: 'A' } as DataQuery, { expr: 'query2', refId: 'B' } as DataQuery], mock.testStarred, mock.testComment, mock.testSessionName ); expect(newHistory).toEqual([mock.storedHistory[0]]); }); it('should not save duplicated query to localStorage', () => { Date.now = jest.fn(() => 2); addToRichHistory( mock.storedHistory, mock.storedHistory[0].datasourceId, mock.storedHistory[0].datasourceName, [{ expr: 'query1', maxLines: null, refId: 'A' } as DataQuery, { expr: 'query2', refId: 'B' } as DataQuery], mock.testStarred, mock.testComment, mock.testSessionName ); expect(store.exists(key)).toBeFalsy(); }); }); describe('updateStarredInRichHistory', () => { it('should update starred in query in history', () => { const updatedStarred = updateStarredInRichHistory(mock.storedHistory, 1); expect(updatedStarred[0].starred).toEqual(false); }); it('should update starred in localStorage', () => { updateStarredInRichHistory(mock.storedHistory, 1); expect(store.exists(key)).toBeTruthy(); expect(store.getObject(key)[0].starred).toEqual(false); }); }); describe('updateCommentInRichHistory', () => { it('should update comment in query in history', () => { const updatedComment = updateCommentInRichHistory(mock.storedHistory, 1, 'new comment'); expect(updatedComment[0].comment).toEqual('new comment'); }); it('should update comment in localStorage', () => { updateCommentInRichHistory(mock.storedHistory, 1, 'new comment'); expect(store.exists(key)).toBeTruthy(); expect(store.getObject(key)[0].comment).toEqual('new comment'); }); }); describe('deleteQueryInRichHistory', () => { it('should delete query in query in history', () => { const deletedHistory = deleteQueryInRichHistory(mock.storedHistory, 1); expect(deletedHistory).toEqual([]); }); it('should delete query in localStorage', () => { deleteQueryInRichHistory(mock.storedHistory, 1); expect(store.exists(key)).toBeTruthy(); expect(store.getObject(key)).toEqual([]); }); }); describe('mapNumbertoTimeInSlider', () => { it('should correctly map number to value', () => { const value = mapNumbertoTimeInSlider(25); expect(value).toEqual('25 days ago'); }); }); describe('createDateStringFromTs', () => { it('should correctly create string value from timestamp', () => { const value = createDateStringFromTs(1583932327000); expect(value).toEqual('March 11'); }); }); describe('filterQueries', () => { it('should filter out queries based on data source filter', () => { const filteredQueries = filterAndSortQueries( mock.storedHistory, SortOrder.Ascending, ['not provided data source'], '' ); expect(filteredQueries).toHaveLength(0); }); it('should keep queries based on data source filter', () => { const filteredQueries = filterAndSortQueries( mock.storedHistory, SortOrder.Ascending, ['datasource history name'], '' ); expect(filteredQueries).toHaveLength(1); }); it('should filter out all queries based on search filter', () => { const filteredQueries = filterAndSortQueries( mock.storedHistory, SortOrder.Ascending, [], 'i do not exist in query' ); expect(filteredQueries).toHaveLength(0); }); it('should include queries based on search filter', () => { const filteredQueries = filterAndSortQueries(mock.storedHistory, SortOrder.Ascending, [], 'query1'); expect(filteredQueries).toHaveLength(1); }); }); describe('createQueryHeading', () => { it('should correctly create heading for queries when sort order is ascending ', () => { // Have to offset the timezone of a 1 microsecond epoch, and then reverse the changes mock.storedHistory[0].ts = 1 + -1 * dateTime().utcOffset() * 60 * 1000; const heading = createQueryHeading(mock.storedHistory[0], SortOrder.Ascending); expect(heading).toEqual('January 1'); }); it('should correctly create heading for queries when sort order is datasourceAZ ', () => { const heading = createQueryHeading(mock.storedHistory[0], SortOrder.DatasourceAZ); expect(heading).toEqual(mock.storedHistory[0].datasourceName); }); });