diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index 24ad1358bf0eae238180b4a12aa7a12d3592e4d2..aedbed5b3a74ecae029abc43ef98b86e8071e74a 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx @@ -5,12 +5,8 @@ import { useSelector, useDispatch } from 'react-redux' import { AppStore } from 'store' import { changeScreenType } from 'store/global/global.actions' import { updateModalIsFeedbacksOpen } from 'store/modal/modal.actions' -import { - updateProfile, - setFirstConnection, -} from 'store/profile/profile.actions' +import { updateProfile } from 'store/profile/profile.actions' -import ProfileService from 'services/profile.service' import MailService from 'services/mail.service' import { ScreenType } from 'enum/screen.enum' import get from 'lodash/get' @@ -18,7 +14,6 @@ import get from 'lodash/get' import WelcomeModal from 'components/Welcome/WelcomeModal' import FeedbackModal from 'components/Feedback/FeedbackModal' import FavoriteModal from 'components/Favorite/FavoriteModal' -import { Profile } from 'models' interface ContentProps { children?: React.ReactNode @@ -66,24 +61,16 @@ const Content: React.FC<ContentProps> = ({ ], } mailService.SendMail(client, mailData) - const profileService = new ProfileService(client) - const updatedProfile: Profile | null = await profileService.updateProfile({ - isFirstConnection: false, - }) - if (updatedProfile) { - dispatch(setFirstConnection(false)) - } + dispatch( + updateProfile({ + isFirstConnection: false, + }) + ) }, [client, dispatch]) - const setFavoriteModalViewed = useCallback(async () => { - const profileService = new ProfileService(client) - const updatedProfile: Profile | null = await profileService.updateProfile({ - haveSeenFavoriteModal: true, - }) - if (updatedProfile) { - dispatch(updateProfile(updatedProfile)) - } - }, [client, dispatch]) + const setFavoriteModalViewed = useCallback(() => { + dispatch(updateProfile({ haveSeenFavoriteModal: true })) + }, [dispatch]) const handleFeedbackModalClose = useCallback(() => { dispatch(updateModalIsFeedbacksOpen(false)) diff --git a/src/components/Home/HomeView.tsx b/src/components/Home/HomeView.tsx index 3cdaf94af89f51dec06bd0abb48203957f1389f3..e9b8b06c6efcceb132318ae54afc3fed09c96a8d 100644 --- a/src/components/Home/HomeView.tsx +++ b/src/components/Home/HomeView.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useCallback } from 'react' -import { useClient } from 'cozy-client' import { useSelector, useDispatch } from 'react-redux' import { AppStore } from 'store' import { updateProfile } from 'store/profile/profile.actions' @@ -16,14 +15,11 @@ import ConsumptionNavigator from 'components/ConsumptionNavigator/ConsumptionNav import HomeIndicators from 'components/Home/HomeIndicators' import KonnectorViewerList from 'components/Konnector/KonnectorViewerList' import OldFluidDataModal from 'components/Home/OldFluidDataModal' -import { DateTime } from 'luxon' -import ProfileService from 'services/profile.service' import { FluidState, FluidType } from 'enum/fluid.enum' -import { Profile } from 'models' +import { DateTime } from 'luxon' const HomeView: React.FC = () => { - const client = useClient() const dispatch = useDispatch() const { fluidStatus, fluidTypes } = useSelector( (state: AppStore) => state.ecolyo.global @@ -43,17 +39,15 @@ const HomeView: React.FC = () => { const [openOldFluidDataModal, setopenOldFluidDataModal] = useState(false) const [fluidOldData] = useState<FluidType[]>([]) - const updateProfileHaveSeenOldFluidModal = useCallback(async () => { - const profileService = new ProfileService(client) - const updatedProfile: Profile | null = await profileService.updateProfile({ - haveSeenOldFluidModal: DateTime.local().setZone('utc', { - keepLocalTime: true, - }), - }) - if (updatedProfile) { - dispatch(updateProfile(updatedProfile)) - } - }, [client, dispatch]) + const updateProfileHaveSeenOldFluidModal = useCallback(() => { + dispatch( + updateProfile({ + haveSeenOldFluidModal: DateTime.local().setZone('utc', { + keepLocalTime: true, + }), + }) + ) + }, [dispatch]) const setChartLoaded = useCallback(() => { setChartLoading(false) @@ -103,7 +97,7 @@ const HomeView: React.FC = () => { if (fluidOldData.length > 0) { if (profile.haveSeenOldFluidModal === false) { //if user never has never seen the modal - await updateProfileHaveSeenOldFluidModal() + updateProfileHaveSeenOldFluidModal() return setopenOldFluidDataModal(true) } else if (profile.haveSeenOldFluidModal) { const dateToCompare = profile.haveSeenOldFluidModal diff --git a/src/components/Konnector/KonnectorViewerCard.tsx b/src/components/Konnector/KonnectorViewerCard.tsx index 2a58a9636c742cb89172bc7c547905b488ea7680..07b41cbff9d9987ae80c0a6786d4f67b7f449b0a 100644 --- a/src/components/Konnector/KonnectorViewerCard.tsx +++ b/src/components/Konnector/KonnectorViewerCard.tsx @@ -14,7 +14,6 @@ import { Konnector, Trigger, FluidStatus, - Profile, FluidConnection, } from 'models' import { getPicto, getAddPicto, getParamPicto } from 'utils/picto' @@ -25,7 +24,6 @@ import { toogleChallengeNotification, updatedFluidConnection, } from 'store/global/global.actions' -import ProfileService from 'services/profile.service' import FluidService from 'services/fluid.service' import InitializationService from 'services/initialization.service' import ChallengeService from 'services/challenge.service' @@ -91,15 +89,9 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ setActive(prev => !prev) } - const updateProfileHaveSeenOldFluidModal = useCallback(async () => { - const profileService = new ProfileService(client) - const updatedProfile: Profile | null = await profileService.updateProfile({ - haveSeenOldFluidModal: false, - }) - if (updatedProfile) { - dispatch(updateProfile(updatedProfile)) - } - }, [client, dispatch]) + const updateProfileHaveSeenOldFluidModal = useCallback(() => { + dispatch(updateProfile({ haveSeenOldFluidModal: false })) + }, [dispatch]) const updateGlobalFluidStatus = useCallback(async (): Promise< FluidStatus[] @@ -142,7 +134,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ }, [dispatch, updatedFluidStatus]) const handleAccountDeletion = useCallback(async () => { - await updateProfileHaveSeenOldFluidModal() + updateProfileHaveSeenOldFluidModal() await refreshChallengeState() const _updatedFluidStatus = await updateGlobalFluidStatus() if (_updatedFluidStatus.length > 0) { @@ -150,8 +142,8 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ } setActive(false) }, [ - updateProfileHaveSeenOldFluidModal, updateGlobalFluidStatus, + updateProfileHaveSeenOldFluidModal, refreshChallengeState, dispatch, ]) @@ -178,7 +170,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ shouldLaunchKonnector: false, } dispatch(updatedFluidConnection(fluidStatus.fluidType, updatedConnection)) - await updateProfileHaveSeenOldFluidModal() + updateProfileHaveSeenOldFluidModal() await refreshChallengeState() await updateGlobalFluidStatus() setKonnectorState(_state) diff --git a/src/components/Options/ReportOptions.spec.tsx b/src/components/Options/ReportOptions.spec.tsx index a9f982cd999d8eba71d1d8776dd5bf37527f8333..ae5e6fb3708a6bab45d891dfade146e916904b32 100644 --- a/src/components/Options/ReportOptions.spec.tsx +++ b/src/components/Options/ReportOptions.spec.tsx @@ -1,10 +1,12 @@ import React from 'react' import { mount } from 'enzyme' -import configureStore from 'redux-mock-store' import { Provider } from 'react-redux' import ReportOptions from 'components/Options/ReportOptions' -import { profileData } from '../../../test/__mocks__/profile.mock' -import { Profile } from 'models' +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../test/__mocks__/store' +import * as profileActions from 'store/profile/profile.actions' jest.mock('cozy-ui/transpiled/react/I18n', () => { return { @@ -16,23 +18,16 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { } }) -const mockUpdateProfile = jest.fn() -jest.mock('services/profile.service', () => { - return jest.fn(() => { - return { - updateProfile: mockUpdateProfile, - } - }) -}) - -const mockStore = configureStore([]) -const store = mockStore({ - ecolyo: { - profile: profileData, - }, -}) +const updateProfileSpy = jest.spyOn(profileActions, 'updateProfile') describe('ReportOptions component', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + updateProfileSpy.mockClear() + }) + it('should be rendered with 2 inputs', () => { const wrapper = mount( <Provider store={store}> @@ -43,11 +38,6 @@ describe('ReportOptions component', () => { }) it('should update the profile with sendReportNotification to true', () => { - const updatedProfileData: Profile = { - ...profileData, - sendReportNotification: true, - } - mockUpdateProfile.mockResolvedValueOnce(updatedProfileData) const wrapper = mount( <Provider store={store}> <ReportOptions /> @@ -57,17 +47,13 @@ describe('ReportOptions component', () => { .find('#monthly') .first() .simulate('change', { target: { value: 'true' } }) - expect(mockUpdateProfile).toHaveBeenCalledWith({ - sendReportNotification: updatedProfileData.sendReportNotification, + expect(updateProfileSpy).toBeCalledTimes(1) + expect(updateProfileSpy).toHaveBeenCalledWith({ + sendReportNotification: true, }) }) it('should update the profile with sendReportNotification to false', () => { - const updatedProfileData: Profile = { - ...profileData, - sendReportNotification: false, - } - mockUpdateProfile.mockResolvedValueOnce(updatedProfileData) const wrapper = mount( <Provider store={store}> <ReportOptions /> @@ -77,8 +63,9 @@ describe('ReportOptions component', () => { .find('#monthly') .first() .simulate('change', { target: { value: 'false' } }) - expect(mockUpdateProfile).toHaveBeenCalledWith({ - sendReportNotification: updatedProfileData.sendReportNotification, + expect(updateProfileSpy).toBeCalledTimes(1) + expect(updateProfileSpy).toHaveBeenCalledWith({ + sendReportNotification: false, }) }) }) diff --git a/src/components/Options/ReportOptions.tsx b/src/components/Options/ReportOptions.tsx index 6c8d529570674ae9f00edbd22fcd00a79a1648f9..97232bec66f9b21f574b7f2a2230ece7291605dd 100644 --- a/src/components/Options/ReportOptions.tsx +++ b/src/components/Options/ReportOptions.tsx @@ -1,27 +1,17 @@ import React from 'react' import { useI18n } from 'cozy-ui/transpiled/react/I18n' -import { useClient } from 'cozy-client' import { useSelector, useDispatch } from 'react-redux' import { AppStore } from 'store' import { updateProfile } from 'store/profile/profile.actions' -import ProfileService from 'services/profile.service' import './reportOptions.scss' -import { Profile } from 'models' const ReportOptions: React.FC = () => { const { t } = useI18n() - const client = useClient() const dispatch = useDispatch() const profile = useSelector((state: AppStore) => state.ecolyo.profile) const updateProfileReport = async (value: boolean) => { - const profileService = new ProfileService(client) - const updatedProfile: Profile | null = await profileService.updateProfile({ - sendReportNotification: value, - }) - if (updatedProfile) { - dispatch(updateProfile(updatedProfile)) - } + dispatch(updateProfile({ sendReportNotification: value })) } const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { diff --git a/src/components/Report/ReportView.spec.tsx b/src/components/Report/ReportView.spec.tsx index b8b89753fc02c4a960dece3a6f6d92fe4ab88e55..fd7707f94f40cb5d6f9238d685df983b8d46d563 100644 --- a/src/components/Report/ReportView.spec.tsx +++ b/src/components/Report/ReportView.spec.tsx @@ -1,7 +1,19 @@ import React from 'react' -import { shallow } from 'enzyme' +import { mount } from 'enzyme' +import * as reactRedux from 'react-redux' +import { Provider } from 'react-redux' import ReportView from 'components/Report/ReportView' import { globalStateData } from '../../../test/__mocks__/globalStateData.mock' +import { profileData } from '../../../test/__mocks__/profile.mock' +import CozyBar from 'components/Header/CozyBar' +import Content from 'components/Content/Content' +import Header from 'components/Header/Header' +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../test/__mocks__/store' +import * as globalActions from 'store/global/global.actions' +import * as profileActions from 'store/profile/profile.actions' jest.mock('cozy-ui/transpiled/react/I18n', () => { return { @@ -13,24 +25,84 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { } }) -const mockUpdateProfile = jest.fn() -jest.mock('services/profile.service', () => { - return jest.fn(() => { - return { - updateUserProfile: mockUpdateProfile, - } - }) -}) - -const mockUseSelector = globalStateData -jest.mock('react-redux', () => ({ - useSelector: jest.fn().mockResolvedValue(mockUseSelector), - useDispatch: () => jest.fn(), -})) +const useSelectorSpy = jest.spyOn(reactRedux, 'useSelector') +const useDispatchSpy = jest.spyOn(reactRedux, 'useDispatch') +const toogleReportNotificationSpy = jest.spyOn( + globalActions, + 'toogleReportNotification' +) +const updateProfileSpy = jest.spyOn(profileActions, 'updateProfile') describe('ReportOptions component', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + useSelectorSpy.mockClear() + useDispatchSpy.mockClear() + toogleReportNotificationSpy.mockClear() + updateProfileSpy.mockClear() + }) + it('should be rendered correctly', () => { - const component = shallow(<ReportView />).getElement() - expect(component).toMatchSnapshot() + useSelectorSpy.mockReturnValue({ + global: globalStateData, + profile: profileData, + }) + useDispatchSpy.mockReturnValue(jest.fn()) + const wrapper = mount( + <Provider store={store}> + <ReportView /> + </Provider> + ) + expect(wrapper.find(CozyBar)).toBeTruthy() + expect(wrapper.find(Header)).toBeTruthy() + expect(wrapper.find(Content)).toBeTruthy() + }) + + it('should update profile and toogle report notification to false if notification is true', () => { + useSelectorSpy.mockReturnValue({ + global: { + ...globalStateData, + reportNotification: true, + }, + profile: { + ...profileData, + haveSeenLastReport: false, + }, + }) + useDispatchSpy.mockReturnValue(jest.fn()) + mount( + <Provider store={store}> + <ReportView /> + </Provider> + ) + expect(updateProfileSpy).toBeCalledTimes(1) + expect(updateProfileSpy).toHaveBeenCalledWith({ + haveSeenLastReport: true, + }) + expect(toogleReportNotificationSpy).toBeCalledTimes(1) + expect(toogleReportNotificationSpy).toHaveBeenCalledWith(false) + }) + + it('should toogle report notification to false if user have seen last report', () => { + useSelectorSpy.mockReturnValue({ + global: { + ...globalStateData, + reportNotification: false, + }, + profile: { + ...profileData, + haveSeenLastReport: true, + }, + }) + useDispatchSpy.mockReturnValue(jest.fn()) + mount( + <Provider store={store}> + <ReportView /> + </Provider> + ) + expect(toogleReportNotificationSpy).toBeCalledTimes(1) + expect(toogleReportNotificationSpy).toHaveBeenCalledWith(false) }) }) diff --git a/src/components/Report/ReportView.tsx b/src/components/Report/ReportView.tsx index b2558ef959ad5c330397d27577d864590fbf509d..43019f87da172e344ddc92e070a16743c07f126e 100644 --- a/src/components/Report/ReportView.tsx +++ b/src/components/Report/ReportView.tsx @@ -1,23 +1,20 @@ import React, { useState, useEffect, useCallback } from 'react' -import { useClient } from 'cozy-client' import { useSelector, useDispatch } from 'react-redux' import { updateProfile } from 'store/profile/profile.actions' import { toogleReportNotification } from 'store/global/global.actions' import { AppStore } from 'store' -import ProfileService from 'services/profile.service' import CozyBar from 'components/Header/CozyBar' import Header from 'components/Header/Header' import Content from 'components/Content/Content' import MonthlyReport from 'components/Report/MonthlyReport' -import { Profile } from 'models' const ReportView: React.FC = () => { - const client = useClient() const [headerHeight, setHeaderHeight] = useState<number>(0) - const { reportNotification } = useSelector( - (state: AppStore) => state.ecolyo.global - ) + const { + global: { reportNotification }, + profile: { haveSeenLastReport }, + } = useSelector((state: AppStore) => state.ecolyo) const dispatch = useDispatch() const defineHeaderHeight = useCallback((height: number) => { @@ -25,28 +22,23 @@ const ReportView: React.FC = () => { }, []) useEffect(() => { - let subscribed = true - const updateProfileReport = async () => { + const updateProfileReport = () => { if (reportNotification) { - const profileService = new ProfileService(client) - try { - const updatedProfile: Profile | null = await profileService.updateProfile( - { haveSeenLastReport: true } - ) - if (subscribed && updatedProfile) { - dispatch(updateProfile(updatedProfile)) - dispatch(toogleReportNotification(false)) - } - } catch (err) { - console.log(err) - } + dispatch(updateProfile({ haveSeenLastReport: true })) + dispatch(toogleReportNotification(false)) } } updateProfileReport() - return () => { - subscribed = false + }, [dispatch, reportNotification]) + + useEffect(() => { + const updateReportNotification = () => { + if (haveSeenLastReport) { + dispatch(toogleReportNotification(false)) + } } - }, [client, dispatch, reportNotification]) + updateReportNotification() + }, [haveSeenLastReport, dispatch]) return ( <> diff --git a/src/components/Report/__snapshots__/ReportView.spec.tsx.snap b/src/components/Report/__snapshots__/ReportView.spec.tsx.snap deleted file mode 100644 index edc8133d7e37e2300fbb4d503c0620c3f7dfc922..0000000000000000000000000000000000000000 --- a/src/components/Report/__snapshots__/ReportView.spec.tsx.snap +++ /dev/null @@ -1,18 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ReportOptions component should be rendered correctly 1`] = ` -<React.Fragment> - <CozyBar - titleKey="report.viewTitle" - /> - <Header - desktopTitleKey="report.viewTitle" - setHeaderHeight={[Function]} - /> - <Content - height={0} - > - <MonthlyReport /> - </Content> -</React.Fragment> -`; diff --git a/src/db/profileData.json b/src/db/profileData.json index 6b61e4e0c15039052db5415d9fdd922d298584d5..a0313d8ff710e6d63df01a73ddcbd2625290a901 100644 --- a/src/db/profileData.json +++ b/src/db/profileData.json @@ -10,6 +10,24 @@ "haveSeenOldFluidModal": false, "haveSeenLastReport": true, "sendReportNotification": false, - "monthlyReportDate": "0000-01-01T00:00:00.000Z" + "monthlyReportDate": "0000-01-01T00:00:00.000Z", + "isProfileTypeCompleted": false, + "profileType": { + "housingType": "individual_house", + "constructionYear": "between_1975_and_1989", + "area": 100, + "occupantsNumber": 4, + "outsideFacingWalls": 2, + "floor": "not_applicable", + "heating": "individual", + "individualInsulationWork": [ + "window_replacement_and_wall_insulation" + ], + "facilitiesInstallation": "none", + "hotWaterEquipment": "solar", + "warmingFluid": 0, + "hotWaterFluid": 0, + "cookingFluid": 0 + } } ] diff --git a/src/services/profile.service.ts b/src/services/profile.service.ts index 17ad022eff016ee0ccbcc973262feda784630885..1c2753dfc70607f2ce31ef324a7b3148e3c731cb 100644 --- a/src/services/profile.service.ts +++ b/src/services/profile.service.ts @@ -76,9 +76,9 @@ export default class ProfileService { return null } - public async updateProfile(attributes: { - [key: string]: string | string[] | boolean | number | DateTime - }): Promise<Profile | null> { + public async updateProfile( + attributes: Partial<Profile> + ): Promise<Profile | null> { const query: QueryDefinition = Q(PROFILE_DOCTYPE) const { data: [doc], diff --git a/src/store/challenge/challenge.reducer.spec.ts b/src/store/challenge/challenge.reducer.spec.ts index 11fcd1bafdb85f1944ff45f3cf11165ef072392a..0e0d9260100c7989035741d39c17cbba9d0d1e76 100644 --- a/src/store/challenge/challenge.reducer.spec.ts +++ b/src/store/challenge/challenge.reducer.spec.ts @@ -7,22 +7,22 @@ import { } from './challenge.actions' import { Dataload, ChallengeState, UserChallenge } from 'models' import { UserChallengeState } from 'enum/userChallenge.enum' -import { challengeStateData } from '../../../test/__mocks__/challengeStateData.mock' import { userChallengeData, userChallengeDefault, } from '../../../test/__mocks__/userChallengeData.mock' import { DateTime } from 'luxon' +import { mockInitialChallengeState } from '../../../test/__mocks__/store' describe('challenge reducer', () => { it('should return the initial state', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = challengeReducer(undefined as any, { type: 'default' }) - expect(result).toEqual(challengeStateData) + expect(result).toEqual(mockInitialChallengeState) }) it('should handle SET_USER_CHALLENGE_LIST with payload', () => { - const result = challengeReducer(challengeStateData, { + const result = challengeReducer(mockInitialChallengeState, { type: SET_USER_CHALLENGE_LIST, payload: userChallengeData, }) @@ -35,22 +35,22 @@ describe('challenge reducer', () => { }) it('should handle SET_USER_CHALLENGE_LIST without payload', () => { - const result = challengeReducer(challengeStateData, { + const result = challengeReducer(mockInitialChallengeState, { type: SET_USER_CHALLENGE_LIST, }) - expect(result).toEqual(challengeStateData) + expect(result).toEqual(mockInitialChallengeState) }) it('should handle UPDATE_USER_CHALLENGE_LIST with payload', () => { - const updatedChallengeStateData = { - ...challengeStateData, + const updatedMockInitialChallengeState = { + ...mockInitialChallengeState, userChallengeList: userChallengeDefault, } const updatedUserChallenge: UserChallenge = { ...userChallengeDefault[0], state: UserChallengeState.ONGOING, } - const result = challengeReducer(updatedChallengeStateData, { + const result = challengeReducer(updatedMockInitialChallengeState, { type: UPDATE_USER_CHALLENGE_LIST, payload: updatedUserChallenge, }) @@ -66,15 +66,15 @@ describe('challenge reducer', () => { }) it('should handle UPDATE_USER_CHALLENGE_LIST without payload', () => { - const result = challengeReducer(challengeStateData, { + const result = challengeReducer(mockInitialChallengeState, { type: UPDATE_USER_CHALLENGE_LIST, }) - expect(result).toEqual(challengeStateData) + expect(result).toEqual(mockInitialChallengeState) }) it('should handle UNLOCK_NEXT_USER_CHALLENGE with payload', () => { - const updatedChallengeStateData = { - ...challengeStateData, + const updatedMockInitialChallengeState = { + ...mockInitialChallengeState, userChallengeList: userChallengeDefault, } const updatedUserChallenge: UserChallenge = { @@ -85,7 +85,7 @@ describe('challenge reducer', () => { ...userChallengeDefault[1], state: UserChallengeState.UNLOCKED, } - const result = challengeReducer(updatedChallengeStateData, { + const result = challengeReducer(updatedMockInitialChallengeState, { type: UNLOCK_NEXT_USER_CHALLENGE, payload: updatedUserChallenge, }) @@ -102,15 +102,15 @@ describe('challenge reducer', () => { }) it('should handle UNLOCK_NEXT_USER_CHALLENGE without payload', () => { - const result = challengeReducer(challengeStateData, { + const result = challengeReducer(mockInitialChallengeState, { type: UNLOCK_NEXT_USER_CHALLENGE, }) - expect(result).toEqual(challengeStateData) + expect(result).toEqual(mockInitialChallengeState) }) it('should handle SET_CHALLENGE_CONSUMPTION with payload', () => { - const updatedChallengeStateData = { - ...challengeStateData, + const updatedMockInitialChallengeState = { + ...mockInitialChallengeState, userChallengeList: userChallengeDefault, } const dataload: Dataload[] = [ @@ -137,7 +137,7 @@ describe('challenge reducer', () => { currentChallenge: null, currentDataload: dataload, } - const result = challengeReducer(updatedChallengeStateData, { + const result = challengeReducer(updatedMockInitialChallengeState, { type: SET_CHALLENGE_CONSUMPTION, payload: { userChallenge: updatedUserChallenge, @@ -148,9 +148,9 @@ describe('challenge reducer', () => { }) it('should handle SET_CHALLENGE_CONSUMPTION without payload', () => { - const result = challengeReducer(challengeStateData, { + const result = challengeReducer(mockInitialChallengeState, { type: SET_CHALLENGE_CONSUMPTION, }) - expect(result).toEqual(challengeStateData) + expect(result).toEqual(mockInitialChallengeState) }) }) diff --git a/src/store/chart/chart.reducer.spec.ts b/src/store/chart/chart.reducer.spec.ts index 897a908d3c8fd878c473d2fc85a351fbf213a31e..a656b61a2d0c24587bb803e4312c17d658e20f7a 100644 --- a/src/store/chart/chart.reducer.spec.ts +++ b/src/store/chart/chart.reducer.spec.ts @@ -1,45 +1,40 @@ import { chartReducer } from './chart.reducer' import { SET_PREVIOUS_TIMESTEP, ADD_MAX_LOAD } from './chart.actions' -import { ChartState } from 'models' import { TimeStep } from 'enum/timeStep.enum' - -const mockInitialState: ChartState = { - previousTimeStep: TimeStep.DAY, - maxLoads: new Map(), -} +import { mockInitialChartState } from '../../../test/__mocks__/store' describe('modal reducer', () => { it('should return the initial state', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = chartReducer(undefined as any, { type: 'default' }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialChartState) }) it('should handle SET_PREVIOUS_TIMESTEP with payload', () => { - const result = chartReducer(mockInitialState, { + const result = chartReducer(mockInitialChartState, { type: SET_PREVIOUS_TIMESTEP, payload: TimeStep.MONTH, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialChartState, previousTimeStep: TimeStep.MONTH, }) }) it('should handle SET_PREVIOUS_TIMESTEP without payload', () => { - const result = chartReducer(mockInitialState, { + const result = chartReducer(mockInitialChartState, { type: SET_PREVIOUS_TIMESTEP, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialChartState) }) it('should handle ADD_MAX_LOAD with payload', () => { - const result = chartReducer(mockInitialState, { + const result = chartReducer(mockInitialChartState, { type: ADD_MAX_LOAD, payload: new Map().set('KEY', 10), }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialChartState, maxLoads: new Map().set('KEY', 10), }) const result2 = chartReducer(result, { @@ -53,9 +48,9 @@ describe('modal reducer', () => { }) it('should handle ADD_MAX_LOAD without payload', () => { - const result = chartReducer(mockInitialState, { + const result = chartReducer(mockInitialChartState, { type: ADD_MAX_LOAD, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialChartState) }) }) diff --git a/src/store/global/global.reducer.spec.ts b/src/store/global/global.reducer.spec.ts index 8b2e04f57feb460c4c3239d42b6b34e378a31824..1795e9a6243371e059833972ab551156f03d2ba8 100644 --- a/src/store/global/global.reducer.spec.ts +++ b/src/store/global/global.reducer.spec.ts @@ -6,12 +6,13 @@ import { SET_FLUID_STATUS, } from './global.actions' import { ScreenType } from 'enum/screen.enum' -import { FluidStatus, GlobalState } from 'models' +import { FluidStatus } from 'models' import { FluidState, FluidType } from 'enum/fluid.enum' import { DateTime } from 'luxon' import { konnectorsData } from '../../../test/__mocks__/konnectorsData.mock' import { accountsData } from '../../../test/__mocks__/accountsData.mock' import { triggersData } from '../../../test/__mocks__/triggersData.mock' +import { mockInitialGlobalState } from '../../../test/__mocks__/store' const mockLastDataDates: (DateTime | null)[] = [ DateTime.local().setZone('utc', { @@ -25,133 +26,65 @@ const mockLastDataDates: (DateTime | null)[] = [ }), ] -const mockFluidStatus: FluidStatus[] = [ - { - fluidType: FluidType.ELECTRICITY, - status: FluidState.KONNECTOR_NOT_FOUND, - lastDataDate: null, - connection: { - shouldLaunchKonnector: false, - isUpdating: false, - konnector: null, - account: null, - trigger: null, - triggerState: null, - konnectorConfig: { - name: '', - oauth: false, - slug: '', - siteLink: '', - }, - }, - }, - { - fluidType: FluidType.WATER, - status: FluidState.KONNECTOR_NOT_FOUND, - lastDataDate: null, - connection: { - shouldLaunchKonnector: false, - isUpdating: false, - konnector: null, - account: null, - trigger: null, - triggerState: null, - konnectorConfig: { - name: '', - oauth: false, - slug: '', - siteLink: '', - }, - }, - }, - { - fluidType: FluidType.GAS, - status: FluidState.KONNECTOR_NOT_FOUND, - lastDataDate: null, - connection: { - shouldLaunchKonnector: false, - isUpdating: false, - konnector: null, - account: null, - trigger: null, - triggerState: null, - konnectorConfig: { - name: '', - oauth: false, - slug: '', - siteLink: '', - }, - }, - }, -] - -const mockInitialState: GlobalState = { - screenType: ScreenType.MOBILE, - challengeNotification: false, - reportNotification: false, - fluidStatus: mockFluidStatus, - fluidTypes: [], -} - describe('global reducer', () => { it('should return the initial state', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = globalReducer(undefined as any, { type: 'default' }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialGlobalState) }) it('should handle CHANGE_SCREEN_TYPE with payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: CHANGE_SCREEN_TYPE, payload: ScreenType.DESKTOP, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialGlobalState, screenType: ScreenType.DESKTOP, }) }) it('should handle CHANGE_SCREEN_TYPE without payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: CHANGE_SCREEN_TYPE, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialGlobalState) }) it('should handle TOOGLE_CHALLENGE_NOTIFICATION with payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: TOOGLE_CHALLENGE_NOTIFICATION, payload: true, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialGlobalState, challengeNotification: true, }) }) it('should handle TOOGLE_CHALLENGE_NOTIFICATION without payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: TOOGLE_CHALLENGE_NOTIFICATION, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialGlobalState) }) it('should handle TOOGLE_REPORT_NOTIFICATION with payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: TOOGLE_REPORT_NOTIFICATION, payload: true, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialGlobalState, reportNotification: true, }) }) it('should handle TOOGLE_REPORT_NOTIFICATION without payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: TOOGLE_REPORT_NOTIFICATION, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialGlobalState) }) it('should handle SET_FLUID_STATUS with payload', () => { @@ -214,21 +147,21 @@ describe('global reducer', () => { }, }, ] - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: SET_FLUID_STATUS, payload: fluidStatus, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialGlobalState, fluidStatus: fluidStatus, fluidTypes: [FluidType.ELECTRICITY, FluidType.WATER], }) }) it('should handle SET_FLUID_STATUS without payload', () => { - const result = globalReducer(mockInitialState, { + const result = globalReducer(mockInitialGlobalState, { type: SET_FLUID_STATUS, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialGlobalState) }) }) diff --git a/src/store/index.ts b/src/store/index.ts index 8e6310d05153b303ba4ab456225c6c370a4db1a0..c91ee3c801bc97b1268199c6c815b3b6209c083e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,5 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { createStore, combineReducers, Store } from 'redux' +import { + createStore, + combineReducers, + applyMiddleware, + compose, + Store, +} from 'redux' +import thunkMiddleware from 'redux-thunk' import { composeWithDevTools } from 'redux-devtools-extension' import { globalReducer } from 'store/global/global.reducer' import { profileReducer } from './profile/profile.reducer' @@ -28,20 +35,24 @@ export const ecolyoReducer = combineReducers({ export interface AppStore { ecolyo: EcolyoState - cozy: any + cozy: never } const configureStore = ( client: Client, persistedState: any ): Store<AppStore> => { + const middlewares = [thunkMiddleware.withExtraArgument({ client })] + const composeEnhancers = composeWithDevTools || compose + const store: Store<AppStore> = createStore( combineReducers({ ecolyo: ecolyoReducer, cozy: client.reducer(), persistedState, }), - composeWithDevTools() + // eslint-disable-next-line prefer-spread + composeEnhancers(applyMiddleware.apply(null, middlewares)) ) return store } diff --git a/src/store/modal/modal.reducer.spec.ts b/src/store/modal/modal.reducer.spec.ts index d94e6f84b45f1c235ffb8711b2a03b787bc6f658..f17055cae7853dcd29f4c4e9f559c66b7929cfb3 100644 --- a/src/store/modal/modal.reducer.spec.ts +++ b/src/store/modal/modal.reducer.spec.ts @@ -1,33 +1,29 @@ import { modalReducer } from './modal.reducer' import { UPDATE_MODAL_ISFEEDBACKSOPEN } from './modal.actions' -import { ModalState } from 'models' - -const mockInitialState: ModalState = { - isFeedbacksOpen: false, -} +import { mockInitialModalState } from '../../../test/__mocks__/store' describe('modal reducer', () => { it('should return the initial state', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = modalReducer(undefined as any, { type: 'default' }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialModalState) }) it('should handle UPDATE_MODAL_ISFEEDBACKSOPEN with payload', () => { - const result = modalReducer(mockInitialState, { + const result = modalReducer(mockInitialModalState, { type: UPDATE_MODAL_ISFEEDBACKSOPEN, payload: true, }) expect(result).toEqual({ - ...mockInitialState, + ...mockInitialModalState, isFeedbacksOpen: true, }) }) it('should handle UPDATE_MODAL_ISFEEDBACKSOPEN without payload', () => { - const result = modalReducer(mockInitialState, { + const result = modalReducer(mockInitialModalState, { type: UPDATE_MODAL_ISFEEDBACKSOPEN, }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialModalState) }) }) diff --git a/src/store/profile/profile.action.spec.ts b/src/store/profile/profile.action.spec.ts index 369a228a7ac0b4b9db049d51d772b2daf704f6b1..3aa86aad064190c7c747cf4fa0f85d6f615e93b4 100644 --- a/src/store/profile/profile.action.spec.ts +++ b/src/store/profile/profile.action.spec.ts @@ -1,25 +1,40 @@ -import { - UPDATE_PROFILE, - SET_FIRST_CONNECTION, - updateProfile, - setFirstConnection, -} from './profile.actions' +import { UPDATE_PROFILE, updateProfile } from './profile.actions' import { profileData } from '../../../test/__mocks__/profile.mock' +import { + createMockStore, + mockInitialEcolyoState, +} from '../../../test/__mocks__/store' -describe('profile actions', () => { - it('should create an action to update profile', () => { - const expectedAction = { - type: UPDATE_PROFILE, - payload: profileData, +const mockUpdateProfile = jest.fn() +jest.mock('services/profile.service', () => { + return jest.fn(() => { + return { + updateProfile: mockUpdateProfile, } - expect(updateProfile(profileData)).toEqual(expectedAction) }) +}) - it('should create an action to set firstConnection', () => { - const expectedAction = { - type: SET_FIRST_CONNECTION, - payload: true, - } - expect(setFirstConnection(true)).toEqual(expectedAction) +describe('profile actions', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let store: any + beforeEach(() => { + store = createMockStore(mockInitialEcolyoState) + }) + it('should create an UPDATE_PROFILE action when profile is updated', async () => { + mockUpdateProfile.mockResolvedValueOnce(profileData) + const expectedActions = [ + { + type: UPDATE_PROFILE, + payload: profileData, + }, + ] + await store.dispatch(updateProfile(profileData)) + expect(store.getActions()).toEqual(expectedActions) + }) + + it('should not create action when profile is not updated', async () => { + mockUpdateProfile.mockResolvedValueOnce(null) + await store.dispatch(updateProfile(profileData)) + expect(store.getActions()).toEqual([]) }) }) diff --git a/src/store/profile/profile.actions.ts b/src/store/profile/profile.actions.ts index 7ace467d460d623e3d0d721ff3067820411f0b83..a8bc3635b347a2017e89f46fb040631153c39f16 100644 --- a/src/store/profile/profile.actions.ts +++ b/src/store/profile/profile.actions.ts @@ -1,4 +1,8 @@ +import { Client } from 'cozy-client' import { Profile } from 'models' +import ProfileService from 'services/profile.service' +import { Dispatch } from 'react' +import { AppStore } from 'store' export const UPDATE_PROFILE = 'UPDATE_PROFILE' export const SET_FIRST_CONNECTION = 'SET_FIRST_CONNECTION' @@ -8,23 +12,25 @@ interface UpdateProfile { payload?: Profile } -interface SetFirstConnection { - type: typeof SET_FIRST_CONNECTION - payload: boolean -} - -export type ProfileActionTypes = UpdateProfile | SetFirstConnection +export type ProfileActionTypes = UpdateProfile -export function updateProfile(profile: Profile): ProfileActionTypes { +export function updateProfileSuccess(updatedProfile: Profile): UpdateProfile { return { type: UPDATE_PROFILE, - payload: profile, + payload: updatedProfile, } } -export function setFirstConnection(isFirst: boolean): ProfileActionTypes { - return { - type: SET_FIRST_CONNECTION, - payload: isFirst, +export function updateProfile(upd: Partial<Profile>) { + return async ( + dispatch: Dispatch<UpdateProfile>, + getState: () => AppStore, + { client }: { client: Client } + ) => { + const profileService = new ProfileService(client) + const updatedProfile = await profileService.updateProfile(upd) + if (updatedProfile) { + dispatch(updateProfileSuccess(updatedProfile)) + } } } diff --git a/src/store/profile/profile.reducer.spec.ts b/src/store/profile/profile.reducer.spec.ts index adf38a29e6e3532e719bbf8bf4bf32a871d5cd91..96f600f90ad0aa813253dba440b3373c7eb40595 100644 --- a/src/store/profile/profile.reducer.spec.ts +++ b/src/store/profile/profile.reducer.spec.ts @@ -1,62 +1,17 @@ import { profileReducer } from './profile.reducer' -import { UPDATE_PROFILE, SET_FIRST_CONNECTION } from './profile.actions' -import { Profile } from 'models' -import { DateTime } from 'luxon' +import { UPDATE_PROFILE } from './profile.actions' +import { mockInitialProfileState } from '../../../test/__mocks__/store' import { profileData } from '../../../test/__mocks__/profile.mock' -import { - ConstructionYear, - FacilitiesInstallation, - Floor, - Heating, - HotWaterEquipment, - HousingType, - IndividualInsulationWork, - OutsideFacingWalls, -} from 'enum/profileType.enum' -import { FluidType } from 'enum/fluid.enum' - -const mockInitialState: Profile = { - id: '', - ecogestureHash: '', - challengeHash: '', - duelHash: '', - quizHash: '', - explorationHash: '', - isFirstConnection: false, - lastConnectionDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), - haveSeenFavoriteModal: true, - haveSeenOldFluidModal: true, - haveSeenLastReport: true, - sendReportNotification: false, - monthlyReportDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), - isProfileTypeCompleted: false, - profileType: { - housingType: HousingType.INDIVIDUAL_HOUSE, - constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, - area: 100, - occupantsNumber: 4, - outsideFacingWalls: OutsideFacingWalls.TWO, - floor: Floor.NOT_APPLICABLE, - heating: Heating.INDIVIDUAL, - individualInsulationWork: - IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, - facilitiesInstallation: FacilitiesInstallation.NONE, - hotWaterEquipment: HotWaterEquipment.SOLAR, - warmingFluid: FluidType.ELECTRICITY, - hotWaterFluid: FluidType.ELECTRICITY, - cookingFluid: FluidType.ELECTRICITY, - }, -} describe('profile reducer', () => { it('should return the initial state', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const result = profileReducer(undefined as any, { type: 'default' }) - expect(result).toEqual(mockInitialState) + expect(result).toEqual(mockInitialProfileState) }) it('should handle UPDATE_PROFILE with payload', () => { - const result = profileReducer(mockInitialState, { + const result = profileReducer(mockInitialProfileState, { type: UPDATE_PROFILE, payload: profileData, }) @@ -64,17 +19,9 @@ describe('profile reducer', () => { }) it('should handle UPDATE_PROFILE without payload', () => { - const result = profileReducer(mockInitialState, { + const result = profileReducer(mockInitialProfileState, { type: UPDATE_PROFILE, }) - expect(result).toEqual(mockInitialState) - }) - - it('should handle SET_FIRST_CONNECTION with payload', () => { - const result = profileReducer(mockInitialState, { - type: SET_FIRST_CONNECTION, - payload: true, - }) - expect(result).toEqual({ ...mockInitialState, isFirstConnection: true }) + expect(result).toEqual(mockInitialProfileState) }) }) diff --git a/src/store/profile/profile.reducer.ts b/src/store/profile/profile.reducer.ts index c2119567939c507a538076234977e42d93f2ca3b..7d2a9efb3e79de62da82af777e776b437047ff2e 100644 --- a/src/store/profile/profile.reducer.ts +++ b/src/store/profile/profile.reducer.ts @@ -1,7 +1,6 @@ import { Reducer } from 'redux' import { UPDATE_PROFILE, - SET_FIRST_CONNECTION, ProfileActionTypes, } from 'store/profile/profile.actions' import { Profile } from 'models' @@ -61,11 +60,6 @@ export const profileReducer: Reducer<Profile> = ( ...state, ...action.payload, } - case SET_FIRST_CONNECTION: - return { - ...state, - isFirstConnection: action.payload, - } default: return state } diff --git a/test/__mocks__/globalStateData.mock.ts b/test/__mocks__/globalStateData.mock.ts index c8385fc7aa780cc5b0a3295a690749cd7d1cbab7..178204eb4391482f5211c6198511bed3917b7aee 100644 --- a/test/__mocks__/globalStateData.mock.ts +++ b/test/__mocks__/globalStateData.mock.ts @@ -1,4 +1,4 @@ -import { FluidType } from 'enum/fluid.enum' +import { FluidState, FluidType } from 'enum/fluid.enum' import { ScreenType } from 'enum/screen.enum' import { GlobalState } from 'models' @@ -9,18 +9,60 @@ export const globalStateData: GlobalState = { fluidStatus: [ { fluidType: FluidType.ELECTRICITY, - status: null, + status: FluidState.KONNECTOR_NOT_FOUND, lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, }, { fluidType: FluidType.WATER, - status: null, + status: FluidState.KONNECTOR_NOT_FOUND, lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, }, { fluidType: FluidType.GAS, - status: null, + status: FluidState.KONNECTOR_NOT_FOUND, lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, }, ], fluidTypes: [], diff --git a/test/__mocks__/store.ts b/test/__mocks__/store.ts new file mode 100644 index 0000000000000000000000000000000000000000..74e74c5cb02167f14db0c8a89b751f3dbfc2ebdc --- /dev/null +++ b/test/__mocks__/store.ts @@ -0,0 +1,162 @@ +import { FluidState, FluidType } from 'enum/fluid.enum' +import { + ConstructionYear, + FacilitiesInstallation, + Floor, + Heating, + HotWaterEquipment, + HousingType, + IndividualInsulationWork, + OutsideFacingWalls, +} from 'enum/profileType.enum' +import { ScreenType } from 'enum/screen.enum' +import { TimeStep } from 'enum/timeStep.enum' +import { DateTime } from 'luxon' +import { + ChallengeState, + ChartState, + GlobalState, + ModalState, + Profile, +} from 'models' +import configureStore from 'redux-mock-store' +import thunkMiddleware from 'redux-thunk' +import { EcolyoState } from 'store' +import mockClient from './client' + +export const mockInitialGlobalState: GlobalState = { + screenType: ScreenType.MOBILE, + challengeNotification: false, + reportNotification: false, + fluidStatus: [ + { + fluidType: FluidType.ELECTRICITY, + status: FluidState.KONNECTOR_NOT_FOUND, + lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, + }, + { + fluidType: FluidType.WATER, + status: FluidState.KONNECTOR_NOT_FOUND, + lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, + }, + { + fluidType: FluidType.GAS, + status: FluidState.KONNECTOR_NOT_FOUND, + lastDataDate: null, + connection: { + shouldLaunchKonnector: false, + isUpdating: false, + konnector: null, + account: null, + trigger: null, + triggerState: null, + konnectorConfig: { + name: '', + oauth: false, + slug: '', + siteLink: '', + }, + }, + }, + ], + fluidTypes: [], +} + +export const mockInitialProfileState: Profile = { + id: '', + ecogestureHash: '', + challengeHash: '', + duelHash: '', + quizHash: '', + explorationHash: '', + isFirstConnection: false, + lastConnectionDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), + haveSeenFavoriteModal: true, + haveSeenOldFluidModal: true, + haveSeenLastReport: true, + sendReportNotification: false, + monthlyReportDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), + isProfileTypeCompleted: false, + profileType: { + housingType: HousingType.INDIVIDUAL_HOUSE, + constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, + area: 100, + occupantsNumber: 4, + outsideFacingWalls: OutsideFacingWalls.TWO, + floor: Floor.NOT_APPLICABLE, + heating: Heating.INDIVIDUAL, + individualInsulationWork: + IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, + facilitiesInstallation: FacilitiesInstallation.NONE, + hotWaterEquipment: HotWaterEquipment.SOLAR, + warmingFluid: FluidType.ELECTRICITY, + hotWaterFluid: FluidType.ELECTRICITY, + cookingFluid: FluidType.ELECTRICITY, + }, +} + +export const mockInitialChartState: ChartState = { + previousTimeStep: TimeStep.DAY, + maxLoads: new Map(), +} + +export const mockInitialModalState: ModalState = { + isFeedbacksOpen: false, +} + +export const mockInitialChallengeState: ChallengeState = { + userChallengeList: [], + currentChallenge: null, + currentDataload: [], +} + +export const mockInitialEcolyoState = { + global: mockInitialGlobalState, + profile: mockInitialProfileState, + chart: mockInitialChartState, + modal: mockInitialModalState, + challenge: mockInitialChallengeState, +} + +const middlewares = [thunkMiddleware.withExtraArgument({ mockClient })] +const mockStore = configureStore(middlewares) +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const mockedStore: any = mockStore({ + ecolyo: mockInitialEcolyoState, +}) + +export const createMockStore = (initialState: EcolyoState) => { + return mockStore({ + ecolyo: initialState, + }) +} + +export default mockedStore