diff --git a/src/components/Challenge/ChallengeCardOnGoing.tsx b/src/components/Challenge/ChallengeCardOnGoing.tsx index 89d59adbe215169b4dd0846caaf32f8d062e8554..4b3585a0e7496d19d75e5430cc5bb171108cdd26 100644 --- a/src/components/Challenge/ChallengeCardOnGoing.tsx +++ b/src/components/Challenge/ChallengeCardOnGoing.tsx @@ -43,7 +43,7 @@ const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({ ) const { fluidTypes } = useSelector((state: AppStore) => state.ecolyo.global) - //To be removed when action and missions will be done + //To be removed when action and explorations will be done const winStars = async () => { const challengeService = new ChallengeService(client) const updatedChallenge = await challengeService.updateUserChallenge( @@ -51,7 +51,7 @@ const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({ ...userChallenge, progress: { ...userChallenge.progress, - missionProgress: 5, + explorationProgress: 5, actionProgress: 5, }, }, @@ -152,22 +152,22 @@ const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({ </div> <div className={classNames('smallCard', { - ['finished']: userChallenge.progress.missionProgress === 5, + ['finished']: userChallenge.progress.explorationProgress === 5, })} onClick={winStars} > <StyledIcon className="cardIcon" icon={ - userChallenge.progress.missionProgress === 5 + userChallenge.progress.explorationProgress === 5 ? circleChecked : circleUnchecked } size={25} /> <div className="content"> - <span>{t('challenge.card.ongoing.mission')}</span> - <StarsContainer result={userChallenge.progress.missionProgress} /> + <span>{t('challenge.card.ongoing.exploration')}</span> + <StarsContainer result={userChallenge.progress.explorationProgress} /> </div> </div> <div @@ -191,7 +191,7 @@ const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({ </div> </div> {userChallenge.progress.actionProgress + - userChallenge.progress.missionProgress + + userChallenge.progress.explorationProgress + userChallenge.progress.quizProgress >= userChallenge.target && userChallenge.duel.state === UserDuelState.UNLOCKED ? ( @@ -228,7 +228,7 @@ const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({ <StyledIcon icon={circleStar} size={30} /> <span className="blueNumber">{`${userChallenge.progress .quizProgress + - userChallenge.progress.missionProgress + + userChallenge.progress.explorationProgress + userChallenge.progress.actionProgress} `}</span> <span>{` / ${userChallenge.target}`}</span> </p> diff --git a/src/components/Challenge/StarsContainer.tsx b/src/components/Challenge/StarsContainer.tsx index 0814f7d6932e39d3acd3b4fd2191f9134be408d6..7e5d77a00ef7f99f0d2c4e212c722e66065ef61a 100644 --- a/src/components/Challenge/StarsContainer.tsx +++ b/src/components/Challenge/StarsContainer.tsx @@ -16,7 +16,7 @@ const StarsContainer: React.FC<StarsContainerProps> = ({ const [elements] = useState<string[]>([]) useEffect(() => { const renderStars = () => { - //To be removed when action and missions will be done + //To be removed when action and explorations will be done if (result === 5) { elements.splice(0, elements.length) } diff --git a/src/components/Challenge/__snapshots__/ChallengeCard.spec.tsx.snap b/src/components/Challenge/__snapshots__/ChallengeCard.spec.tsx.snap index a7f2f8b6afa2b889dab38b587c301a20c6ca7b8a..a450c77fca31666c6d1e0428bd57a0c8358db32f 100644 --- a/src/components/Challenge/__snapshots__/ChallengeCard.spec.tsx.snap +++ b/src/components/Challenge/__snapshots__/ChallengeCard.spec.tsx.snap @@ -30,7 +30,7 @@ exports[`ChallengeCard component should be rendered correctly 1`] = ` "id": "CHALLENGE0002", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { diff --git a/src/components/Challenge/__snapshots__/ChallengeCardDone.spec.tsx.snap b/src/components/Challenge/__snapshots__/ChallengeCardDone.spec.tsx.snap index a32e3ff0aac95f29c141ce43950ff46b28cb6c22..9047c191306062fb87d2c7df02f861f128b3dbd3 100644 --- a/src/components/Challenge/__snapshots__/ChallengeCardDone.spec.tsx.snap +++ b/src/components/Challenge/__snapshots__/ChallengeCardDone.spec.tsx.snap @@ -36,7 +36,7 @@ exports[`ChallengeCardDone component should be rendered correctly 1`] = ` > Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, } diff --git a/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap b/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap index d624e0f8f2bd80c87131f724ba5b54f708a68f95..1457a2ee8292544e04522fc03af81439ee24ffed 100644 --- a/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap +++ b/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap @@ -53,7 +53,7 @@ exports[`ChallengeView component should be rendered correctly 1`] = ` "id": "CHALLENGE0001", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { @@ -182,7 +182,7 @@ exports[`ChallengeView component should be rendered correctly 1`] = ` "id": "CHALLENGE0002", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { @@ -311,7 +311,7 @@ exports[`ChallengeView component should be rendered correctly 1`] = ` "id": "CHALLENGE0003", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { @@ -440,7 +440,7 @@ exports[`ChallengeView component should be rendered correctly 1`] = ` "id": "CHALLENGE0004", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { @@ -569,7 +569,7 @@ exports[`ChallengeView component should be rendered correctly 1`] = ` "id": "CHALLENGE0005", "progress": Object { "actionProgress": 0, - "missionProgress": 0, + "explorationProgress": 0, "quizProgress": 0, }, "quiz": Object { diff --git a/src/db/mission.json b/src/db/explorationEntity.json similarity index 78% rename from src/db/mission.json rename to src/db/explorationEntity.json index cc365ef879f64bc4304e10bdc36a451dd855479e..f947a49f405933e64aca687cb378e07e88e512df 100644 --- a/src/db/mission.json +++ b/src/db/explorationEntity.json @@ -1,79 +1,79 @@ [ { - "_id": "MISSION001", + "_id": "EXPLORATION001", "state": 0, "description": "Se connecter 3 fois à Ecolyo", "target": 3, "type": 0, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [], "priority_by_condition": 1 }, { - "_id": "MISSION002", + "_id": "EXPLORATION002", "state": 0, "description": "Contrôle du nuage", "target": 1, "type": 3, "date": null, - "ecogesture_id": 0032, + "ecogesture_id": "0032", "fluid_config": [], "priority_by_condition": 1 }, { - "_id": "MISSION003", + "_id": "EXPLORATION003", "state": 0, "description": "Parler en bien d’Ecolyo à un ami (quitte à mentir)", "target": 1, "type": 0, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [], "priority_by_condition": 1 }, { - "_id": "MISSION004", + "_id": "EXPLORATION004", "state": 0, "description": "Allez voir combien vous avez consommez le 24 décembre 2020", "target": 1, "type": 2, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [], "priority_by_condition": 1 }, { - "_id": "MISSION005", + "_id": "EXPLORATION005", "state": 0, "description": "Nous envoyer un feedback", "target": 1, "type": 1, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [], "priority_by_condition": 1 }, { - "_id": "MISSION006", + "_id": "EXPLORATION006", "state": 0, "description": "Dévérrouiller les données électricité à la demi-heure", "target": 1, "type": 1, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [0], "priority_by_condition": 1 }, { - "_id": "MISSION007", + "_id": "EXPLORATION007", "state": 0, "description": "Mettre l'appli Ecolyo en favoris (rappel des raccourcis)", "target": 1, "type": 0, "date": null, - "ecogesture_id": 0, + "ecogesture_id": "", "fluid_config": [], "priority_by_condition": 1 } -] \ No newline at end of file +] diff --git a/src/doctypes/com-grandlyon-ecolyo-exploration.ts b/src/doctypes/com-grandlyon-ecolyo-exploration.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c9cb4f69d4d8edbafba6e4a554c14fc0bd5dd3d --- /dev/null +++ b/src/doctypes/com-grandlyon-ecolyo-exploration.ts @@ -0,0 +1 @@ +export const EXPLORATION_DOCTYPE = 'com.grandlyon.ecolyo.exploration' diff --git a/src/doctypes/com-grandlyon-ecolyo-mission.ts b/src/doctypes/com-grandlyon-ecolyo-mission.ts deleted file mode 100644 index adeeea15f4c2c97ecfa6448d657bc5d9482cbcee..0000000000000000000000000000000000000000 --- a/src/doctypes/com-grandlyon-ecolyo-mission.ts +++ /dev/null @@ -1 +0,0 @@ -export const MISSION_DOCTYPE = 'com.grandlyon.ecolyo.mission' diff --git a/src/doctypes/index.ts b/src/doctypes/index.ts index 5ef8f106b3699d99acfb75d56270cef5bcedc5c2..5c1f91d059ae95cdf2f2096a41e7601fba43331f 100644 --- a/src/doctypes/index.ts +++ b/src/doctypes/index.ts @@ -13,7 +13,7 @@ import { CHALLENGE_DOCTYPE } from './com-grandlyon-ecolyo-challenge' import { USERCHALLENGE_DOCTYPE } from './com-grandlyon-ecolyo-userchallenge' import { DUEL_DOCTYPE } from './com-grandlyon-ecolyo-duel' import { QUIZ_DOCTYPE } from './com-grandlyon-ecolyo-quiz' -import { MISSION_DOCTYPE } from './com-grandlyon-ecolyo-mission' +import { EXPLORATION_DOCTYPE } from './com-grandlyon-ecolyo-exploration' // the documents schema, necessary for CozyClient const doctypes = { @@ -69,8 +69,8 @@ const doctypes = { doctype: DUEL_DOCTYPE, type: 'has-one', }, - mission: { - doctype: MISSION_DOCTYPE, + exploration: { + doctype: EXPLORATION_DOCTYPE, type: 'has-one', }, }, @@ -90,8 +90,8 @@ const doctypes = { attributes: {}, relationships: {}, }, - mission: { - doctype: MISSION_DOCTYPE, + exploration: { + doctype: EXPLORATION_DOCTYPE, attributes: {}, relationships: {}, }, @@ -127,4 +127,4 @@ export * from './com-grandlyon-ecolyo-challenge' export * from './com-grandlyon-ecolyo-userchallenge' export * from './com-grandlyon-ecolyo-duel' export * from './com-grandlyon-ecolyo-quiz' -export * from './com-grandlyon-ecolyo-mission' +export * from './com-grandlyon-ecolyo-exploration' diff --git a/src/enum/userChallenge.enum.ts b/src/enum/userChallenge.enum.ts index c7fec8bd252368785fe91ce8e10632b3639ac2a7..b9d8796da67dc554a5f6540a3a842f4db687e017 100644 --- a/src/enum/userChallenge.enum.ts +++ b/src/enum/userChallenge.enum.ts @@ -11,7 +11,7 @@ export enum UserChallengeUpdateFlag { QUIZ_DONE = 22, QUIZ_RESET = 23, QUIZ_UPDATE = 24, - MISSION = 30, + EXPLORATION = 30, } export enum UserChallengeState { diff --git a/src/enum/userMission.enum.ts b/src/enum/userExploration.enum.ts similarity index 59% rename from src/enum/userMission.enum.ts rename to src/enum/userExploration.enum.ts index d7408e9e2b738baafdf5415ca8ccf022c370de73..606f4a2f53b6ce2e5dbd5f3cb10927766ad92d5f 100644 --- a/src/enum/userMission.enum.ts +++ b/src/enum/userExploration.enum.ts @@ -1,10 +1,10 @@ -export enum UserMissionState { +export enum UserExplorationState { UNLOCKED = 0, ONGOING = 1, DONE = 2, } -export enum UserMissionType { +export enum UserExplorationType { DECLARATIVE = 0, ACTION = 1, CONSUMPTION = 2, diff --git a/src/locales/fr.json b/src/locales/fr.json index bc8655630283d27b90db097b892237656dc05602..2471a73cb8f57b2431caad1034a5d382c6038ceb 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -312,7 +312,7 @@ }, "ongoing": { "quiz": "Quiz", - "mission": "Missions", + "exploration": "Explorations", "action": "Actions", "duel": "Duel Final", "result": "Résultat", diff --git a/src/models/challenge.model.ts b/src/models/challenge.model.ts index 24bd6a93be1ab6cf5c2dd1d28a90f8be79334be5..dcc2c95ea33a6e8d7632e830ba178b5fb32ec571 100644 --- a/src/models/challenge.model.ts +++ b/src/models/challenge.model.ts @@ -10,8 +10,8 @@ import { Dataload, QuizEntity, UserQuiz, - MissionEntity, - UserMission, + ExplorationEntity, + UserExploration, } from 'models' export interface ChallengeState { @@ -26,12 +26,12 @@ export interface ChallengeEntity { target: number duel: DuelEntity | null quiz: QuizEntity | null - mission: MissionEntity | null + exploration: ExplorationEntity | null } export interface ChallengeProgress { quizProgress: number - missionProgress: number + explorationProgress: number actionProgress: number } @@ -47,7 +47,7 @@ export interface UserChallengeEntity { startDate: string | null endingDate: string | null quiz: UserQuiz - mission: UserMission + exploration: UserExploration } export interface UserChallenge diff --git a/src/models/exploration.model.ts b/src/models/exploration.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..fb8aa992acb67c18a87e44f8d9ecaf89e080ab6e --- /dev/null +++ b/src/models/exploration.model.ts @@ -0,0 +1,23 @@ +import { + UserExplorationState, + UserExplorationType, +} from 'enum/userExploration.enum' +import { FluidType } from 'enum/fluid.enum' +import { DateTime } from 'luxon' + +export interface ExplorationEntity { + id: string + state: UserExplorationState + description: string + target: number + type: UserExplorationType + date: string | null + ecogesture_id: string + fluid_condition: FluidType[] + priority_by_condition: number +} + +export interface UserExploration extends Omit<ExplorationEntity, 'date'> { + progress: number + date: DateTime | null +} diff --git a/src/models/index.ts b/src/models/index.ts index 9f78f17d87b88b25033d5a39cb46937a939609a3..13b495ea0f48bb0d9a2db486987cec546c28f3a1 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -13,7 +13,7 @@ export * from './konnector.model' export * from './modal.model' export * from './profile.model' export * from './quiz.model' -export * from './mission.model' +export * from './exploration.model' export * from './relation.model' export * from './report.model' export * from './timePeriod.model' diff --git a/src/models/mission.model.ts b/src/models/mission.model.ts deleted file mode 100644 index 3df2ea1a1ee970ab0ef4cb6516e02d4e59f079b0..0000000000000000000000000000000000000000 --- a/src/models/mission.model.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { UserMissionState, UserMissionType } from 'enum/userMission.enum' -import { FluidType } from 'enum/fluid.enum' -import { DateTime } from 'luxon' - -export interface MissionEntity { - id: string - state: UserMissionState - description: string - target: number - type: UserMissionType - date: string | null - ecogesture_id: number - fluid_condition: FluidType[] - priority_by_condition: number -} - -export interface UserMission extends Omit<MissionEntity, 'date'> { - progress: number - date: DateTime | null -} diff --git a/src/services/challenge.service.spec.ts b/src/services/challenge.service.spec.ts index d043db38b8c4151894cb56d350e844eada5ffd74..ad46483029d17834ef2c96be2311d3dc9e1da9e1 100644 --- a/src/services/challenge.service.spec.ts +++ b/src/services/challenge.service.spec.ts @@ -65,7 +65,7 @@ describe('Challenge service', () => { state: UserChallengeState.LOCKED, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, success: UserChallengeSuccess.ONGOING, diff --git a/src/services/challenge.service.ts b/src/services/challenge.service.ts index 81123565031347624b192fa5d75675340c07f988..603551b7bbad32c1bcb4c068361220df0097aa50 100644 --- a/src/services/challenge.service.ts +++ b/src/services/challenge.service.ts @@ -108,7 +108,7 @@ export default class ChallengeService { state: UserChallengeState.LOCKED, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, success: UserChallengeSuccess.ONGOING, @@ -259,7 +259,7 @@ export default class ChallengeService { ): Promise<UserChallenge> { userChallenge.state = UserChallengeState.ONGOING userChallenge.progress.actionProgress = 0 - userChallenge.progress.missionProgress = 0 + userChallenge.progress.explorationProgress = 0 userChallenge.progress.quizProgress = 0 userChallenge.startDate = DateTime.local() .setZone('utc', { diff --git a/src/services/exploration.service.spec.ts b/src/services/exploration.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..68e96661709bad22515e6ec245189742e9449ff6 --- /dev/null +++ b/src/services/exploration.service.spec.ts @@ -0,0 +1,122 @@ +import { QueryResult } from 'cozy-client' +import { UserExploration, ExplorationEntity } from 'models' +import { + allExplorationEntities, + explorationEntity, + UserExplorationUnlocked, + UserExplorationDone, + UserExplorationStarted, +} from '../../test/__mocks__/explorationData.mock' +import mockClient from '../../test/__mocks__/client' +import ExplorationService from './exploration.service' + +describe('Exploration service', () => { + const explorationService = new ExplorationService(mockClient) + + describe('getAllExplorationEntities method', () => { + it('should return all exploration entity', async () => { + const mockQueryResult: QueryResult<ExplorationEntity[]> = { + data: allExplorationEntities, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await explorationService.getAllExplorationEntities() + expect(result).toEqual(allExplorationEntities) + }) + }) + + describe('getExplorationEntityById method', () => { + it('should return one exploration by id', async () => { + const mockQueryResult: QueryResult<ExplorationEntity[]> = { + data: [explorationEntity], + bookmark: '', + next: false, + skip: 0, + } + const explorationId = 'EXPLORATION001' + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await explorationService.getExplorationEntityById( + explorationId + ) + expect(result).toEqual(explorationEntity) + }) + }) + + describe('deleteAllExplorationEntities method', () => { + it('should delete all exploration entities', async () => { + const mockQueryResult: QueryResult<ExplorationEntity[]> = { + data: allExplorationEntities, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + + const result = await explorationService.deleteAllExplorationEntities() + expect(result).toBeTruthy() + }) + + it('should throw an error because destroy failed', async () => { + const mockQueryResult: QueryResult<ExplorationEntity[]> = { + data: allExplorationEntities, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + mockClient.destroy.mockRejectedValue(new Error()) + try { + await explorationService.deleteAllExplorationEntities() + } catch (error) { + expect(error).toEqual(new Error()) + } + }) + }) + + describe('parseExplorationEntityToUserExploration method', () => { + it('should return the userExploration from a explorationEntity', () => { + const result = explorationService.parseExplorationEntityToUserExploration( + explorationEntity + ) + const mockUpdatedExploration: UserExploration = { + ...explorationEntity, + progress: 0, + date: result.date, + } + expect(result).toEqual(mockUpdatedExploration) + }) + }) + + describe('getUserExplorationfromExplorationEntities method', () => { + it('should return the userExploration from a explorationEntity', () => { + const searchId = 'EXPLORATION001' + const result = explorationService.getUserExplorationfromExplorationEntities( + allExplorationEntities, + searchId + ) + const updatedUserExploration = { + ...UserExplorationUnlocked, + date: result.date, + } + expect(result).toEqual(updatedUserExploration) + }) + }) + describe('startUserExploration Method', () => { + it('should return the started userExploration', async () => { + const result = await explorationService.startUserExploration( + UserExplorationUnlocked + ) + expect(result).toEqual(UserExplorationStarted) + }) + }) + describe('endUserExploration Method', () => { + it('should return the finished userExploration', async () => { + const result = await explorationService.endUserExploration( + UserExplorationStarted + ) + expect(result).toEqual(UserExplorationDone) + }) + }) +}) diff --git a/src/services/exploration.service.ts b/src/services/exploration.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..f54dabb5d01aabef9eb3c7d56d2735e4b2895d31 --- /dev/null +++ b/src/services/exploration.service.ts @@ -0,0 +1,170 @@ +/* eslint-disable @typescript-eslint/camelcase */ +import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client' +import { EXPLORATION_DOCTYPE } from 'doctypes' +import { + UserExplorationState, + UserExplorationType, +} from 'enum/userExploration.enum' +import { DateTime } from 'luxon' +import { ExplorationEntity, UserExploration } from 'models' + +export default class ExplorationService { + private readonly _client: Client + + constructor(_client: Client) { + this._client = _client + } + + /** + * Retrieve all exploration entities from db + * @returns {ExplorationEntity[]} + */ + public async getAllExplorationEntities(): Promise<ExplorationEntity[]> { + const query: QueryDefinition = Q(EXPLORATION_DOCTYPE) + const { + data: explorations, + }: QueryResult<ExplorationEntity[]> = await this._client.query(query) + return explorations + } + + /** + * Retrieve exploration entities from db given the id + * + * @param {string} explorationId - ID of the searched exploration + * @returns {ExplorationEntity} + */ + public async getExplorationEntityById( + explorationId: string + ): Promise<ExplorationEntity> { + const query: QueryDefinition = Q(EXPLORATION_DOCTYPE) + .where({ _id: explorationId }) + .limitBy(1) + const { data }: QueryResult<ExplorationEntity[]> = await this._client.query( + query + ) + return data && data[0] + } + + /** + * Delete all exploration entities from the db + * @returns {boolean} - true when deleted with success + * @throws {Error} + */ + public async deleteAllExplorationEntities(): Promise<boolean> { + try { + const explorations = await this.getAllExplorationEntities() + if (!explorations) return true + for (let index = 0; index < explorations.length; index++) { + await this._client.destroy(explorations[index]) + } + return true + } catch (err) { + throw err + } + } + + /** + * Return exploration created from exploration entity + * @param {ExplorationEntity[]} explorationEntityList - userExploration to update + * @param {string} searchId - userExploration to update + * @returns {UserExploration} + */ + public getUserExplorationfromExplorationEntities( + explorationEntityList: ExplorationEntity[], + searchId: string + ): UserExploration { + let exploration: UserExploration = { + id: '', + state: UserExplorationState.UNLOCKED, + description: '', + target: 0, + type: UserExplorationType.DECLARATIVE, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + progress: 0, + } + if (explorationEntityList.length > 0) { + const explorationEntityIndex = explorationEntityList.findIndex( + entity => entity.id === searchId + ) + if (explorationEntityIndex >= 0) { + const explorationEntity: ExplorationEntity = + explorationEntityList[explorationEntityIndex] + exploration = this.parseExplorationEntityToUserExploration( + explorationEntity + ) + } + } + return exploration + } + + /** + * Return UserExploration created from ExplorationEntity + * @param {ExplorationEntity} + * @returns {UserExploration} + */ + public parseExplorationEntityToUserExploration( + exploration: ExplorationEntity + ): UserExploration { + const userExploration: UserExploration = { + ...exploration, + progress: 0, + date: DateTime.local().setZone('utc', { + keepLocalTime: true, + }), + } + return userExploration + } + + /** + * Return exploration with updated state to UserExplorationState.ONGOING + * @param {UserExploration} userExploration - userExploration to update + * @returns {UserExploration} + */ + public async startUserExploration( + userExploration: UserExploration + ): Promise<UserExploration> { + const updatedUserExploration: UserExploration = { + ...userExploration, + state: UserExplorationState.ONGOING, + } + return updatedUserExploration + } + + /** + * Return exploration with updated state to UserExplorationState.DONE + * @param {UserExploration} userExploration - userExploration to update + * @returns {UserExploration} + */ + public async endUserExploration( + userExploration: UserExploration + ): Promise<UserExploration> { + const updatedUserExploration: UserExploration = { + ...userExploration, + state: UserExplorationState.DONE, + progress: userExploration.type === UserExplorationType.ACTION ? 3 : 1, + } + return updatedUserExploration + } + + /** + * Return updated exploration + * @param {UserExploration} userExploration - userExploration to update + * @returns {UserExploration} + * @returns {questionIndex} + * @returns {questionResult} + */ + public async updateUserExploration( + userExploration: UserExploration + ): Promise<UserExploration> { + const updatedProgress = userExploration.progress++ + + const updatedUserExploration: UserExploration = { + ...userExploration, + progress: updatedProgress, + } + return updatedUserExploration + } +} diff --git a/src/services/mission.service.spec.ts b/src/services/mission.service.spec.ts deleted file mode 100644 index 89d4fc1656f630f61abcb8de1cd7450c1c41ba71..0000000000000000000000000000000000000000 --- a/src/services/mission.service.spec.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { QueryResult } from 'cozy-client' -// import { UserMission, MissionEntity } from 'models' -// // import { -// // allMissionEntities, -// // missionDefault, -// // missionEntity, -// // userMission, -// // UserMissionDone, -// // UserMissionReseted, -// // UserMissionStarted, -// // } from '../../test/__mocks__/missionData.mock' -// import mockClient from '../../test/__mocks__/client' -// import MissionService from './mission.service' - -// describe('Mission service', () => { -// const missionService = new MissionService(mockClient) - -// describe('getAllMissionEntities method', () => { -// it('should return all mission entity', async () => { -// const mockQueryResult: QueryResult<MissionEntity[]> = { -// data: allMissionEntities, -// bookmark: '', -// next: false, -// skip: 0, -// } -// mockClient.query.mockResolvedValueOnce(mockQueryResult) -// const result = await missionService.getAllMissionEntities() -// expect(result).toEqual(allMissionEntities) -// }) -// }) - -// describe('getMissionEntityById method', () => { -// it('should return one mission by id', async () => { -// const mockQueryResult: QueryResult<MissionEntity[]> = { -// data: [missionEntity], -// bookmark: '', -// next: false, -// skip: 0, -// } -// const missionId = 'MISSION001' -// mockClient.query.mockResolvedValueOnce(mockQueryResult) -// const result = await missionService.getMissionEntityById(missionId) -// expect(result).toEqual(missionEntity) -// }) -// }) - -// describe('deleteAllMissionEntities method', () => { -// it('should delete all mission entities', async () => { -// const mockQueryResult: QueryResult<MissionEntity[]> = { -// data: allMissionEntities, -// bookmark: '', -// next: false, -// skip: 0, -// } -// mockClient.query.mockResolvedValueOnce(mockQueryResult) - -// const result = await missionService.deleteAllMissionEntities() -// expect(result).toBeTruthy() -// }) - -// it('should throw an error because destroy failed', async () => { -// const mockQueryResult: QueryResult<MissionEntity[]> = { -// data: allMissionEntities, -// bookmark: '', -// next: false, -// skip: 0, -// } -// mockClient.query.mockResolvedValueOnce(mockQueryResult) -// mockClient.destroy.mockRejectedValue(new Error()) -// try { -// await missionService.deleteAllMissionEntities() -// } catch (error) { -// expect(error).toEqual(new Error()) -// } -// }) -// }) - -// describe('parseMissionEntityToUserMission method', () => { -// it('should return the userMission from a missionEntity', () => { -// const mockUpdatedMission: UserMission = {} - -// const result = missionService.parseMissionEntityToUserMission( -// missionEntity -// ) -// expect(result).toEqual(mockUpdatedMission) -// }) -// }) - -// describe('getUserMissionfromMissionEntities method', () => { -// it('should return the userMission from a missionEntity', () => { -// const searchId = 'MISSION001' - -// const result = missionService.getUserMissionfromMissionEntities( -// allMissionEntities, -// searchId -// ) -// expect(result).toEqual(userMission) -// }) -// }) -// describe('endUserMission Method', () => { -// it('should return the finished userMission', async () => { -// const result = await missionService.endUserMission(missionDefault) -// expect(result).toEqual(UserMissionDone) -// }) -// }) -// describe('startUserMission Method', () => { -// it('should return the started userMission', async () => { -// const result = await missionService.startUserMission(missionDefault) -// expect(result).toEqual(UserMissionStarted) -// }) -// }) -// describe('updateUserMission Method', () => { -// it('should return the userMission with updated result and correct answer to question', async () => {}) -// }) -// }) diff --git a/src/services/mission.service.ts b/src/services/mission.service.ts deleted file mode 100644 index 909c8af2fd1ff1ceb0bd0d83c68fb24bb22445a2..0000000000000000000000000000000000000000 --- a/src/services/mission.service.ts +++ /dev/null @@ -1,156 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client' -import { MISSION_DOCTYPE } from 'doctypes' -import { FluidType } from 'enum/fluid.enum' -import { UserMissionState, UserMissionType } from 'enum/userMission.enum' -import { DateTime } from 'luxon' -import { MissionEntity, UserMission } from 'models' - -export default class MissionService { - private readonly _client: Client - - constructor(_client: Client) { - this._client = _client - } - - /** - * Retrieve all mission entities from db - * @returns {MissionEntity[]} - */ - public async getAllMissionEntities(): Promise<MissionEntity[]> { - const query: QueryDefinition = Q(MISSION_DOCTYPE) - const { - data: missions, - }: QueryResult<MissionEntity[]> = await this._client.query(query) - return missions - } - - /** - * Retrieve mission entities from db given the id - * - * @param {string} missionId - ID of the searched mission - * @returns {MissionEntity} - */ - public async getMissionEntityById(missionId: string): Promise<MissionEntity> { - const query: QueryDefinition = Q(MISSION_DOCTYPE) - .where({ _id: missionId }) - .limitBy(1) - const { data }: QueryResult<MissionEntity[]> = await this._client.query( - query - ) - return data && data[0] - } - - /** - * Delete all mission entities from the db - * @returns {boolean} - true when deleted with success - * @throws {Error} - */ - public async deleteAllMissionEntities(): Promise<boolean> { - try { - const missions = await this.getAllMissionEntities() - if (!missions) return true - for (let index = 0; index < missions.length; index++) { - await this._client.destroy(missions[index]) - } - return true - } catch (err) { - throw err - } - } - - /** - * Return mission created from mission entity - * @param {MissionEntity[]} missionEntityList - userMission to update - * @param {string} searchId - userMission to update - * @returns {UserMission} - */ - public getUserMissionfromMissionEntities( - missionEntityList: MissionEntity[], - searchId: string - ): UserMission { - let mission: UserMission = { - id: '', - state: UserMissionState.UNLOCKED, - description: '', - target: 5, - type: UserMissionType.DECLARATIVE, - date: null, - ecogesture_id: 0, - fluid_condition: [FluidType.ELECTRICITY], - priority_by_condition: 1, - progress: 0, - } - if (missionEntityList.length > 0) { - const missionEntityIndex = missionEntityList.findIndex( - entity => entity.id === searchId - ) - if (missionEntityIndex >= 0) { - const missionEntity: MissionEntity = - missionEntityList[missionEntityIndex] - mission = this.parseMissionEntityToUserMission(missionEntity) - } - } - return mission - } - - /** - * Return UserMission created from MissionEntity - * @param {MissionEntity} - * @returns {UserMission} - */ - public parseMissionEntityToUserMission(mission: MissionEntity): UserMission { - const userMission: UserMission = { - ...mission, - progress: 0, - date: DateTime.local().setZone('utc', { - keepLocalTime: true, - }), - } - return userMission - } - - /** - * Return mission with updated state to UserMissionState.ONGOING - * @param {UserMission} userMission - userMission to update - * @returns {UserMission} - */ - public async startUserMission( - userMission: UserMission - ): Promise<UserMission> { - const updatedUserMission: UserMission = { - ...userMission, - state: UserMissionState.ONGOING, - } - return updatedUserMission - } - - /** - * Return mission with updated state to UserMissionState.DONE - * @param {UserMission} userMission - userMission to update - * @returns {UserMission} - */ - public async endUserMission(userMission: UserMission): Promise<UserMission> { - const updatedUserMission: UserMission = { - ...userMission, - state: UserMissionState.DONE, - } - return updatedUserMission - } - - /** - * Return mission with result and updated question or customQuestion if no index is passed - * @param {UserMission} userMission - userMission to update - * @returns {UserMission} - * @returns {questionIndex} - * @returns {questionResult} - */ - public async updateUserMission( - userMission: UserMission - ): Promise<UserMission> { - const updatedUserMission: UserMission = { - ...userMission, - } - return updatedUserMission - } -} diff --git a/test/__mocks__/explorationData.mock.ts b/test/__mocks__/explorationData.mock.ts new file mode 100644 index 0000000000000000000000000000000000000000..a1a0460db959d1ec61b636b2f1cca81841edbbc8 --- /dev/null +++ b/test/__mocks__/explorationData.mock.ts @@ -0,0 +1,136 @@ +/* eslint-disable @typescript-eslint/camelcase */ +import { + UserExplorationState, + UserExplorationType, +} from 'enum/userExploration.enum' +import { ExplorationEntity, UserExploration } from 'models' + +export const explorationEntity: ExplorationEntity = { + id: 'EXPLORATION001', + state: UserExplorationState.UNLOCKED, + description: 'Se connecter 3 fois à Ecolyo', + target: 3, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, +} + +export const allExplorationEntities: ExplorationEntity[] = [ + { + id: 'EXPLORATION001', + state: 0, + description: 'Se connecter 3 fois à Ecolyo', + target: 3, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION002', + state: 0, + description: 'Contrôle du nuage', + target: 1, + type: UserExplorationType.ECOGESTURE, + date: null, + ecogesture_id: '0032', + fluid_condition: [], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION003', + state: 0, + description: 'Parler en bien d’Ecolyo à un ami (quitte à mentir)', + target: 1, + type: UserExplorationType.DECLARATIVE, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION004', + state: 0, + description: 'Allez voir combien vous avez consommez le 24 décembre 2020', + target: 1, + type: UserExplorationType.CONSUMPTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION005', + state: 0, + description: 'Nous envoyer un feedback', + target: 1, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION006', + state: 0, + description: 'Dévérrouiller les données électricité à la demi-heure', + target: 1, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [0], + priority_by_condition: 1, + }, + { + id: 'EXPLORATION007', + state: 0, + description: "Mettre l'appli Ecolyo en favoris (rappel des raccourcis)", + target: 1, + type: UserExplorationType.DECLARATIVE, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + }, +] + +export const UserExplorationStarted: UserExploration = { + id: 'EXPLORATION001', + state: UserExplorationState.ONGOING, + description: 'Se connecter 3 fois à Ecolyo', + target: 3, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + progress: 0, +} +export const UserExplorationDone: UserExploration = { + id: 'EXPLORATION001', + state: UserExplorationState.DONE, + description: 'Se connecter 3 fois à Ecolyo', + target: 3, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + progress: 3, +} + +export const UserExplorationUnlocked: UserExploration = { + id: 'EXPLORATION001', + state: UserExplorationState.UNLOCKED, + description: 'Se connecter 3 fois à Ecolyo', + target: 3, + type: UserExplorationType.ACTION, + date: null, + ecogesture_id: '', + fluid_condition: [], + priority_by_condition: 1, + progress: 0, +} diff --git a/test/__mocks__/userChallengeData.mock.ts b/test/__mocks__/userChallengeData.mock.ts index f4aeba7035239d42226627bea68ca8e9645c66d1..cdda7c79b8a5bca0f10f92fe311461a3ee7d774e 100644 --- a/test/__mocks__/userChallengeData.mock.ts +++ b/test/__mocks__/userChallengeData.mock.ts @@ -4,6 +4,7 @@ import { } from 'enum/userChallenge.enum' import { UserChallenge } from 'models' import { duelData, duelDefault } from './duelData.mock' +import { UserExplorationUnlocked } from './explorationData.mock' import { quizDefault, userQuiz } from './quizData.mock' export const userChallengeData: UserChallenge[] = [ @@ -15,7 +16,7 @@ export const userChallengeData: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelData, @@ -23,6 +24,7 @@ export const userChallengeData: UserChallenge[] = [ startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0002', @@ -32,7 +34,7 @@ export const userChallengeData: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelData, @@ -40,6 +42,7 @@ export const userChallengeData: UserChallenge[] = [ startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0003', @@ -49,7 +52,7 @@ export const userChallengeData: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelData, @@ -57,6 +60,7 @@ export const userChallengeData: UserChallenge[] = [ startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0004', @@ -66,7 +70,7 @@ export const userChallengeData: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelData, @@ -74,6 +78,7 @@ export const userChallengeData: UserChallenge[] = [ startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0005', @@ -83,7 +88,7 @@ export const userChallengeData: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelData, @@ -91,6 +96,7 @@ export const userChallengeData: UserChallenge[] = [ startDate: null, endingDate: null, quiz: userQuiz, + exploration: UserExplorationUnlocked, }, ] @@ -103,7 +109,7 @@ export const userChallengeDefault: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelDefault, @@ -111,6 +117,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0002', @@ -120,7 +127,7 @@ export const userChallengeDefault: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelDefault, @@ -128,6 +135,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0003', @@ -137,7 +145,7 @@ export const userChallengeDefault: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelDefault, @@ -145,6 +153,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0004', @@ -154,7 +163,7 @@ export const userChallengeDefault: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelDefault, @@ -162,6 +171,7 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, + exploration: UserExplorationUnlocked, }, { id: 'CHALLENGE0005', @@ -171,7 +181,7 @@ export const userChallengeDefault: UserChallenge[] = [ target: 15, progress: { quizProgress: 0, - missionProgress: 0, + explorationProgress: 0, actionProgress: 0, }, duel: duelDefault, @@ -179,5 +189,6 @@ export const userChallengeDefault: UserChallenge[] = [ startDate: null, endingDate: null, quiz: quizDefault, + exploration: UserExplorationUnlocked, }, ]