import * as redux from "react-redux"; import store from "../../store"; import { Router } from "react-router-dom"; import history from "../../store/utils/history"; import { mockState } from "../../mockState"; import { render } from "@testing-library/react"; import AdsPage from "../../pages/AdsPage/AdsPage"; import * as api from "../../request/adsRequest"; import { runSaga } from "redux-saga"; import { FETCH_ADS_REQ } from "../../store/actions/ads/adsActionConstants"; import ColorModeProvider from "../../context/ColorModeContext"; import * as fc from "../../store/saga/adsSaga"; import { setAds, setFilteredAds } from "../../store/actions/ads/adsAction"; import { setArchiveAds } from "../../store/actions/archiveAds/archiveAdsActions"; import { setCreateAd } from "../../store/actions/createAd/createAdActions"; import { setAd, setAdError } from "../../store/actions/ad/adActions"; import { archiveActiveAd } from "../../store/actions/archiveActiveAd/archiveActiveAdActions"; import * as helper from "../../util/helpers/rejectErrorCodeHelper"; describe("Ads reducer tests", () => { const cont = ( ); let spyOnUseSelector; let spyOnUseDispatch; let mockDispatch; beforeEach(() => { spyOnUseSelector = jest.spyOn(redux, "useSelector"); spyOnUseSelector.mockReturnValueOnce(mockState.ads); spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); mockDispatch = jest.fn(); spyOnUseDispatch.mockReturnValue(mockDispatch); }); afterEach(() => { jest.restoreAllMocks(); }); it("Should dispatch get ads request when rendered", () => { render(cont); expect(mockDispatch).toHaveBeenCalledWith({ type: FETCH_ADS_REQ, }); }); it("Should load and handle ads in case of success", async () => { const dispatchedActions = []; const mockedCall = { data: mockState.ads.ads }; api.getAllAds = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.getAds, {}).done; expect(api.getAllAds.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(setAds(mockedCall.data)); }); it("Should load and handle filtered ads in case of success", async () => { const dispatchedActions = []; const filter = { minimumExperience: 0, maximumExperience: 0, technologies: [1], workHour: "FullTime", employmentType: "Work", }; const filteredData = mockState.ads.ads.filter( (ad) => ad.minimumExperience >= filter.minimumExperience && ad.minimumExperience <= filter.maximumExperience && ad.workHour === filter.workHour && ad.employmentType === filter.employmentType ); const mockedCall = { data: filteredData }; api.getAllFilteredAds = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.getFilteredAds, filter).done; expect(api.getAllFilteredAds.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(setFilteredAds(mockedCall.data)); }); it("Should load and handle archived ads in case of success", async () => { const dispatchedActions = []; const date = new Date(); const filteredData = mockState.ads.ads.filter((ad) => ad.expiredAt < date); const mockedCall = { data: filteredData }; api.getAllArchiveAds = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.getArchiveAds, {}).done; expect(api.getAllArchiveAds.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(setArchiveAds(mockedCall.data)); }); it("Should load and handle ad by id in case of success", async () => { const dispatchedActions = []; const id = 1; const filteredData = mockState.ads.ads.filter((ad) => ad.id === id); const mockedCall = { data: filteredData }; api.getAdDetailsById = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.getAd, { payload: id }).done; expect(api.getAdDetailsById.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(setAd(mockedCall.data)); }); it("Should create ad", async () => { const dispatchedActions = []; const mockedCall = { data: { title: "React Developer", minimumExperience: 1, createdAt: new Date(), expiredAt: new Date("2023-5-5"), keyResponsibilities: "key responsibilities", requirements: "requirements", offer: "offer", workHour: "PartTime", employmentType: "Intership", technologiesIds: [1, 2], onSuccessAddAd: jest.fn, }, }; api.createNewAd = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.createAd, { payload: { title: "React Developer", minimumExperience: 1, createdAt: new Date(), expiredAt: new Date("2023-5-5"), keyResponsibilities: "key responsibilities", requirements: "requirements", offer: "offer", workHour: "PartTime", employmentType: "Intership", technologiesIds: [1, 2], onSuccessAddAd: jest.fn, }, }).done; expect(api.createNewAd.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(setCreateAd(mockedCall.data)); }); it("Archive ad", async () => { const dispatchedActions = []; const mockedCall = { data: { id: 1, navigateToAds: jest.fn, }, }; api.archiveActiveAdRequest = jest.fn(() => Promise.resolve(mockedCall)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.archiveActiveAdSaga, { payload: { id: 1, navigateToAds: jest.fn, }, }).done; expect(api.archiveActiveAdRequest.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual(archiveActiveAd(mockedCall.data)); }); it("Should not return ads when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; api.getAllAds = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.getAds, {}).done; expect(mockfn).not.toHaveBeenCalled(); }); it("Should not return filtered ads when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; const filter = { minimumExperience: 0, maximumExperience: 0, technologies: [1], workHour: "FullTime", employmentType: "Work", }; api.getFilteredAds = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.getFilteredAds, filter).done; expect(mockfn).not.toHaveBeenCalled(); }); it("Should not return ad when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; api.getAd = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.getAd, { payload: { id: 1, }, }).done; expect(mockfn).not.toHaveBeenCalled(); }); it("Should not return archived ad when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; api.getAd = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.getArchiveAds, {}).done; expect(mockfn).not.toHaveBeenCalled(); }); it("Should not create ad when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; api.createNewAd = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.createAd, { payload: { title: "React Developer", minimumExperience: 1, createdAt: new Date(), expiredAt: new Date("2023-5-5"), keyResponsibilities: "key responsibilities", requirements: "requirements", offer: "offer", workHour: "PartTime", employmentType: "Intership", technologiesIds: [1, 2], onSuccessAddAd: jest.fn, }, }).done; expect(mockfn).not.toHaveBeenCalled(); }); it("Should archive active ad when exception was thrown", async () => { const dispatchedActions = []; const error = { response: { data: { message: "Error" }, }, }; api.createNewAd = jest.fn(() => Promise.reject(error)); const mockfn = jest.fn(); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; // wait for saga to complete await runSaga(fakeStore, fc.archiveActiveAdSaga, { payload: { id: 1, navigateToAds: jest.fn, }, }).done; expect(mockfn).not.toHaveBeenCalled(); }); it("should handle ad load errors in case of failure", async () => { const dispatchedActions = []; helper.rejectErrorCodeHelper = jest.fn(() => "Error"); const error = { response: { data: { message: "Error" }, }, }; api.getAd = jest.fn(() => Promise.reject(error)); const fakeStore = { getState: () => mockState.ads.ads, dispatch: (action) => dispatchedActions.push(action), }; await runSaga(fakeStore, fc.getAd, { payload: { id: 1, }, }).done; expect(api.getAdDetailsById.mock.calls.length).toBe(1); expect(dispatchedActions).toContainEqual( setAdError(error.response.data.message) ); }); });