@ -9,9 +9,11 @@ import {
deleteQueryInRichHistory ,
filterAndSortQueries ,
SortOrder ,
MAX_HISTORY_ITEMS ,
} from './richHistory' ;
import store from 'app/core/store' ;
import { dateTime , DataQuery } from '@grafana/data' ;
import { RichHistoryQuery } from '../../types' ;
const mock : any = {
storedHistory : [
@ -41,177 +43,235 @@ const mock: any = {
const key = 'grafana.explore.richHistory' ;
describe ( 'addToR ichHistory' , ( ) = > {
describe ( 'r ichHistory' , ( ) = > {
beforeEach ( ( ) = > {
deleteAllFromRichHistory ( ) ;
expect ( store . exists ( key ) ) . toBeFalsy ( ) ;
jest . useFakeTimers ( 'modern' ) ;
jest . setSystemTime ( new Date ( 1970 , 0 , 1 ) ) ;
} ) ;
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 ) ;
afterEach ( ( ) = > {
jest . useRealTimers ( ) ;
} ) ;
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 ) ;
} ) ;
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 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 append query to query history' , ( ) = > {
Date . now = jest . fn ( ( ) = > 2 ) ;
const { richHistory : newHistory } = addToRichHistory (
mock . storedHistory ,
mock . testDatasourceId ,
mock . testDatasourceName ,
mock . testQueries ,
mock . testStarred ,
mock . testComment ,
mock . testSessionName ,
true ,
true
) ;
expect ( newHistory ) . toEqual ( expectedResult ) ;
} ) ;
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 ( ) ;
} ) ;
} ) ;
it ( 'should save query history to localStorage' , ( ) = > {
Date . now = jest . fn ( ( ) = > 2 ) ;
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 ) ;
} ) ;
} ) ;
addToRichHistory (
mock . storedHistory ,
mock . testDatasourceId ,
mock . testDatasourceName ,
mock . testQueries ,
mock . testStarred ,
mock . testComment ,
mock . testSessionName ,
true ,
true
) ;
expect ( store . exists ( key ) ) . toBeTruthy ( ) ;
expect ( store . getObject ( key ) ) . toMatchObject ( expectedResult ) ;
} ) ;
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' ) ;
} ) ;
} ) ;
it ( 'should not append duplicated query to query history' , ( ) = > {
Date . now = jest . fn ( ( ) = > 2 ) ;
const { richHistory : 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 ,
true ,
true
) ;
expect ( newHistory ) . toEqual ( [ mock . storedHistory [ 0 ] ] ) ;
} ) ;
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 ( [ ] ) ;
} ) ;
} ) ;
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 ,
true ,
true
) ;
expect ( store . exists ( key ) ) . toBeFalsy ( ) ;
} ) ;
it ( 'should not save more than MAX_HISTORY_ITEMS' , ( ) = > {
Date . now = jest . fn ( ( ) = > 2 ) ;
const extraItems = 100 ;
// the history has more than MAX
let history = [ ] ;
// history = [ { starred: true, comment: "0" }, { starred: false, comment: "1" }, ... ]
for ( let i = 0 ; i < MAX_HISTORY_ITEMS + extraItems ; i ++ ) {
history . push ( {
starred : i % 2 === 0 ,
comment : i.toString ( ) ,
queries : [ ] ,
ts : new Date ( 2019 , 11 , 31 ) . getTime ( ) ,
} ) ;
}
const starredItemsInHistory = ( MAX_HISTORY_ITEMS + extraItems ) / 2 ;
const notStarredItemsInHistory = ( MAX_HISTORY_ITEMS + extraItems ) / 2 ;
describe ( 'mapNumbertoTimeInSlider' , ( ) = > {
it ( 'should correctly map number to value' , ( ) = > {
const value = mapNumbertoTimeInSlider ( 25 ) ;
expect ( value ) . toEqual ( '25 days ago' ) ;
expect ( history . filter ( ( h ) = > h . starred ) ) . toHaveLength ( starredItemsInHistory ) ;
expect ( history . filter ( ( h ) = > ! h . starred ) ) . toHaveLength ( notStarredItemsInHistory ) ;
const { richHistory : newHistory } = addToRichHistory (
( history as any ) as RichHistoryQuery [ ] ,
mock . storedHistory [ 0 ] . datasourceId ,
mock . storedHistory [ 0 ] . datasourceName ,
[ { expr : 'query1' , maxLines : null , refId : 'A' } as DataQuery , { expr : 'query2' , refId : 'B' } as DataQuery ] ,
true ,
mock . testComment ,
mock . testSessionName ,
true ,
true
) ;
// one not starred replaced with a newly added starred item
const removedNotStarredItems = extraItems + 1 ; // + 1 to make space for the new item
expect ( newHistory . filter ( ( h ) = > h . starred ) ) . toHaveLength ( starredItemsInHistory + 1 ) ; // starred item added
expect ( newHistory . filter ( ( h ) = > ! h . starred ) ) . toHaveLength ( starredItemsInHistory - removedNotStarredItems ) ;
} ) ;
} ) ;
} ) ;
describe ( 'createDateStringFromTs' , ( ) = > {
it ( 'should correctly create string value from timestamp' , ( ) = > {
const value = createDateStringFromTs ( 1583932327000 ) ;
expect ( value ) . toEqual ( 'March 11' ) ;
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 ( '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 ) ;
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' ) ;
} ) ;
} ) ;
it ( 'should keep queries based on data source filter' , ( ) = > {
const filteredQueries = filterAndSortQueries (
mock . storedHistory ,
SortOrder . Ascending ,
[ 'datasource history name' ] ,
''
) ;
expect ( filteredQueries ) . toHaveLength ( 1 ) ;
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 ( [ ] ) ;
} ) ;
} ) ;
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 ) ;
describe ( 'mapNumbertoTimeInSlider' , ( ) = > {
it ( 'should correctly map number to value' , ( ) = > {
const value = mapNumbertoTimeInSlider ( 25 ) ;
expect ( value ) . toEqual ( '25 days ago' ) ;
} ) ;
} ) ;
it ( 'should include queries based on search filter' , ( ) = > {
const filteredQueries = filterAndSortQueries ( mock . storedHistory , SortOrder . Ascending , [ ] , 'query1' ) ;
expect ( filteredQueries ) . toHaveLength ( 1 ) ;
describe ( 'createDateStringFromTs' , ( ) = > {
it ( 'should correctly create string value from timestamp' , ( ) = > {
const value = createDateStringFromTs ( 1583932327000 ) ;
expect ( value ) . toEqual ( 'March 11' ) ;
} ) ;
} ) ;
} ) ;
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' ) ;
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 ) ;
} ) ;
} ) ;
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 ) ;
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 ) ;
} ) ;
} ) ;
} ) ;