useWidgetBuilderState.spec.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import {LocationFixture} from 'sentry-fixture/locationFixture';
  2. import {act, renderHook} from 'sentry-test/reactTestingLibrary';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. import {useNavigate} from 'sentry/utils/useNavigate';
  5. import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
  6. import useWidgetBuilderState, {
  7. BuilderStateAction,
  8. } from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState';
  9. jest.mock('sentry/utils/useLocation');
  10. jest.mock('sentry/utils/useNavigate');
  11. const mockedUsedLocation = jest.mocked(useLocation);
  12. const mockedUseNavigate = jest.mocked(useNavigate);
  13. describe('useWidgetBuilderState', () => {
  14. beforeEach(() => {
  15. jest.useFakeTimers();
  16. });
  17. afterEach(() => {
  18. jest.useRealTimers();
  19. jest.clearAllMocks();
  20. });
  21. it('returns the widget builder state from the query params', () => {
  22. mockedUsedLocation.mockReturnValue(
  23. LocationFixture({
  24. query: {
  25. title: 'test',
  26. description: 'lalala this is a description',
  27. },
  28. })
  29. );
  30. const {result} = renderHook(() => useWidgetBuilderState());
  31. expect(result.current.state.title).toBe('test');
  32. expect(result.current.state.description).toBe('lalala this is a description');
  33. });
  34. it('sets the new title and description in the query params', () => {
  35. const mockNavigate = jest.fn();
  36. mockedUseNavigate.mockReturnValue(mockNavigate);
  37. const {result} = renderHook(() => useWidgetBuilderState());
  38. act(() => {
  39. result.current.dispatch({
  40. type: BuilderStateAction.SET_TITLE,
  41. payload: 'new title',
  42. });
  43. });
  44. act(() => {
  45. result.current.dispatch({
  46. type: BuilderStateAction.SET_DESCRIPTION,
  47. payload: 'new description',
  48. });
  49. });
  50. jest.runAllTimers();
  51. expect(mockNavigate).toHaveBeenCalledWith(
  52. expect.objectContaining({query: expect.objectContaining({title: 'new title'})})
  53. );
  54. expect(mockNavigate).toHaveBeenCalledWith(
  55. expect.objectContaining({
  56. query: expect.objectContaining({description: 'new description'}),
  57. })
  58. );
  59. });
  60. describe('display type', () => {
  61. it('returns the display type from the query params', () => {
  62. mockedUsedLocation.mockReturnValue(
  63. LocationFixture({
  64. query: {displayType: DisplayType.AREA},
  65. })
  66. );
  67. const {result} = renderHook(() => useWidgetBuilderState());
  68. expect(result.current.state.displayType).toBe(DisplayType.AREA);
  69. });
  70. it('returns a default display type from the query params when the display type is not valid', () => {
  71. mockedUsedLocation.mockReturnValue(
  72. LocationFixture({
  73. query: {displayType: 'invalid'},
  74. })
  75. );
  76. const {result} = renderHook(() => useWidgetBuilderState());
  77. expect(result.current.state.displayType).toBe(DisplayType.TABLE);
  78. });
  79. it('sets the display type in the query params', () => {
  80. const mockNavigate = jest.fn();
  81. mockedUseNavigate.mockReturnValue(mockNavigate);
  82. const {result} = renderHook(() => useWidgetBuilderState());
  83. act(() => {
  84. result.current.dispatch({
  85. type: BuilderStateAction.SET_DISPLAY_TYPE,
  86. payload: DisplayType.AREA,
  87. });
  88. });
  89. jest.runAllTimers();
  90. expect(mockNavigate).toHaveBeenCalledWith(
  91. expect.objectContaining({
  92. query: expect.objectContaining({displayType: DisplayType.AREA}),
  93. })
  94. );
  95. });
  96. });
  97. describe('dataset', () => {
  98. it('returns the dataset from the query params', () => {
  99. mockedUsedLocation.mockReturnValue(
  100. LocationFixture({query: {dataset: WidgetType.ISSUE}})
  101. );
  102. const {result} = renderHook(() => useWidgetBuilderState());
  103. expect(result.current.state.dataset).toBe(WidgetType.ISSUE);
  104. });
  105. it('sets the dataset in the query params', () => {
  106. const mockNavigate = jest.fn();
  107. mockedUseNavigate.mockReturnValue(mockNavigate);
  108. const {result} = renderHook(() => useWidgetBuilderState());
  109. act(() => {
  110. result.current.dispatch({
  111. type: BuilderStateAction.SET_DATASET,
  112. payload: WidgetType.METRICS,
  113. });
  114. });
  115. jest.runAllTimers();
  116. expect(mockNavigate).toHaveBeenCalledWith(
  117. expect.objectContaining({
  118. query: expect.objectContaining({dataset: WidgetType.METRICS}),
  119. })
  120. );
  121. });
  122. it('returns errors as the default dataset', () => {
  123. mockedUsedLocation.mockReturnValue(LocationFixture({query: {dataset: 'invalid'}}));
  124. const {result} = renderHook(() => useWidgetBuilderState());
  125. expect(result.current.state.dataset).toBe(WidgetType.ERRORS);
  126. });
  127. });
  128. describe('fields', () => {
  129. it('returns the fields from the query params', () => {
  130. mockedUsedLocation.mockReturnValue(
  131. LocationFixture({query: {field: ['event.type', 'potato', 'count()']}})
  132. );
  133. const {result} = renderHook(() => useWidgetBuilderState());
  134. expect(result.current.state.fields).toEqual([
  135. {field: 'event.type', alias: undefined, kind: 'field'},
  136. {field: 'potato', alias: undefined, kind: 'field'},
  137. {
  138. alias: undefined,
  139. kind: 'function',
  140. function: ['count', '', undefined, undefined],
  141. },
  142. ]);
  143. });
  144. });
  145. describe('yAxis', () => {
  146. it('does not conflict with fields when setting the state', () => {
  147. mockedUsedLocation.mockReturnValue(
  148. LocationFixture({
  149. query: {
  150. field: ['event.type', 'potato', 'count()'],
  151. yAxis: ['count()', 'count_unique(user)'],
  152. },
  153. })
  154. );
  155. const {result} = renderHook(() => useWidgetBuilderState());
  156. expect(result.current.state.fields).toEqual([
  157. {field: 'event.type', alias: undefined, kind: 'field'},
  158. {field: 'potato', alias: undefined, kind: 'field'},
  159. {
  160. function: ['count', '', undefined, undefined],
  161. alias: undefined,
  162. kind: 'function',
  163. },
  164. ]);
  165. expect(result.current.state.yAxis).toEqual([
  166. {
  167. function: ['count', '', undefined, undefined],
  168. alias: undefined,
  169. kind: 'function',
  170. },
  171. {
  172. function: ['count_unique', 'user', undefined, undefined],
  173. alias: undefined,
  174. kind: 'function',
  175. },
  176. ]);
  177. });
  178. });
  179. });