You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

adsReducer.test.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. import * as redux from "react-redux";
  2. import store from "../../store";
  3. import { Router } from "react-router-dom";
  4. import history from "../../store/utils/history";
  5. import { mockState } from "../../mockState";
  6. import { render } from "@testing-library/react";
  7. import AdsPage from "../../pages/AdsPage/AdsPage";
  8. import * as api from "../../request/adsRequest";
  9. import { runSaga } from "redux-saga";
  10. import { FETCH_ADS_REQ } from "../../store/actions/ads/adsActionConstants";
  11. import ColorModeProvider from "../../context/ColorModeContext";
  12. import * as fc from "../../store/saga/adsSaga";
  13. import { setAds, setFilteredAds } from "../../store/actions/ads/adsAction";
  14. import { setArchiveAds } from "../../store/actions/archiveAds/archiveAdsActions";
  15. import { setCreateAd } from "../../store/actions/createAd/createAdActions";
  16. import { setAd, setAdError } from "../../store/actions/ad/adActions";
  17. import { archiveActiveAd } from "../../store/actions/archiveActiveAd/archiveActiveAdActions";
  18. import * as helper from "../../util/helpers/rejectErrorCodeHelper";
  19. describe("Ads reducer tests", () => {
  20. const cont = (
  21. <redux.Provider store={store}>
  22. <Router history={history}>
  23. <ColorModeProvider>
  24. <AdsPage />
  25. </ColorModeProvider>
  26. </Router>
  27. </redux.Provider>
  28. );
  29. let spyOnUseSelector;
  30. let spyOnUseDispatch;
  31. let mockDispatch;
  32. beforeEach(() => {
  33. spyOnUseSelector = jest.spyOn(redux, "useSelector");
  34. spyOnUseSelector.mockReturnValueOnce(mockState.ads);
  35. spyOnUseDispatch = jest.spyOn(redux, "useDispatch");
  36. mockDispatch = jest.fn();
  37. spyOnUseDispatch.mockReturnValue(mockDispatch);
  38. });
  39. afterEach(() => {
  40. jest.restoreAllMocks();
  41. });
  42. it("Should dispatch get ads request when rendered", () => {
  43. render(cont);
  44. expect(mockDispatch).toHaveBeenCalledWith({
  45. type: FETCH_ADS_REQ,
  46. });
  47. });
  48. it("Should load and handle ads in case of success", async () => {
  49. const dispatchedActions = [];
  50. const mockedCall = { data: mockState.ads.ads };
  51. api.getAllAds = jest.fn(() => Promise.resolve(mockedCall));
  52. const fakeStore = {
  53. getState: () => mockState.ads.ads,
  54. dispatch: (action) => dispatchedActions.push(action),
  55. };
  56. await runSaga(fakeStore, fc.getAds, {}).done;
  57. expect(api.getAllAds.mock.calls.length).toBe(1);
  58. expect(dispatchedActions).toContainEqual(setAds(mockedCall.data));
  59. });
  60. it("Should load and handle filtered ads in case of success", async () => {
  61. const dispatchedActions = [];
  62. const filter = {
  63. minimumExperience: 0,
  64. maximumExperience: 0,
  65. technologies: [1],
  66. workHour: "FullTime",
  67. employmentType: "Work",
  68. };
  69. const filteredData = mockState.ads.ads.filter(
  70. (ad) =>
  71. ad.minimumExperience >= filter.minimumExperience &&
  72. ad.minimumExperience <= filter.maximumExperience &&
  73. ad.workHour === filter.workHour &&
  74. ad.employmentType === filter.employmentType
  75. );
  76. const mockedCall = { data: filteredData };
  77. api.getAllFilteredAds = jest.fn(() => Promise.resolve(mockedCall));
  78. const fakeStore = {
  79. getState: () => mockState.ads.ads,
  80. dispatch: (action) => dispatchedActions.push(action),
  81. };
  82. await runSaga(fakeStore, fc.getFilteredAds, filter).done;
  83. expect(api.getAllFilteredAds.mock.calls.length).toBe(1);
  84. expect(dispatchedActions).toContainEqual(setFilteredAds(mockedCall.data));
  85. });
  86. it("Should load and handle archived ads in case of success", async () => {
  87. const dispatchedActions = [];
  88. const date = new Date();
  89. const filteredData = mockState.ads.ads.filter((ad) => ad.expiredAt < date);
  90. const mockedCall = { data: filteredData };
  91. api.getAllArchiveAds = jest.fn(() => Promise.resolve(mockedCall));
  92. const fakeStore = {
  93. getState: () => mockState.ads.ads,
  94. dispatch: (action) => dispatchedActions.push(action),
  95. };
  96. await runSaga(fakeStore, fc.getArchiveAds, {}).done;
  97. expect(api.getAllArchiveAds.mock.calls.length).toBe(1);
  98. expect(dispatchedActions).toContainEqual(setArchiveAds(mockedCall.data));
  99. });
  100. it("Should load and handle ad by id in case of success", async () => {
  101. const dispatchedActions = [];
  102. const id = 1;
  103. const filteredData = mockState.ads.ads.filter((ad) => ad.id === id);
  104. const mockedCall = { data: filteredData };
  105. api.getAdDetailsById = jest.fn(() => Promise.resolve(mockedCall));
  106. const fakeStore = {
  107. getState: () => mockState.ads.ads,
  108. dispatch: (action) => dispatchedActions.push(action),
  109. };
  110. await runSaga(fakeStore, fc.getAd, { payload: id }).done;
  111. expect(api.getAdDetailsById.mock.calls.length).toBe(1);
  112. expect(dispatchedActions).toContainEqual(setAd(mockedCall.data));
  113. });
  114. it("Should create ad", async () => {
  115. const dispatchedActions = [];
  116. const mockedCall = {
  117. data: {
  118. title: "React Developer",
  119. minimumExperience: 1,
  120. createdAt: new Date(),
  121. expiredAt: new Date("2023-5-5"),
  122. keyResponsibilities: "key responsibilities",
  123. requirements: "requirements",
  124. offer: "offer",
  125. workHour: "PartTime",
  126. employmentType: "Intership",
  127. technologiesIds: [1, 2],
  128. onSuccessAddAd: jest.fn,
  129. },
  130. };
  131. api.createNewAd = jest.fn(() => Promise.resolve(mockedCall));
  132. const fakeStore = {
  133. getState: () => mockState.ads.ads,
  134. dispatch: (action) => dispatchedActions.push(action),
  135. };
  136. await runSaga(fakeStore, fc.createAd, {
  137. payload: {
  138. title: "React Developer",
  139. minimumExperience: 1,
  140. createdAt: new Date(),
  141. expiredAt: new Date("2023-5-5"),
  142. keyResponsibilities: "key responsibilities",
  143. requirements: "requirements",
  144. offer: "offer",
  145. workHour: "PartTime",
  146. employmentType: "Intership",
  147. technologiesIds: [1, 2],
  148. onSuccessAddAd: jest.fn,
  149. },
  150. }).done;
  151. expect(api.createNewAd.mock.calls.length).toBe(1);
  152. expect(dispatchedActions).toContainEqual(setCreateAd(mockedCall.data));
  153. });
  154. it("Archive ad", async () => {
  155. const dispatchedActions = [];
  156. const mockedCall = {
  157. data: {
  158. id: 1,
  159. navigateToAds: jest.fn,
  160. },
  161. };
  162. api.archiveActiveAdRequest = jest.fn(() => Promise.resolve(mockedCall));
  163. const fakeStore = {
  164. getState: () => mockState.ads.ads,
  165. dispatch: (action) => dispatchedActions.push(action),
  166. };
  167. await runSaga(fakeStore, fc.archiveActiveAdSaga, {
  168. payload: {
  169. id: 1,
  170. navigateToAds: jest.fn,
  171. },
  172. }).done;
  173. expect(api.archiveActiveAdRequest.mock.calls.length).toBe(1);
  174. expect(dispatchedActions).toContainEqual(archiveActiveAd(mockedCall.data));
  175. });
  176. it("Should not return ads when exception was thrown", async () => {
  177. const dispatchedActions = [];
  178. const error = {
  179. response: {
  180. data: { message: "Error" },
  181. },
  182. };
  183. api.getAllAds = jest.fn(() => Promise.reject(error));
  184. const mockfn = jest.fn();
  185. const fakeStore = {
  186. getState: () => mockState.ads.ads,
  187. dispatch: (action) => dispatchedActions.push(action),
  188. };
  189. // wait for saga to complete
  190. await runSaga(fakeStore, fc.getAds, {}).done;
  191. expect(mockfn).not.toHaveBeenCalled();
  192. });
  193. it("Should not return filtered ads when exception was thrown", async () => {
  194. const dispatchedActions = [];
  195. const error = {
  196. response: {
  197. data: { message: "Error" },
  198. },
  199. };
  200. const filter = {
  201. minimumExperience: 0,
  202. maximumExperience: 0,
  203. technologies: [1],
  204. workHour: "FullTime",
  205. employmentType: "Work",
  206. };
  207. api.getFilteredAds = jest.fn(() => Promise.reject(error));
  208. const mockfn = jest.fn();
  209. const fakeStore = {
  210. getState: () => mockState.ads.ads,
  211. dispatch: (action) => dispatchedActions.push(action),
  212. };
  213. // wait for saga to complete
  214. await runSaga(fakeStore, fc.getFilteredAds, filter).done;
  215. expect(mockfn).not.toHaveBeenCalled();
  216. });
  217. it("Should not return ad when exception was thrown", async () => {
  218. const dispatchedActions = [];
  219. const error = {
  220. response: {
  221. data: { message: "Error" },
  222. },
  223. };
  224. api.getAd = jest.fn(() => Promise.reject(error));
  225. const mockfn = jest.fn();
  226. const fakeStore = {
  227. getState: () => mockState.ads.ads,
  228. dispatch: (action) => dispatchedActions.push(action),
  229. };
  230. // wait for saga to complete
  231. await runSaga(fakeStore, fc.getAd, {
  232. payload: {
  233. id: 1,
  234. },
  235. }).done;
  236. expect(mockfn).not.toHaveBeenCalled();
  237. });
  238. it("Should not return archived ad when exception was thrown", async () => {
  239. const dispatchedActions = [];
  240. const error = {
  241. response: {
  242. data: { message: "Error" },
  243. },
  244. };
  245. api.getAd = jest.fn(() => Promise.reject(error));
  246. const mockfn = jest.fn();
  247. const fakeStore = {
  248. getState: () => mockState.ads.ads,
  249. dispatch: (action) => dispatchedActions.push(action),
  250. };
  251. // wait for saga to complete
  252. await runSaga(fakeStore, fc.getArchiveAds, {}).done;
  253. expect(mockfn).not.toHaveBeenCalled();
  254. });
  255. it("Should not create ad when exception was thrown", async () => {
  256. const dispatchedActions = [];
  257. const error = {
  258. response: {
  259. data: { message: "Error" },
  260. },
  261. };
  262. api.createNewAd = jest.fn(() => Promise.reject(error));
  263. const mockfn = jest.fn();
  264. const fakeStore = {
  265. getState: () => mockState.ads.ads,
  266. dispatch: (action) => dispatchedActions.push(action),
  267. };
  268. // wait for saga to complete
  269. await runSaga(fakeStore, fc.createAd, {
  270. payload: {
  271. title: "React Developer",
  272. minimumExperience: 1,
  273. createdAt: new Date(),
  274. expiredAt: new Date("2023-5-5"),
  275. keyResponsibilities: "key responsibilities",
  276. requirements: "requirements",
  277. offer: "offer",
  278. workHour: "PartTime",
  279. employmentType: "Intership",
  280. technologiesIds: [1, 2],
  281. onSuccessAddAd: jest.fn,
  282. },
  283. }).done;
  284. expect(mockfn).not.toHaveBeenCalled();
  285. });
  286. it("Should archive active ad when exception was thrown", async () => {
  287. const dispatchedActions = [];
  288. const error = {
  289. response: {
  290. data: { message: "Error" },
  291. },
  292. };
  293. api.createNewAd = jest.fn(() => Promise.reject(error));
  294. const mockfn = jest.fn();
  295. const fakeStore = {
  296. getState: () => mockState.ads.ads,
  297. dispatch: (action) => dispatchedActions.push(action),
  298. };
  299. // wait for saga to complete
  300. await runSaga(fakeStore, fc.archiveActiveAdSaga, {
  301. payload: {
  302. id: 1,
  303. navigateToAds: jest.fn,
  304. },
  305. }).done;
  306. expect(mockfn).not.toHaveBeenCalled();
  307. });
  308. it("should handle ad load errors in case of failure", async () => {
  309. const dispatchedActions = [];
  310. helper.rejectErrorCodeHelper = jest.fn(() => "Error");
  311. const error = {
  312. response: {
  313. data: { message: "Error" },
  314. },
  315. };
  316. api.getAd = jest.fn(() => Promise.reject(error));
  317. const fakeStore = {
  318. getState: () => mockState.ads.ads,
  319. dispatch: (action) => dispatchedActions.push(action),
  320. };
  321. await runSaga(fakeStore, fc.getAd, {
  322. payload: {
  323. id: 1,
  324. },
  325. }).done;
  326. expect(api.getAdDetailsById.mock.calls.length).toBe(1);
  327. expect(dispatchedActions).toContainEqual(
  328. setAdError(error.response.data.message)
  329. );
  330. });
  331. });