reducers.test.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. import { itemReducer, makeExploreItemState, exploreReducer, makeInitialUpdateState } from './reducers';
  2. import { ExploreId, ExploreItemState, ExploreUrlState } from 'app/types/explore';
  3. import { reducerTester } from 'test/core/redux/reducerTester';
  4. import { scanStartAction, scanStopAction } from './actionTypes';
  5. import { Reducer } from 'redux';
  6. import { ActionOf } from 'app/core/redux/actionCreatorFactory';
  7. import { updateLocation } from 'app/core/actions/location';
  8. import { LogsDedupStrategy } from 'app/core/logs_model';
  9. import { serializeStateToUrlParam } from 'app/core/utils/explore';
  10. describe('Explore item reducer', () => {
  11. describe('scanning', () => {
  12. test('should start scanning', () => {
  13. const scanner = jest.fn();
  14. const initalState = {
  15. ...makeExploreItemState(),
  16. scanning: false,
  17. scanner: undefined,
  18. };
  19. reducerTester()
  20. .givenReducer(itemReducer as Reducer<ExploreItemState, ActionOf<any>>, initalState)
  21. .whenActionIsDispatched(scanStartAction({ exploreId: ExploreId.left, scanner }))
  22. .thenStateShouldEqual({
  23. ...makeExploreItemState(),
  24. scanning: true,
  25. scanner,
  26. });
  27. });
  28. test('should stop scanning', () => {
  29. const scanner = jest.fn();
  30. const initalState = {
  31. ...makeExploreItemState(),
  32. scanning: true,
  33. scanner,
  34. scanRange: {},
  35. };
  36. reducerTester()
  37. .givenReducer(itemReducer as Reducer<ExploreItemState, ActionOf<any>>, initalState)
  38. .whenActionIsDispatched(scanStopAction({ exploreId: ExploreId.left }))
  39. .thenStateShouldEqual({
  40. ...makeExploreItemState(),
  41. scanning: false,
  42. scanner: undefined,
  43. scanRange: undefined,
  44. });
  45. });
  46. });
  47. });
  48. export const setup = (urlStateOverrides?: any) => {
  49. const update = makeInitialUpdateState();
  50. const urlStateDefaults: ExploreUrlState = {
  51. datasource: 'some-datasource',
  52. queries: [],
  53. range: {
  54. from: '',
  55. to: '',
  56. },
  57. ui: {
  58. dedupStrategy: LogsDedupStrategy.none,
  59. showingGraph: false,
  60. showingTable: false,
  61. showingLogs: false,
  62. },
  63. };
  64. const urlState: ExploreUrlState = { ...urlStateDefaults, ...urlStateOverrides };
  65. const serializedUrlState = serializeStateToUrlParam(urlState);
  66. const initalState = { split: false, left: { urlState, update }, right: { urlState, update } };
  67. return {
  68. initalState,
  69. serializedUrlState,
  70. };
  71. };
  72. describe('Explore reducer', () => {
  73. describe('when updateLocation is dispatched', () => {
  74. describe('and payload does not contain a query', () => {
  75. it('then it should just return state', () => {
  76. reducerTester()
  77. .givenReducer(exploreReducer, {})
  78. .whenActionIsDispatched(updateLocation({ query: null }))
  79. .thenStateShouldEqual({});
  80. });
  81. });
  82. describe('and payload contains a query', () => {
  83. describe("but does not contain 'left'", () => {
  84. it('then it should just return state', () => {
  85. reducerTester()
  86. .givenReducer(exploreReducer, {})
  87. .whenActionIsDispatched(updateLocation({ query: {} }))
  88. .thenStateShouldEqual({});
  89. });
  90. });
  91. describe("and query contains a 'right'", () => {
  92. it('then it should add split in state', () => {
  93. const { initalState, serializedUrlState } = setup();
  94. const expectedState = { ...initalState, split: true };
  95. reducerTester()
  96. .givenReducer(exploreReducer, initalState)
  97. .whenActionIsDispatched(
  98. updateLocation({
  99. query: {
  100. left: serializedUrlState,
  101. right: serializedUrlState,
  102. },
  103. })
  104. )
  105. .thenStateShouldEqual(expectedState);
  106. });
  107. });
  108. describe("and query contains a 'left'", () => {
  109. describe('but urlState is not set in state', () => {
  110. it('then it should just add urlState and update in state', () => {
  111. const { initalState, serializedUrlState } = setup();
  112. const stateWithoutUrlState = { ...initalState, left: { urlState: null } };
  113. const expectedState = { ...initalState };
  114. reducerTester()
  115. .givenReducer(exploreReducer, stateWithoutUrlState)
  116. .whenActionIsDispatched(
  117. updateLocation({
  118. query: {
  119. left: serializedUrlState,
  120. },
  121. path: '/explore',
  122. })
  123. )
  124. .thenStateShouldEqual(expectedState);
  125. });
  126. });
  127. describe("but '/explore' is missing in path", () => {
  128. it('then it should just add urlState and update in state', () => {
  129. const { initalState, serializedUrlState } = setup();
  130. const expectedState = { ...initalState };
  131. reducerTester()
  132. .givenReducer(exploreReducer, initalState)
  133. .whenActionIsDispatched(
  134. updateLocation({
  135. query: {
  136. left: serializedUrlState,
  137. },
  138. path: '/dashboard',
  139. })
  140. )
  141. .thenStateShouldEqual(expectedState);
  142. });
  143. });
  144. describe("and '/explore' is in path", () => {
  145. describe('and datasource differs', () => {
  146. it('then it should return update datasource', () => {
  147. const { initalState, serializedUrlState } = setup();
  148. const expectedState = {
  149. ...initalState,
  150. left: {
  151. ...initalState.left,
  152. update: {
  153. ...initalState.left.update,
  154. datasource: true,
  155. },
  156. },
  157. };
  158. const stateWithDifferentDataSource = {
  159. ...initalState,
  160. left: {
  161. ...initalState.left,
  162. urlState: {
  163. ...initalState.left.urlState,
  164. datasource: 'different datasource',
  165. },
  166. },
  167. };
  168. reducerTester()
  169. .givenReducer(exploreReducer, stateWithDifferentDataSource)
  170. .whenActionIsDispatched(
  171. updateLocation({
  172. query: {
  173. left: serializedUrlState,
  174. },
  175. path: '/explore',
  176. })
  177. )
  178. .thenStateShouldEqual(expectedState);
  179. });
  180. });
  181. describe('and range differs', () => {
  182. it('then it should return update range', () => {
  183. const { initalState, serializedUrlState } = setup();
  184. const expectedState = {
  185. ...initalState,
  186. left: {
  187. ...initalState.left,
  188. update: {
  189. ...initalState.left.update,
  190. range: true,
  191. },
  192. },
  193. };
  194. const stateWithDifferentDataSource = {
  195. ...initalState,
  196. left: {
  197. ...initalState.left,
  198. urlState: {
  199. ...initalState.left.urlState,
  200. range: {
  201. from: 'now',
  202. to: 'now-6h',
  203. },
  204. },
  205. },
  206. };
  207. reducerTester()
  208. .givenReducer(exploreReducer, stateWithDifferentDataSource)
  209. .whenActionIsDispatched(
  210. updateLocation({
  211. query: {
  212. left: serializedUrlState,
  213. },
  214. path: '/explore',
  215. })
  216. )
  217. .thenStateShouldEqual(expectedState);
  218. });
  219. });
  220. describe('and queries differs', () => {
  221. it('then it should return update queries', () => {
  222. const { initalState, serializedUrlState } = setup();
  223. const expectedState = {
  224. ...initalState,
  225. left: {
  226. ...initalState.left,
  227. update: {
  228. ...initalState.left.update,
  229. queries: true,
  230. },
  231. },
  232. };
  233. const stateWithDifferentDataSource = {
  234. ...initalState,
  235. left: {
  236. ...initalState.left,
  237. urlState: {
  238. ...initalState.left.urlState,
  239. queries: [{ expr: '{__filename__="some.log"}' }],
  240. },
  241. },
  242. };
  243. reducerTester()
  244. .givenReducer(exploreReducer, stateWithDifferentDataSource)
  245. .whenActionIsDispatched(
  246. updateLocation({
  247. query: {
  248. left: serializedUrlState,
  249. },
  250. path: '/explore',
  251. })
  252. )
  253. .thenStateShouldEqual(expectedState);
  254. });
  255. });
  256. describe('and ui differs', () => {
  257. it('then it should return update ui', () => {
  258. const { initalState, serializedUrlState } = setup();
  259. const expectedState = {
  260. ...initalState,
  261. left: {
  262. ...initalState.left,
  263. update: {
  264. ...initalState.left.update,
  265. ui: true,
  266. },
  267. },
  268. };
  269. const stateWithDifferentDataSource = {
  270. ...initalState,
  271. left: {
  272. ...initalState.left,
  273. urlState: {
  274. ...initalState.left.urlState,
  275. ui: {
  276. ...initalState.left.urlState.ui,
  277. showingGraph: true,
  278. },
  279. },
  280. },
  281. };
  282. reducerTester()
  283. .givenReducer(exploreReducer, stateWithDifferentDataSource)
  284. .whenActionIsDispatched(
  285. updateLocation({
  286. query: {
  287. left: serializedUrlState,
  288. },
  289. path: '/explore',
  290. })
  291. )
  292. .thenStateShouldEqual(expectedState);
  293. });
  294. });
  295. describe('and nothing differs', () => {
  296. fit('then it should return update ui', () => {
  297. const { initalState, serializedUrlState } = setup();
  298. const expectedState = { ...initalState };
  299. reducerTester()
  300. .givenReducer(exploreReducer, initalState)
  301. .whenActionIsDispatched(
  302. updateLocation({
  303. query: {
  304. left: serializedUrlState,
  305. },
  306. path: '/explore',
  307. })
  308. )
  309. .thenStateShouldEqual(expectedState);
  310. });
  311. });
  312. });
  313. });
  314. });
  315. });
  316. });