From c7e1a7f4675d46ce525f5172c03d7e29161ae312 Mon Sep 17 00:00:00 2001 From: Yoan VALLET <ext.sopra.yvallet@grandlyon.com> Date: Mon, 26 Apr 2021 12:06:49 +0200 Subject: [PATCH] feat: update profile data --- src/db/profileData.json | 68 +++++++------ src/models/profile.model.ts | 70 +++++++------ src/services/profile.service.ts | 144 ++++++++++++++------------- src/store/profile/profile.reducer.ts | 136 +++++++++++++------------ tests/__mocks__/profile.mock.ts | 4 + tests/__mocks__/store.ts | 4 + 6 files changed, 230 insertions(+), 196 deletions(-) diff --git a/src/db/profileData.json b/src/db/profileData.json index 285bc7709..f83000e5e 100644 --- a/src/db/profileData.json +++ b/src/db/profileData.json @@ -1,32 +1,36 @@ -[ - { - "ecogestureHash": "", - "challengeHash": "", - "duelHash": "", - "quizHash": "", - "isFirstConnection": true, - "lastConnectionDate": "0000-01-01T00:00:00.000Z", - "haveSeenOldFluidModal": false, - "haveSeenLastAnalysis": true, - "sendAnalysisNotification": false, - "monthlyAnalysisDate": "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", - "coldWater": "individual", - "hotWater": "individual", - "individualInsulationWork": ["window_replacement_and_wall_insulation"], - "facilitiesInstallation": "none", - "hotWaterEquipment": "solar", - "warmingFluid": 0, - "hotWaterFluid": 0, - "cookingFluid": 0 - } - } -] +[ + { + "ecogestureHash": "", + "challengeHash": "", + "duelHash": "", + "quizHash": "", + "isFirstConnection": true, + "GCUApprovalDate": null, + "lastConnectionDate": "0000-01-01T00:00:00.000Z", + "haveSeenOldFluidModal": false, + "haveSeenLastAnalysis": true, + "sendAnalysisNotification": false, + "monthlyAnalysisDate": "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", + "coldWater": "individual", + "hotWater": "individual", + "individualInsulationWork": ["window_replacement_and_wall_insulation"], + "facilitiesInstallation": "none", + "hotWaterEquipment": "solar", + "warmingFluid": 0, + "hotWaterFluid": 0, + "cookingFluid": 0 + }, + "tutorial": { + "isWelcomeSeen": false + } + } +] diff --git a/src/models/profile.model.ts b/src/models/profile.model.ts index 2e672bde8..f4dc003ed 100644 --- a/src/models/profile.model.ts +++ b/src/models/profile.model.ts @@ -1,29 +1,41 @@ -import { DateTime } from 'luxon' -import { ProfileType } from './profileType.model' -export interface ProfileEntity { - id: string - ecogestureHash: string - challengeHash: string - duelHash: string - quizHash: string - explorationHash: string - isFirstConnection: boolean - lastConnectionDate: string - haveSeenLastAnalysis: boolean - haveSeenOldFluidModal: string | boolean - sendAnalysisNotification: boolean - monthlyAnalysisDate: string - profileType: ProfileType - isProfileTypeCompleted: boolean - _id?: string - _rev?: string -} -export interface Profile - extends Omit< - ProfileEntity, - 'haveSeenOldFluidModal' | 'lastConnectionDate' | 'monthlyAnalysisDate' - > { - lastConnectionDate: DateTime - haveSeenOldFluidModal: DateTime | boolean - monthlyAnalysisDate: DateTime -} +import { DateTime } from 'luxon' +import { ProfileType } from './profileType.model' + +interface Tutorial { + isWelcomeSeen: boolean +} + +export interface ProfileEntity { + id: string + ecogestureHash: string + challengeHash: string + duelHash: string + quizHash: string + explorationHash: string + isFirstConnection: boolean + GCUApprovalDate: string | null + lastConnectionDate: string + haveSeenLastAnalysis: boolean + haveSeenOldFluidModal: string | boolean + sendAnalysisNotification: boolean + monthlyAnalysisDate: string + profileType: ProfileType + isProfileTypeCompleted: boolean + tutorial: Tutorial + _id?: string + _rev?: string +} + +export interface Profile + extends Omit< + ProfileEntity, + | 'GCUApprovalDate' + | 'haveSeenOldFluidModal' + | 'lastConnectionDate' + | 'monthlyAnalysisDate' + > { + GCUApprovalDate: DateTime | null + lastConnectionDate: DateTime + haveSeenOldFluidModal: DateTime | boolean + monthlyAnalysisDate: DateTime +} diff --git a/src/services/profile.service.ts b/src/services/profile.service.ts index 46a43c5c2..2927967a8 100644 --- a/src/services/profile.service.ts +++ b/src/services/profile.service.ts @@ -1,69 +1,75 @@ -import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client' -import { Profile, ProfileEntity } from 'models' -import { PROFILE_DOCTYPE } from 'doctypes' -import { DateTime } from 'luxon' - -export default class ProfileService { - private readonly _client: Client - - constructor(_client: Client) { - this._client = _client - } - /** - * Retrieve Profile from the ProfileEntity - * @param {ProfileEntity} profileEntity - * @returns {Profile} - */ - private parseProfileEntityToProfile(profileEntity: ProfileEntity): Profile { - const profile: Profile = { - ...profileEntity, - haveSeenOldFluidModal: - typeof profileEntity.haveSeenOldFluidModal === 'string' - ? DateTime.fromISO(profileEntity.haveSeenOldFluidModal, { - zone: 'utc', - }) - : profileEntity.haveSeenOldFluidModal, - monthlyAnalysisDate: - typeof profileEntity.monthlyAnalysisDate === 'string' - ? DateTime.fromISO(profileEntity.monthlyAnalysisDate, { - zone: 'utc', - }) - : profileEntity.monthlyAnalysisDate, - lastConnectionDate: DateTime.fromISO(profileEntity.lastConnectionDate, { - zone: 'utc', - }), - } - return profile - } - - public async getProfile(): Promise<Profile | null> { - const query: QueryDefinition = Q(PROFILE_DOCTYPE) - const { - data: [profile], - }: QueryResult<ProfileEntity[]> = await this._client.query(query.limitBy(1)) - const profileEntity: ProfileEntity | null = profile ? profile : null - if (profileEntity) { - return this.parseProfileEntityToProfile(profileEntity) - } - return null - } - - public async updateProfile( - attributes: Partial<Profile> - ): Promise<Profile | null> { - const query: QueryDefinition = Q(PROFILE_DOCTYPE) - const { - data: [doc], - }: QueryResult<ProfileEntity[]> = await this._client.query(query.limitBy(1)) - const { - data: profileEntity, - }: QueryResult<ProfileEntity | null> = await this._client.save({ - ...doc, - ...attributes, - }) - if (profileEntity) { - return this.parseProfileEntityToProfile(profileEntity) - } - return null - } -} +import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client' +import { Profile, ProfileEntity } from 'models' +import { PROFILE_DOCTYPE } from 'doctypes' +import { DateTime } from 'luxon' + +export default class ProfileService { + private readonly _client: Client + + constructor(_client: Client) { + this._client = _client + } + /** + * Retrieve Profile from the ProfileEntity + * @param {ProfileEntity} profileEntity + * @returns {Profile} + */ + private parseProfileEntityToProfile(profileEntity: ProfileEntity): Profile { + const profile: Profile = { + ...profileEntity, + GCUApprovalDate: + typeof profileEntity.GCUApprovalDate === 'string' + ? DateTime.fromISO(profileEntity.GCUApprovalDate, { + zone: 'utc', + }) + : profileEntity.GCUApprovalDate, + haveSeenOldFluidModal: + typeof profileEntity.haveSeenOldFluidModal === 'string' + ? DateTime.fromISO(profileEntity.haveSeenOldFluidModal, { + zone: 'utc', + }) + : profileEntity.haveSeenOldFluidModal, + monthlyAnalysisDate: + typeof profileEntity.monthlyAnalysisDate === 'string' + ? DateTime.fromISO(profileEntity.monthlyAnalysisDate, { + zone: 'utc', + }) + : profileEntity.monthlyAnalysisDate, + lastConnectionDate: DateTime.fromISO(profileEntity.lastConnectionDate, { + zone: 'utc', + }), + } + return profile + } + + public async getProfile(): Promise<Profile | null> { + const query: QueryDefinition = Q(PROFILE_DOCTYPE) + const { + data: [profile], + }: QueryResult<ProfileEntity[]> = await this._client.query(query.limitBy(1)) + const profileEntity: ProfileEntity | null = profile ? profile : null + if (profileEntity) { + return this.parseProfileEntityToProfile(profileEntity) + } + return null + } + + public async updateProfile( + attributes: Partial<Profile> + ): Promise<Profile | null> { + const query: QueryDefinition = Q(PROFILE_DOCTYPE) + const { + data: [doc], + }: QueryResult<ProfileEntity[]> = await this._client.query(query.limitBy(1)) + const { + data: profileEntity, + }: QueryResult<ProfileEntity | null> = await this._client.save({ + ...doc, + ...attributes, + }) + if (profileEntity) { + return this.parseProfileEntityToProfile(profileEntity) + } + return null + } +} diff --git a/src/store/profile/profile.reducer.ts b/src/store/profile/profile.reducer.ts index 3f4c39056..4d8391817 100644 --- a/src/store/profile/profile.reducer.ts +++ b/src/store/profile/profile.reducer.ts @@ -1,66 +1,70 @@ -import { Reducer } from 'redux' -import { - UPDATE_PROFILE, - ProfileActionTypes, -} from 'store/profile/profile.actions' -import { Profile } from 'models' -import { DateTime } from 'luxon' -import { - ConstructionYear, - Floor, - HotWaterEquipment, - HousingType, - IndividualOrCollective, - OutsideFacingWalls, - ThreeChoicesAnswer, -} from 'enum/profileType.enum' -import { FluidType } from 'enum/fluid.enum' - -const initialState: Profile = { - id: '', - ecogestureHash: '', - challengeHash: '', - duelHash: '', - quizHash: '', - explorationHash: '', - isFirstConnection: false, - lastConnectionDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), - haveSeenOldFluidModal: true, - haveSeenLastAnalysis: true, - sendAnalysisNotification: false, - monthlyAnalysisDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), - isProfileTypeCompleted: false, - profileType: { - housingType: HousingType.APPARTMENT, - constructionYear: ConstructionYear.AFTER_1999, - area: 35, - occupantsNumber: 1, - outsideFacingWalls: OutsideFacingWalls.ONE, - floor: Floor.INTERMEDIATE_FLOOR, - heating: IndividualOrCollective.COLLECTIVE, - coldWater: IndividualOrCollective.INDIVIDUAL, - hotWater: IndividualOrCollective.INDIVIDUAL, - individualInsulationWork: [], - hasInstalledVentilation: ThreeChoicesAnswer.NO, - hasReplacedHeater: ThreeChoicesAnswer.NO, - hotWaterEquipment: HotWaterEquipment.OTHER, - warmingFluid: FluidType.ELECTRICITY, - hotWaterFluid: FluidType.ELECTRICITY, - cookingFluid: FluidType.GAS, - }, -} - -export const profileReducer: Reducer<Profile> = ( - state = initialState, - action: ProfileActionTypes -): Profile => { - switch (action.type) { - case UPDATE_PROFILE: - return { - ...state, - ...action.payload, - } - default: - return state - } -} +import { Reducer } from 'redux' +import { + UPDATE_PROFILE, + ProfileActionTypes, +} from 'store/profile/profile.actions' +import { Profile } from 'models' +import { DateTime } from 'luxon' +import { + ConstructionYear, + Floor, + HotWaterEquipment, + HousingType, + IndividualOrCollective, + OutsideFacingWalls, + ThreeChoicesAnswer, +} from 'enum/profileType.enum' +import { FluidType } from 'enum/fluid.enum' + +const initialState: Profile = { + id: '', + ecogestureHash: '', + challengeHash: '', + duelHash: '', + quizHash: '', + explorationHash: '', + isFirstConnection: false, + GCUApprovalDate: null, + lastConnectionDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), + haveSeenOldFluidModal: true, + haveSeenLastAnalysis: true, + sendAnalysisNotification: false, + monthlyAnalysisDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), + isProfileTypeCompleted: false, + profileType: { + housingType: HousingType.APPARTMENT, + constructionYear: ConstructionYear.AFTER_1999, + area: 35, + occupantsNumber: 1, + outsideFacingWalls: OutsideFacingWalls.ONE, + floor: Floor.INTERMEDIATE_FLOOR, + heating: IndividualOrCollective.COLLECTIVE, + coldWater: IndividualOrCollective.INDIVIDUAL, + hotWater: IndividualOrCollective.INDIVIDUAL, + individualInsulationWork: [], + hasInstalledVentilation: ThreeChoicesAnswer.NO, + hasReplacedHeater: ThreeChoicesAnswer.NO, + hotWaterEquipment: HotWaterEquipment.OTHER, + warmingFluid: FluidType.ELECTRICITY, + hotWaterFluid: FluidType.ELECTRICITY, + cookingFluid: FluidType.GAS, + }, + tutorial: { + isWelcomeSeen: false, + }, +} + +export const profileReducer: Reducer<Profile> = ( + state = initialState, + action: ProfileActionTypes +): Profile => { + switch (action.type) { + case UPDATE_PROFILE: + return { + ...state, + ...action.payload, + } + default: + return state + } +} diff --git a/tests/__mocks__/profile.mock.ts b/tests/__mocks__/profile.mock.ts index 543663b7f..701a3f02e 100644 --- a/tests/__mocks__/profile.mock.ts +++ b/tests/__mocks__/profile.mock.ts @@ -21,6 +21,7 @@ export const profileData: Profile = { quizHash: '1136feb6185c7643e071d14180c0e95782aa4ba3', explorationHash: '1136feb6185c7643e071d14180c0e95782aa4ba3', isFirstConnection: true, + GCUApprovalDate: null, lastConnectionDate: DateTime.fromISO('2020-11-03T00:00:00.000Z', { zone: 'utc', }), @@ -49,4 +50,7 @@ export const profileData: Profile = { cookingFluid: FluidType.GAS, }, isProfileTypeCompleted: false, + tutorial: { + isWelcomeSeen: false, + }, } diff --git a/tests/__mocks__/store.ts b/tests/__mocks__/store.ts index e43fab87d..d13843c47 100644 --- a/tests/__mocks__/store.ts +++ b/tests/__mocks__/store.ts @@ -102,6 +102,7 @@ export const mockInitialProfileState: Profile = { quizHash: '', explorationHash: '', isFirstConnection: false, + GCUApprovalDate: null, lastConnectionDate: DateTime.fromISO('0000-01-01T00:00:00.000Z'), haveSeenOldFluidModal: true, haveSeenLastAnalysis: true, @@ -126,6 +127,9 @@ export const mockInitialProfileState: Profile = { hotWaterFluid: FluidType.ELECTRICITY, cookingFluid: FluidType.GAS, }, + tutorial: { + isWelcomeSeen: false, + }, } export const mockInitialChartState: ChartState = { -- GitLab