@@ -21,10 +21,33 @@ import { createDirectAccessDashboardLinkGenerator } from './url_generator';
2121import { hashedItemStore } from '../../kibana_utils/public' ;
2222// eslint-disable-next-line
2323import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock' ;
24- import { esFilters } from '../../data/public' ;
24+ import { esFilters , Filter } from '../../data/public' ;
25+ import { SavedObjectLoader } from '../../saved_objects/public' ;
2526
2627const APP_BASE_PATH : string = 'xyz/app/kibana' ;
2728
29+ const createMockDashboardLoader = (
30+ dashboardToFilters : {
31+ [ dashboardId : string ] : ( ) => Filter [ ] ;
32+ } = { }
33+ ) => {
34+ return {
35+ get : async ( dashboardId : string ) => {
36+ return {
37+ searchSource : {
38+ getField : ( field : string ) => {
39+ if ( field === 'filter' )
40+ return dashboardToFilters [ dashboardId ] ? dashboardToFilters [ dashboardId ] ( ) : [ ] ;
41+ throw new Error (
42+ `createMockDashboardLoader > searchSource > getField > ${ field } is not mocked`
43+ ) ;
44+ } ,
45+ } ,
46+ } ;
47+ } ,
48+ } as SavedObjectLoader ;
49+ } ;
50+
2851describe ( 'dashboard url generator' , ( ) => {
2952 beforeEach ( ( ) => {
3053 // @ts -ignore
@@ -33,15 +56,23 @@ describe('dashboard url generator', () => {
3356
3457 test ( 'creates a link to a saved dashboard' , async ( ) => {
3558 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
36- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : false } )
59+ Promise . resolve ( {
60+ appBasePath : APP_BASE_PATH ,
61+ useHashedUrl : false ,
62+ savedDashboardLoader : createMockDashboardLoader ( ) ,
63+ } )
3764 ) ;
3865 const url = await generator . createUrl ! ( { } ) ;
3966 expect ( url ) . toMatchInlineSnapshot ( `"xyz/app/kibana#/dashboard?_a=()&_g=()"` ) ;
4067 } ) ;
4168
4269 test ( 'creates a link with global time range set up' , async ( ) => {
4370 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
44- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : false } )
71+ Promise . resolve ( {
72+ appBasePath : APP_BASE_PATH ,
73+ useHashedUrl : false ,
74+ savedDashboardLoader : createMockDashboardLoader ( ) ,
75+ } )
4576 ) ;
4677 const url = await generator . createUrl ! ( {
4778 timeRange : { to : 'now' , from : 'now-15m' , mode : 'relative' } ,
@@ -53,7 +84,11 @@ describe('dashboard url generator', () => {
5384
5485 test ( 'creates a link with filters, time range, refresh interval and query to a saved object' , async ( ) => {
5586 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
56- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : false } )
87+ Promise . resolve ( {
88+ appBasePath : APP_BASE_PATH ,
89+ useHashedUrl : false ,
90+ savedDashboardLoader : createMockDashboardLoader ( ) ,
91+ } )
5792 ) ;
5893 const url = await generator . createUrl ! ( {
5994 timeRange : { to : 'now' , from : 'now-15m' , mode : 'relative' } ,
@@ -89,7 +124,11 @@ describe('dashboard url generator', () => {
89124
90125 test ( 'if no useHash setting is given, uses the one was start services' , async ( ) => {
91126 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
92- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : true } )
127+ Promise . resolve ( {
128+ appBasePath : APP_BASE_PATH ,
129+ useHashedUrl : true ,
130+ savedDashboardLoader : createMockDashboardLoader ( ) ,
131+ } )
93132 ) ;
94133 const url = await generator . createUrl ! ( {
95134 timeRange : { to : 'now' , from : 'now-15m' , mode : 'relative' } ,
@@ -99,7 +138,11 @@ describe('dashboard url generator', () => {
99138
100139 test ( 'can override a false useHash ui setting' , async ( ) => {
101140 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
102- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : false } )
141+ Promise . resolve ( {
142+ appBasePath : APP_BASE_PATH ,
143+ useHashedUrl : false ,
144+ savedDashboardLoader : createMockDashboardLoader ( ) ,
145+ } )
103146 ) ;
104147 const url = await generator . createUrl ! ( {
105148 timeRange : { to : 'now' , from : 'now-15m' , mode : 'relative' } ,
@@ -110,12 +153,162 @@ describe('dashboard url generator', () => {
110153
111154 test ( 'can override a true useHash ui setting' , async ( ) => {
112155 const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
113- Promise . resolve ( { appBasePath : APP_BASE_PATH , useHashedUrl : true } )
156+ Promise . resolve ( {
157+ appBasePath : APP_BASE_PATH ,
158+ useHashedUrl : true ,
159+ savedDashboardLoader : createMockDashboardLoader ( ) ,
160+ } )
114161 ) ;
115162 const url = await generator . createUrl ! ( {
116163 timeRange : { to : 'now' , from : 'now-15m' , mode : 'relative' } ,
117164 useHash : false ,
118165 } ) ;
119166 expect ( url . indexOf ( 'relative' ) ) . toBeGreaterThan ( 1 ) ;
120167 } ) ;
168+
169+ describe ( 'preserving saved filters' , ( ) => {
170+ const savedFilter1 = {
171+ meta : {
172+ alias : null ,
173+ disabled : false ,
174+ negate : false ,
175+ } ,
176+ query : { query : 'savedfilter1' } ,
177+ } ;
178+
179+ const savedFilter2 = {
180+ meta : {
181+ alias : null ,
182+ disabled : false ,
183+ negate : false ,
184+ } ,
185+ query : { query : 'savedfilter2' } ,
186+ } ;
187+
188+ const appliedFilter = {
189+ meta : {
190+ alias : null ,
191+ disabled : false ,
192+ negate : false ,
193+ } ,
194+ query : { query : 'appliedfilter' } ,
195+ } ;
196+
197+ test ( 'attaches filters from destination dashboard' , async ( ) => {
198+ const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
199+ Promise . resolve ( {
200+ appBasePath : APP_BASE_PATH ,
201+ useHashedUrl : false ,
202+ savedDashboardLoader : createMockDashboardLoader ( {
203+ [ 'dashboard1' ] : ( ) => [ savedFilter1 ] ,
204+ [ 'dashboard2' ] : ( ) => [ savedFilter2 ] ,
205+ } ) ,
206+ } )
207+ ) ;
208+
209+ const urlToDashboard1 = await generator . createUrl ! ( {
210+ dashboardId : 'dashboard1' ,
211+ filters : [ appliedFilter ] ,
212+ } ) ;
213+
214+ expect ( urlToDashboard1 ) . toEqual ( expect . stringContaining ( 'query:savedfilter1' ) ) ;
215+ expect ( urlToDashboard1 ) . toEqual ( expect . stringContaining ( 'query:appliedfilter' ) ) ;
216+
217+ const urlToDashboard2 = await generator . createUrl ! ( {
218+ dashboardId : 'dashboard2' ,
219+ filters : [ appliedFilter ] ,
220+ } ) ;
221+
222+ expect ( urlToDashboard2 ) . toEqual ( expect . stringContaining ( 'query:savedfilter2' ) ) ;
223+ expect ( urlToDashboard2 ) . toEqual ( expect . stringContaining ( 'query:appliedfilter' ) ) ;
224+ } ) ;
225+
226+ test ( "doesn't fail if can't retrieve filters from destination dashboard" , async ( ) => {
227+ const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
228+ Promise . resolve ( {
229+ appBasePath : APP_BASE_PATH ,
230+ useHashedUrl : false ,
231+ savedDashboardLoader : createMockDashboardLoader ( {
232+ [ 'dashboard1' ] : ( ) => {
233+ throw new Error ( 'Not found' ) ;
234+ } ,
235+ } ) ,
236+ } )
237+ ) ;
238+
239+ const url = await generator . createUrl ! ( {
240+ dashboardId : 'dashboard1' ,
241+ filters : [ appliedFilter ] ,
242+ } ) ;
243+
244+ expect ( url ) . not . toEqual ( expect . stringContaining ( 'query:savedfilter1' ) ) ;
245+ expect ( url ) . toEqual ( expect . stringContaining ( 'query:appliedfilter' ) ) ;
246+ } ) ;
247+
248+ test ( 'can enforce empty filters' , async ( ) => {
249+ const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
250+ Promise . resolve ( {
251+ appBasePath : APP_BASE_PATH ,
252+ useHashedUrl : false ,
253+ savedDashboardLoader : createMockDashboardLoader ( {
254+ [ 'dashboard1' ] : ( ) => [ savedFilter1 ] ,
255+ } ) ,
256+ } )
257+ ) ;
258+
259+ const url = await generator . createUrl ! ( {
260+ dashboardId : 'dashboard1' ,
261+ filters : [ ] ,
262+ preserveSavedFilters : false ,
263+ } ) ;
264+
265+ expect ( url ) . not . toEqual ( expect . stringContaining ( 'query:savedfilter1' ) ) ;
266+ expect ( url ) . not . toEqual ( expect . stringContaining ( 'query:appliedfilter' ) ) ;
267+ expect ( url ) . toMatchInlineSnapshot (
268+ `"xyz/app/kibana#/dashboard/dashboard1?_a=(filters:!())&_g=(filters:!())"`
269+ ) ;
270+ } ) ;
271+
272+ test ( 'no filters in result url if no filters applied' , async ( ) => {
273+ const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
274+ Promise . resolve ( {
275+ appBasePath : APP_BASE_PATH ,
276+ useHashedUrl : false ,
277+ savedDashboardLoader : createMockDashboardLoader ( {
278+ [ 'dashboard1' ] : ( ) => [ savedFilter1 ] ,
279+ } ) ,
280+ } )
281+ ) ;
282+
283+ const url = await generator . createUrl ! ( {
284+ dashboardId : 'dashboard1' ,
285+ } ) ;
286+ expect ( url ) . not . toEqual ( expect . stringContaining ( 'filters' ) ) ;
287+ expect ( url ) . toMatchInlineSnapshot ( `"xyz/app/kibana#/dashboard/dashboard1?_a=()&_g=()"` ) ;
288+ } ) ;
289+
290+ test ( 'can turn off preserving filters' , async ( ) => {
291+ const generator = createDirectAccessDashboardLinkGenerator ( ( ) =>
292+ Promise . resolve ( {
293+ appBasePath : APP_BASE_PATH ,
294+ useHashedUrl : false ,
295+ savedDashboardLoader : createMockDashboardLoader ( {
296+ [ 'dashboard1' ] : ( ) => [ savedFilter1 ] ,
297+ } ) ,
298+ } )
299+ ) ;
300+ const urlWithPreservedFiltersTurnedOff = await generator . createUrl ! ( {
301+ dashboardId : 'dashboard1' ,
302+ filters : [ appliedFilter ] ,
303+ preserveSavedFilters : false ,
304+ } ) ;
305+
306+ expect ( urlWithPreservedFiltersTurnedOff ) . not . toEqual (
307+ expect . stringContaining ( 'query:savedfilter1' )
308+ ) ;
309+ expect ( urlWithPreservedFiltersTurnedOff ) . toEqual (
310+ expect . stringContaining ( 'query:appliedfilter' )
311+ ) ;
312+ } ) ;
313+ } ) ;
121314} ) ;
0 commit comments