main.test.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { thunkTester } from 'test/core/thunk/thunkTester';
  2. import { ExploreUrlState } from '@grafana/data';
  3. import { serializeStateToUrlParam } from '@grafana/data/src/utils/url';
  4. import { locationService } from '@grafana/runtime';
  5. import { PanelModel } from 'app/features/dashboard/state';
  6. import { reducerTester } from '../../../../test/core/redux/reducerTester';
  7. import { MockDataSourceApi } from '../../../../test/mocks/datasource_srv';
  8. import { ExploreId, ExploreItemState, ExploreState } from '../../../types';
  9. import { exploreReducer, navigateToExplore, splitCloseAction } from './main';
  10. const getNavigateToExploreContext = async (openInNewWindow?: (url: string) => void) => {
  11. const url = '/explore';
  12. const panel: Partial<PanelModel> = {
  13. datasource: { uid: 'mocked datasource' },
  14. targets: [{ refId: 'A' }],
  15. };
  16. const datasource = new MockDataSourceApi(panel.datasource!.uid!);
  17. const get = jest.fn().mockResolvedValue(datasource);
  18. const getDataSourceSrv = jest.fn().mockReturnValue({ get });
  19. const getTimeSrv = jest.fn();
  20. const getExploreUrl = jest.fn().mockResolvedValue(url);
  21. const dispatchedActions = await thunkTester({})
  22. .givenThunk(navigateToExplore)
  23. .whenThunkIsDispatched(panel, { getDataSourceSrv, getTimeSrv, getExploreUrl, openInNewWindow });
  24. return {
  25. url,
  26. panel,
  27. get,
  28. getDataSourceSrv,
  29. getTimeSrv,
  30. getExploreUrl,
  31. dispatchedActions,
  32. };
  33. };
  34. describe('navigateToExplore', () => {
  35. describe('when navigateToExplore thunk is dispatched', () => {
  36. describe('and openInNewWindow is undefined', () => {
  37. const openInNewWindow: (url: string) => void = undefined as unknown as (url: string) => void;
  38. it('then it should dispatch correct actions', async () => {
  39. const { url } = await getNavigateToExploreContext(openInNewWindow);
  40. expect(locationService.getLocation().pathname).toEqual(url);
  41. });
  42. it('then getDataSourceSrv should have been once', async () => {
  43. const { getDataSourceSrv } = await getNavigateToExploreContext(openInNewWindow);
  44. expect(getDataSourceSrv).toHaveBeenCalledTimes(1);
  45. });
  46. it('then getTimeSrv should have been called once', async () => {
  47. const { getTimeSrv } = await getNavigateToExploreContext(openInNewWindow);
  48. expect(getTimeSrv).toHaveBeenCalledTimes(1);
  49. });
  50. it('then getExploreUrl should have been called with correct arguments', async () => {
  51. const { getExploreUrl, panel, getDataSourceSrv, getTimeSrv } = await getNavigateToExploreContext(
  52. openInNewWindow
  53. );
  54. expect(getExploreUrl).toHaveBeenCalledTimes(1);
  55. expect(getExploreUrl).toHaveBeenCalledWith({
  56. panel,
  57. datasourceSrv: getDataSourceSrv(),
  58. timeSrv: getTimeSrv(),
  59. });
  60. });
  61. });
  62. describe('and openInNewWindow is defined', () => {
  63. const openInNewWindow: (url: string) => void = jest.fn();
  64. it('then it should dispatch no actions', async () => {
  65. const { dispatchedActions } = await getNavigateToExploreContext(openInNewWindow);
  66. expect(dispatchedActions).toEqual([]);
  67. });
  68. it('then getDataSourceSrv should have been once', async () => {
  69. const { getDataSourceSrv } = await getNavigateToExploreContext(openInNewWindow);
  70. expect(getDataSourceSrv).toHaveBeenCalledTimes(1);
  71. });
  72. it('then getTimeSrv should have been called once', async () => {
  73. const { getTimeSrv } = await getNavigateToExploreContext(openInNewWindow);
  74. expect(getTimeSrv).toHaveBeenCalledTimes(1);
  75. });
  76. it('then getExploreUrl should have been called with correct arguments', async () => {
  77. const { getExploreUrl, panel, getDataSourceSrv, getTimeSrv } = await getNavigateToExploreContext(
  78. openInNewWindow
  79. );
  80. expect(getExploreUrl).toHaveBeenCalledTimes(1);
  81. expect(getExploreUrl).toHaveBeenCalledWith({
  82. panel,
  83. datasourceSrv: getDataSourceSrv(),
  84. timeSrv: getTimeSrv(),
  85. });
  86. });
  87. it('then openInNewWindow should have been called with correct arguments', async () => {
  88. const openInNewWindowFunc = jest.fn();
  89. const { url } = await getNavigateToExploreContext(openInNewWindowFunc);
  90. expect(openInNewWindowFunc).toHaveBeenCalledTimes(1);
  91. expect(openInNewWindowFunc).toHaveBeenCalledWith(url);
  92. });
  93. });
  94. });
  95. });
  96. describe('Explore reducer', () => {
  97. describe('split view', () => {
  98. describe('split close', () => {
  99. it('should keep right pane as left when left is closed', () => {
  100. const leftItemMock = {
  101. containerWidth: 100,
  102. } as unknown as ExploreItemState;
  103. const rightItemMock = {
  104. containerWidth: 200,
  105. } as unknown as ExploreItemState;
  106. const initialState = {
  107. left: leftItemMock,
  108. right: rightItemMock,
  109. } as unknown as ExploreState;
  110. // closing left item
  111. reducerTester<ExploreState>()
  112. .givenReducer(exploreReducer, initialState)
  113. .whenActionIsDispatched(splitCloseAction({ itemId: ExploreId.left }))
  114. .thenStateShouldEqual({
  115. left: rightItemMock,
  116. right: undefined,
  117. } as unknown as ExploreState);
  118. });
  119. it('should reset right pane when it is closed ', () => {
  120. const leftItemMock = {
  121. containerWidth: 100,
  122. } as unknown as ExploreItemState;
  123. const rightItemMock = {
  124. containerWidth: 200,
  125. } as unknown as ExploreItemState;
  126. const initialState = {
  127. left: leftItemMock,
  128. right: rightItemMock,
  129. } as unknown as ExploreState;
  130. // closing left item
  131. reducerTester<ExploreState>()
  132. .givenReducer(exploreReducer, initialState)
  133. .whenActionIsDispatched(splitCloseAction({ itemId: ExploreId.right }))
  134. .thenStateShouldEqual({
  135. left: leftItemMock,
  136. right: undefined,
  137. } as unknown as ExploreState);
  138. });
  139. });
  140. });
  141. });
  142. export const setup = (urlStateOverrides?: any) => {
  143. const urlStateDefaults: ExploreUrlState = {
  144. datasource: 'some-datasource',
  145. queries: [],
  146. range: {
  147. from: '',
  148. to: '',
  149. },
  150. };
  151. const urlState: ExploreUrlState = { ...urlStateDefaults, ...urlStateOverrides };
  152. const serializedUrlState = serializeStateToUrlParam(urlState);
  153. const initialState = {
  154. split: false,
  155. } as unknown as ExploreState;
  156. return {
  157. initialState,
  158. serializedUrlState,
  159. };
  160. };