Skip to content
Snippets Groups Projects
Commit 2f3e2889 authored by Hugo NOUTS's avatar Hugo NOUTS
Browse files

Merge branch 'features/splashscreen_enhancement' into 'dev'

feat: use of promise all for entities init

Closes #115

See merge request web-et-numerique/llle_project/ecolyo!328
parents 51e1c46b d3b7e377
Branches
Tags
1 merge request!328feat: use of promise all for entities init
import React, { useState, useEffect, ComponentType, ReactNode } from 'react'
import React, {
useState,
useEffect,
ComponentType,
ReactNode,
Dispatch,
} from 'react'
import { useClient } from 'cozy-client'
import classNames from 'classnames'
import { useDispatch } from 'react-redux'
......@@ -8,14 +14,19 @@ import {
toggleChallengeActionNotification,
toggleChallengeDuelNotification,
setFluidStatus,
GlobalActionTypes,
} from 'store/global/global.actions'
import { updateProfile } from 'store/profile/profile.actions'
import {
ProfileActionTypes,
updateProfile,
} from 'store/profile/profile.actions'
import {
setUserChallengeList,
setChallengeConsumption,
updateUserChallengeList,
ChallengeActionTypes,
} from 'store/challenge/challenge.actions'
import { setSelectedDate } from 'store/chart/chart.actions'
import { ChartActionTypes, setSelectedDate } from 'store/chart/chart.actions'
import InitializationService from 'services/initialization.service'
import './splashRoot.scss'
import { UserChallengeState } from 'enum/userChallenge.enum'
......@@ -54,7 +65,12 @@ const SplashRoot = ({
splashStart: false,
})
const [error, setError] = useState<Error | null>(null)
const dispatch = useDispatch()
const dispatch: Dispatch<
| ChallengeActionTypes
| ChartActionTypes
| GlobalActionTypes
| ProfileActionTypes
> = useDispatch()
useEffect(() => {
let timeoutSplash: NodeJS.Timeout
......@@ -76,58 +92,31 @@ const SplashRoot = ({
// Init index
await initializationService.initIndex()
// Init profile and update ecogestures, challenges, analysis
let profile = await initializationService.initProfile()
const profile = await initializationService.initProfile()
if (subscribed && profile) {
setValidExploration(UserExplorationID.EXPLORATION007)
const resultEcogesture = await initializationService.initEcogesture(
profile.ecogestureHash
)
if (
subscribed &&
resultEcogesture.result &&
resultEcogesture.profile
) {
profile = resultEcogesture.profile
}
const resultDuel = await initializationService.initDuelEntity(
profile.duelHash
)
if (subscribed && resultDuel.result && resultDuel.profile) {
profile = resultDuel.profile
}
const resultQuiz = await initializationService.initQuizEntity(
profile.quizHash
)
if (subscribed && resultQuiz.result && resultQuiz.profile) {
profile = resultQuiz.profile
}
const resultExploration = await initializationService.initExplorationEntity(
profile.explorationHash
)
if (
subscribed &&
resultExploration.result &&
resultExploration.profile
) {
profile = resultExploration.profile
}
const resultChallengeEntity = await initializationService.initChallengeEntity(
profile.challengeHash
)
if (
subscribed &&
resultChallengeEntity.result &&
resultChallengeEntity.profile
) {
profile = resultChallengeEntity.profile
}
const resultAnalysis = await initializationService.initAnalysis(
profile
)
if (subscribed && resultAnalysis.result && resultAnalysis.profile) {
profile = resultAnalysis.profile
}
const [
ecogestureHash,
duelHash,
quizHash,
challengeHash,
explorationHash,
analysisResult,
] = await Promise.all([
initializationService.initEcogesture(profile.ecogestureHash),
initializationService.initDuelEntity(profile.duelHash),
initializationService.initQuizEntity(profile.quizHash),
initializationService.initExplorationEntity(profile.challengeHash),
initializationService.initChallengeEntity(profile.explorationHash),
initializationService.initAnalysis(profile),
])
profile.ecogestureHash = ecogestureHash
profile.duelHash = duelHash
profile.quizHash = quizHash
profile.challengeHash = challengeHash
profile.explorationHash = explorationHash
profile.monthlyAnalysisDate = analysisResult.monthlyAnalysisDate
profile.haveSeenLastAnalysis = analysisResult.haveSeenLastAnalysis
dispatch(updateProfile(profile))
dispatch(toggleAnalysisNotification(!profile.haveSeenLastAnalysis))
}
......
......@@ -3,16 +3,25 @@ import { DateTime } from 'luxon'
import { UserChallenge } from 'models'
import InitializationService from './initialization.service'
import mockClient from '../../tests/__mocks__/client'
import { ecogesturesData } from '../../tests/__mocks__/ecogesturesData.mock'
import { profileData } from '../../tests/__mocks__/profile.mock'
import { fluidStatusData } from '../../tests/__mocks__/fluidStatusData.mock'
import ecogestureData from 'db/ecogestureData.json'
import challengeEntityData from 'db/challengeEntity.json'
import duelEntityData from 'db/duelEntity.json'
import quizEntityData from 'db/quizEntity.json'
import explorationEntityData from 'db/explorationEntity.json'
import { hashFile } from 'utils/hash'
import { getActualAnalysisDate } from 'utils/date'
import { FluidType } from 'enum/fluid.enum'
import { ecogesturesData } from '../../tests/__mocks__/ecogesturesData.mock'
import { profileData } from '../../tests/__mocks__/profile.mock'
import { fluidStatusData } from '../../tests/__mocks__/fluidStatusData.mock'
import { userChallengeData } from '../../tests/__mocks__/userChallengeData.mock'
import { graphData } from '../../tests/__mocks__/datachartData.mock'
import { allChallengeEntityData } from '../../tests/__mocks__/challengeEntity.mock'
import { allDuelEntity } from '../../tests/__mocks__/duelData.mock'
import { allQuizEntities } from '../../tests/__mocks__/quizData.mock'
import { allExplorationEntities } from '../../tests/__mocks__/explorationData.mock'
const mockCreateIndexKonnector = jest.fn()
jest.mock('./konnector.service', () => {
......@@ -54,41 +63,86 @@ jest.mock('./ecogesture.service', () => {
})
})
const mockGetKonnectorAccountStatus = jest.fn()
jest.mock('./konnectorStatus.service', () => {
const mockGetAllChallengeEntities = jest.fn()
const mockDeleteAllChallengeEntities = jest.fn()
const mockBuildUserChallengeList = jest.fn()
const mockGetUserChallengeDataload = jest.fn()
const mockUserChallengeUpdateFlag = jest.fn()
jest.mock('./challenge.service', () => {
return jest.fn(() => {
return {
getKonnectorAccountStatus: mockGetKonnectorAccountStatus,
getAllChallengeEntities: mockGetAllChallengeEntities,
deleteAllChallengeEntities: mockDeleteAllChallengeEntities,
buildUserChallengeList: mockBuildUserChallengeList,
getUserChallengeDataload: mockGetUserChallengeDataload,
updateUserChallenge: mockUserChallengeUpdateFlag,
}
})
})
const mockGetFluidStatus = jest.fn()
jest.mock('./fluid.service', () => {
const mockGetAllDuelEntities = jest.fn()
const mockDeleteAllDuelEntities = jest.fn()
jest.mock('./duel.service', () => {
return jest.fn(() => {
return {
getFluidStatus: mockGetFluidStatus,
getAllDuelEntities: mockGetAllDuelEntities,
deleteAllDuelEntities: mockDeleteAllDuelEntities,
}
})
})
const mockBuildUserChallengeList = jest.fn()
const mockGetUserChallengeDataload = jest.fn()
const mockUserChallengeUpdateFlag = jest.fn()
jest.mock('./challenge.service', () => {
const mockGetAllQuizEntities = jest.fn()
const mockDeleteAllQuizEntities = jest.fn()
jest.mock('./quiz.service', () => {
return jest.fn(() => {
return {
buildUserChallengeList: mockBuildUserChallengeList,
getUserChallengeDataload: mockGetUserChallengeDataload,
updateUserChallenge: mockUserChallengeUpdateFlag,
getAllQuizEntities: mockGetAllQuizEntities,
deleteAllQuizEntities: mockDeleteAllQuizEntities,
}
})
})
const mockGetAllExplorationEntities = jest.fn()
const mockDeleteAllExplorationEntities = jest.fn()
jest.mock('./exploration.service', () => {
return jest.fn(() => {
return {
getAllExplorationEntities: mockGetAllExplorationEntities,
deleteAllExplorationEntities: mockDeleteAllExplorationEntities,
}
})
})
const mockGetKonnectorAccountStatus = jest.fn()
jest.mock('./konnectorStatus.service', () => {
return jest.fn(() => {
return {
getKonnectorAccountStatus: mockGetKonnectorAccountStatus,
}
})
})
const mockGetFluidStatus = jest.fn()
jest.mock('./fluid.service', () => {
return jest.fn(() => {
return {
getFluidStatus: mockGetFluidStatus,
}
})
})
describe('Initialization service', () => {
const initializationService = new InitializationService(mockClient)
beforeEach(() => {
mockClient.query.mockClear()
mockClient.create.mockClear()
})
describe('initIndex method', () => {
beforeEach(() => {
mockCreateIndexKonnector.mockClear()
mockCreateIndexAccount.mockClear()
})
it('shoud return true when all indexes created', async () => {
const mockQueryResult: QueryResult<boolean> = {
data: true,
......@@ -101,7 +155,6 @@ describe('Initialization service', () => {
mockCreateIndexAccount.mockResolvedValueOnce(mockQueryResult)
await expect(initializationService.initIndex()).resolves.toBe(true)
})
it('shoud throw error when an index is not created', async () => {
const mockQueryResult: QueryResult<boolean> = {
data: true,
......@@ -119,6 +172,10 @@ describe('Initialization service', () => {
})
describe('initProfile method', () => {
beforeEach(() => {
mockGetProfile.mockClear()
mockUpdateProfile.mockClear()
})
it('shoud return the profil when existing', async () => {
mockGetProfile.mockResolvedValueOnce(profileData)
mockUpdateProfile.mockResolvedValueOnce(profileData)
......@@ -126,7 +183,6 @@ describe('Initialization service', () => {
profileData
)
})
it('shoud create and return the profil when no existing', async () => {
const mockQueryResult: QueryResult<boolean> = {
data: true,
......@@ -141,7 +197,6 @@ describe('Initialization service', () => {
profileData
)
})
it('shoud throw error when the profile is not created', async () => {
const mockQueryResult: QueryResult<null> = {
data: null,
......@@ -155,12 +210,10 @@ describe('Initialization service', () => {
new Error('initProfile: Profile not created')
)
})
it('shoud throw error when the profile could not be fetched', () => {
mockGetProfile.mockRejectedValueOnce(new Error())
expect(initializationService.initProfile()).rejects.toEqual(new Error())
})
it('shoud throw error when the profile failed to be created', () => {
mockGetProfile.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValueOnce(new Error())
......@@ -169,14 +222,18 @@ describe('Initialization service', () => {
})
describe('initEcoGesture method', () => {
it('shoud return true and profile = null when ecogestures hash is already up to date', async () => {
mockGetAllEcogestures.mockResolvedValue(ecogestureData)
await expect(
initializationService.initEcogesture(hashFile(ecogestureData))
).resolves.toEqual({ result: true, profile: null })
beforeEach(() => {
mockGetAllEcogestures.mockClear()
mockDeleteAllEcogestures.mockClear()
})
it('shoud return true and ecogestures when ecogestures are created', async () => {
it('shoud return hash when ecogestures hash is already up to date', async () => {
mockGetAllEcogestures.mockResolvedValueOnce(ecogestureData)
const hash = hashFile(ecogestureData)
await expect(initializationService.initEcogesture(hash)).resolves.toEqual(
hash
)
})
it('shoud return hash when ecogestures are created', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(ecogestureData)
......@@ -187,16 +244,11 @@ describe('Initialization service', () => {
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const mockProfile = {
...profileData,
ecogestureHash: hashFile(ecogestureData),
}
mockUpdateProfile.mockResolvedValueOnce(mockProfile)
await expect(
initializationService.initEcogesture(hashFile(ecogestureData))
).resolves.toEqual({ result: true, profile: mockProfile })
const hash = hashFile(ecogestureData)
await expect(initializationService.initEcogesture(hash)).resolves.toEqual(
hash
)
})
it('shoud throw an error when ecogestures should be created and created ecogestures number does not match', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(null)
......@@ -216,28 +268,14 @@ describe('Initialization service', () => {
)
)
})
it('shoud throw an error when ecogestures should be created and updateProfile failed', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(ecogestureData)
mockUpdateProfile.mockResolvedValueOnce(null)
await expect(
initializationService.initEcogesture(hashFile(ecogestureData))
).rejects.toThrow(new Error('initEcogesture: Profile not updated'))
})
it('shoud throw an error when ecogestures should be created and challenge creation failed', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(ecogestureData)
mockUpdateProfile.mockRejectedValueOnce(new Error())
it('shoud throw an error when ecogestures should be created and creation failed', async () => {
mockGetAllEcogestures.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValue(new Error())
await expect(
initializationService.initEcogesture(hashFile(ecogestureData))
).rejects.toThrow(new Error())
})
it('shoud return true and profil when ecogestures are updated', async () => {
it('shoud return hash when ecogestures are updated', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(ecogestureData)
.mockResolvedValueOnce(ecogestureData)
......@@ -249,17 +287,10 @@ describe('Initialization service', () => {
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const mockProfile = {
...profileData,
ecogestureHash: hashFile(ecogestureData),
}
mockUpdateProfile.mockResolvedValueOnce(mockProfile)
await expect(initializationService.initEcogesture('')).resolves.toEqual({
result: true,
profile: mockProfile,
})
await expect(initializationService.initEcogesture('')).resolves.toEqual(
hashFile(ecogestureData)
)
})
it('shoud throw an error when ecogestures should be updated and created ecogestures number does not match', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(ecogestureData)
......@@ -278,94 +309,468 @@ describe('Initialization service', () => {
)
)
})
it('shoud throw an error when ecogestures should be updated and updateProfile failed', async () => {
it('shoud throw an error when ecogestures should be updated and ecogestures creation failed', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(ecogestureData)
.mockResolvedValueOnce(ecogestureData)
mockDeleteAllEcogestures.mockResolvedValue(true)
mockUpdateProfile.mockResolvedValueOnce(null)
await expect(initializationService.initEcogesture('')).rejects.toThrow(
new Error('initEcogesture: Profile not updated')
mockClient.create.mockRejectedValueOnce(new Error())
expect(initializationService.initEcogesture('')).rejects.toThrow(
new Error()
)
})
})
it('shoud throw an error when ecogestures should be updated and ecogestures creation failed', async () => {
mockGetAllEcogestures
.mockResolvedValueOnce(ecogestureData)
.mockResolvedValueOnce(ecogestureData)
mockDeleteAllEcogestures.mockResolvedValue(true)
mockUpdateProfile.mockRejectedValueOnce(new Error())
expect(initializationService.initEcogesture('')).rejects.toThrow(
describe('initChallengeEntity method', () => {
beforeEach(() => {
mockGetAllChallengeEntities.mockClear()
mockDeleteAllChallengeEntities.mockClear()
})
it('shoud return hash when challenges hash is already up to date', async () => {
mockGetAllChallengeEntities.mockResolvedValueOnce(challengeEntityData)
const hash = hashFile(challengeEntityData)
await expect(
initializationService.initChallengeEntity(hash)
).resolves.toEqual(hash)
})
it('shoud return hash when challenge entities are created', async () => {
mockGetAllChallengeEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(challengeEntityData)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const hash = hashFile(challengeEntityData)
await expect(
initializationService.initChallengeEntity(hash)
).resolves.toEqual(hash)
})
it('shoud throw an error when challenge entities should be created and created challenge entities number does not match', async () => {
mockGetAllChallengeEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(allChallengeEntityData)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initChallengeEntity(hashFile(challengeEntityData))
).rejects.toThrow(
new Error(
'initChallengeEntity: Created challenge entities does not match'
)
)
})
it('shoud throw an error when challenge entities should be created and creation failed', async () => {
mockGetAllChallengeEntities.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValue(new Error())
await expect(
initializationService.initChallengeEntity(hashFile(challengeEntityData))
).rejects.toThrow(new Error())
})
it('shoud return hash when challenge entities are updated', async () => {
mockGetAllChallengeEntities
.mockResolvedValueOnce(challengeEntityData)
.mockResolvedValueOnce(challengeEntityData)
mockDeleteAllChallengeEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initChallengeEntity('')
).resolves.toEqual(hashFile(challengeEntityData))
})
it('shoud throw an error when challenge entities should be updated and created challenge entities number does not match', async () => {
mockGetAllChallengeEntities
.mockResolvedValueOnce(challengeEntityData)
.mockResolvedValueOnce(allChallengeEntityData)
mockDeleteAllChallengeEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initChallengeEntity('')
).rejects.toThrow(
new Error(
'initChallengeEntity: Created challenge entities does not match'
)
)
})
it('shoud throw an error when challenge entities should be updated and challenge entities creation failed', async () => {
mockGetAllChallengeEntities
.mockResolvedValueOnce(challengeEntityData)
.mockResolvedValueOnce(challengeEntityData)
mockDeleteAllChallengeEntities.mockResolvedValue(true)
mockClient.create.mockRejectedValueOnce(new Error())
expect(initializationService.initChallengeEntity('')).rejects.toThrow(
new Error()
)
})
})
describe('initAnalysis method', () => {
it('should return true and profile when analysis is up to date', async () => {
const mockProfile = {
...profileData,
monthlyAnalysisDate: getActualAnalysisDate(),
describe('initDuelEntity method', () => {
beforeEach(() => {
mockGetAllDuelEntities.mockClear()
mockDeleteAllDuelEntities.mockClear()
})
it('shoud return hash when duel hash is already up to date', async () => {
mockGetAllDuelEntities.mockResolvedValueOnce(duelEntityData)
const hash = hashFile(duelEntityData)
await expect(initializationService.initDuelEntity(hash)).resolves.toEqual(
hash
)
})
it('shoud return hash when duel entities are created', async () => {
mockGetAllDuelEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(duelEntityData)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const hash = hashFile(duelEntityData)
await expect(initializationService.initDuelEntity(hash)).resolves.toEqual(
hash
)
})
it('shoud throw an error when duel entities should be created and created duel entities number does not match', async () => {
mockGetAllDuelEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(allDuelEntity)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initAnalysis(mockProfile)
).resolves.toEqual({
result: true,
profile: mockProfile,
})
initializationService.initDuelEntity(hashFile(duelEntityData))
).rejects.toThrow(
new Error('initDuelEntity: Created duel entities does not match')
)
})
it('shoud throw an error when duel entities should be created and creation failed', async () => {
mockGetAllDuelEntities.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValue(new Error())
await expect(
initializationService.initDuelEntity(hashFile(duelEntityData))
).rejects.toThrow(new Error())
})
it('shoud return hash when duel entities are updated', async () => {
mockGetAllDuelEntities
.mockResolvedValueOnce(duelEntityData)
.mockResolvedValueOnce(duelEntityData)
mockDeleteAllDuelEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(initializationService.initDuelEntity('')).resolves.toEqual(
hashFile(duelEntityData)
)
})
it('shoud throw an error when duel entities should be updated and created duel entities number does not match', async () => {
mockGetAllDuelEntities
.mockResolvedValueOnce(duelEntityData)
.mockResolvedValueOnce(allDuelEntity)
mockDeleteAllDuelEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(initializationService.initDuelEntity('')).rejects.toThrow(
new Error('initDuelEntity: Created duel entities does not match')
)
})
it('shoud throw an error when duel entities should be updated and duel entities creation failed', async () => {
mockGetAllDuelEntities
.mockResolvedValueOnce(duelEntityData)
.mockResolvedValueOnce(duelEntityData)
mockDeleteAllDuelEntities.mockResolvedValue(true)
mockClient.create.mockRejectedValueOnce(new Error())
expect(initializationService.initDuelEntity('')).rejects.toThrow(
new Error()
)
})
})
it('should return true and updated profile when analysis is not up to date', async () => {
const mockProfile = {
...profileData,
monthlyAnalysisDate: DateTime.fromISO('2000-10-02T00:00:00.000Z', {
zone: 'utc',
}),
haveSeenLastAnalysis: true,
describe('initQuizEntity method', () => {
beforeEach(() => {
mockGetAllQuizEntities.mockClear()
mockDeleteAllQuizEntities.mockClear()
})
it('shoud return hash when quiz hash is already up to date', async () => {
mockGetAllQuizEntities.mockResolvedValueOnce(quizEntityData)
const hash = hashFile(quizEntityData)
await expect(initializationService.initQuizEntity(hash)).resolves.toEqual(
hash
)
})
it('shoud return hash when quiz entities are created', async () => {
mockGetAllQuizEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(quizEntityData)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const hash = hashFile(quizEntityData)
await expect(initializationService.initQuizEntity(hash)).resolves.toEqual(
hash
)
})
it('shoud throw an error when quiz entities should be created and created quiz entities number does not match', async () => {
mockGetAllQuizEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(allQuizEntities)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initQuizEntity(hashFile(quizEntityData))
).rejects.toThrow(
new Error('initQuizEntity: Created quiz entities does not match')
)
})
it('shoud throw an error when quiz entities should be created and creation failed', async () => {
mockGetAllQuizEntities.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValue(new Error())
await expect(
initializationService.initQuizEntity(hashFile(quizEntityData))
).rejects.toThrow(new Error())
})
it('shoud return hash when quiz entities are updated', async () => {
mockGetAllQuizEntities
.mockResolvedValueOnce(quizEntityData)
.mockResolvedValueOnce(quizEntityData)
mockDeleteAllQuizEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(initializationService.initQuizEntity('')).resolves.toEqual(
hashFile(quizEntityData)
)
})
it('shoud throw an error when quiz entities should be updated and created quiz entities number does not match', async () => {
mockGetAllQuizEntities
.mockResolvedValueOnce(quizEntityData)
.mockResolvedValueOnce(allQuizEntities)
mockDeleteAllQuizEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(initializationService.initQuizEntity('')).rejects.toThrow(
new Error('initQuizEntity: Created quiz entities does not match')
)
})
it('shoud throw an error when quiz entities should be updated and quiz entities creation failed', async () => {
mockGetAllQuizEntities
.mockResolvedValueOnce(quizEntityData)
.mockResolvedValueOnce(quizEntityData)
mockDeleteAllQuizEntities.mockResolvedValue(true)
mockClient.create.mockRejectedValueOnce(new Error())
expect(initializationService.initQuizEntity('')).rejects.toThrow(
new Error()
)
})
})
describe('initExplorationEntity method', () => {
beforeEach(() => {
mockGetAllExplorationEntities.mockClear()
mockDeleteAllExplorationEntities.mockClear()
})
it('shoud return hash when explorations hash is already up to date', async () => {
mockGetAllExplorationEntities.mockResolvedValueOnce(explorationEntityData)
const hash = hashFile(explorationEntityData)
await expect(
initializationService.initExplorationEntity(hash)
).resolves.toEqual(hash)
})
it('shoud return hash when exploration entities are created', async () => {
mockGetAllExplorationEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(explorationEntityData)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
const hash = hashFile(explorationEntityData)
await expect(
initializationService.initExplorationEntity(hash)
).resolves.toEqual(hash)
})
it('shoud throw an error when exploration entities should be created and created exploration entities number does not match', async () => {
mockGetAllExplorationEntities
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(allExplorationEntities)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initExplorationEntity(
hashFile(explorationEntityData)
)
).rejects.toThrow(
new Error(
'initExplorationEntity: Created exploration entities does not match'
)
)
})
it('shoud throw an error when exploration entities should be created and creation failed', async () => {
mockGetAllExplorationEntities.mockResolvedValueOnce(null)
mockClient.create.mockRejectedValue(new Error())
await expect(
initializationService.initExplorationEntity(
hashFile(explorationEntityData)
)
).rejects.toThrow(new Error())
})
it('shoud return hash when exploration entities are updated', async () => {
mockGetAllExplorationEntities
.mockResolvedValueOnce(explorationEntityData)
.mockResolvedValueOnce(explorationEntityData)
mockDeleteAllExplorationEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
const updatedProfile = {
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initExplorationEntity('')
).resolves.toEqual(hashFile(explorationEntityData))
})
it('shoud throw an error when exploration entities should be updated and created exploration entities number does not match', async () => {
mockGetAllExplorationEntities
.mockResolvedValueOnce(explorationEntityData)
.mockResolvedValueOnce(allExplorationEntities)
mockDeleteAllExplorationEntities.mockResolvedValue(true)
const mockQueryResult: QueryResult<boolean> = {
data: true,
bookmark: '',
next: false,
skip: 0,
}
mockClient.create.mockResolvedValue(mockQueryResult)
await expect(
initializationService.initExplorationEntity('')
).rejects.toThrow(
new Error(
'initExplorationEntity: Created exploration entities does not match'
)
)
})
it('shoud throw an error when exploration entities should be updated and exploration entities creation failed', async () => {
mockGetAllExplorationEntities
.mockResolvedValueOnce(explorationEntityData)
.mockResolvedValueOnce(explorationEntityData)
mockDeleteAllExplorationEntities.mockResolvedValue(true)
mockClient.create.mockRejectedValueOnce(new Error())
expect(initializationService.initExplorationEntity('')).rejects.toThrow(
new Error()
)
})
})
describe('initAnalysis method', () => {
it('should return monthlyAnalysisDate and haveSeenLastAnalysis when analysis is up to date', async () => {
const mockProfile = {
...profileData,
monthlyAnalysisDate: getActualAnalysisDate(),
haveSeenLastAnalysis: false,
}
mockUpdateProfile.mockResolvedValueOnce(updatedProfile)
await expect(
initializationService.initAnalysis(mockProfile)
).resolves.toEqual({
result: true,
profile: updatedProfile,
monthlyAnalysisDate: getActualAnalysisDate(),
haveSeenLastAnalysis: mockProfile.haveSeenLastAnalysis,
})
})
it('should throw error when analysis is not up to date and profile is not updated', async () => {
it('should return updated monthlyAnalysisDate and haveSeenLastAnalysis=true when analysis is not up to date and isFirstConnection', async () => {
const mockProfile = {
...profileData,
monthlyAnalysisDate: DateTime.fromISO('2000-10-02T00:00:00.000Z', {
zone: 'utc',
}),
haveSeenLastAnalysis: true,
}
mockUpdateProfile.mockResolvedValueOnce(null)
await expect(
initializationService.initAnalysis(mockProfile)
).rejects.toThrow(new Error('initAnalysis: Profile not updated'))
).resolves.toEqual({
monthlyAnalysisDate: getActualAnalysisDate(),
haveSeenLastAnalysis: true,
})
})
it('should throw error when analysis is not up to date and update profile failed', async () => {
it('should return updated monthlyAnalysisDate and haveSeenLastAnalysis=false when analysis is not up to date and isFirstConnection is false', async () => {
const mockProfile = {
...profileData,
isFirstConnection: false,
monthlyAnalysisDate: DateTime.fromISO('2000-10-02T00:00:00.000Z', {
zone: 'utc',
}),
haveSeenLastAnalysis: true,
}
mockUpdateProfile.mockRejectedValueOnce(new Error())
await expect(
initializationService.initAnalysis(mockProfile)
).rejects.toThrow(new Error())
).resolves.toEqual({
monthlyAnalysisDate: getActualAnalysisDate(),
haveSeenLastAnalysis: false,
})
})
})
describe('initFluidType method', () => {
beforeEach(() => {
mockGetKonnectorAccountStatus.mockClear()
})
it('shoud return all fluid types', async () => {
mockGetKonnectorAccountStatus.mockResolvedValueOnce([
FluidType.ELECTRICITY,
......@@ -378,14 +783,12 @@ describe('Initialization service', () => {
FluidType.GAS,
])
})
it('shoud throw an error when null is retrieved as fluid types', async () => {
mockGetKonnectorAccountStatus.mockResolvedValueOnce(null)
await expect(initializationService.initFluidTypes()).rejects.toThrow(
new Error('initFluidTypes: FluidTypes not found')
)
})
it('shoud throw an error when it fails to retrieve the fluid types', async () => {
mockGetKonnectorAccountStatus.mockRejectedValueOnce(new Error())
await expect(initializationService.initFluidTypes()).rejects.toThrow(
......@@ -395,20 +798,21 @@ describe('Initialization service', () => {
})
describe('initFluidStatus method', () => {
beforeEach(() => {
mockGetFluidStatus.mockClear()
})
it('shoud return all fluids type', async () => {
mockGetFluidStatus.mockResolvedValueOnce(fluidStatusData)
await expect(initializationService.initFluidStatus()).resolves.toEqual(
fluidStatusData
)
})
it('shoud throw an error when null is retrieved as status', async () => {
mockGetFluidStatus.mockResolvedValueOnce(null)
await expect(initializationService.initFluidStatus()).rejects.toThrow(
new Error('initFluidStatus: fluidStatus not found')
)
})
it('shoud throw an error when it fails to retrieve the status', async () => {
mockGetFluidStatus.mockRejectedValueOnce(new Error())
await expect(initializationService.initFluidStatus()).rejects.toThrow(
......@@ -418,32 +822,38 @@ describe('Initialization service', () => {
})
describe('initUserChallenges method', () => {
beforeEach(() => {
mockBuildUserChallengeList.mockClear()
})
it('shoud return all userChallenges', async () => {
mockBuildUserChallengeList.mockResolvedValueOnce(userChallengeData)
await expect(initializationService.initUserChallenges()).resolves.toEqual(
userChallengeData
)
await expect(
initializationService.initUserChallenges([])
).resolves.toEqual(userChallengeData)
})
it('shoud throw an error when null is retrieved as status', async () => {
mockBuildUserChallengeList.mockResolvedValueOnce(null)
await expect(initializationService.initUserChallenges()).rejects.toThrow(
await expect(
initializationService.initUserChallenges([])
).rejects.toThrow(
new Error('initUserChallenges: userChallengeList not found')
)
})
it('shoud throw an error when it fails to retrieve the status', async () => {
mockBuildUserChallengeList.mockRejectedValueOnce(new Error())
await expect(initializationService.initUserChallenges()).rejects.toThrow(
new Error()
)
await expect(
initializationService.initUserChallenges([])
).rejects.toThrow(new Error())
})
})
describe('initDuelProgress method', () => {
beforeEach(() => {
mockGetUserChallengeDataload.mockClear()
mockUserChallengeUpdateFlag.mockClear()
})
it('shoud return updatedUserChallenge and dataload ', async () => {
mockGetUserChallengeDataload.mockResolvedValueOnce(graphData.actualData)
const expectedUpdatedUserChallenge: UserChallenge = {
...userChallengeData[0],
duel: {
......@@ -462,7 +872,6 @@ describe('Initialization service', () => {
initializationService.initDuelProgress(userChallengeData[0])
).resolves.toEqual(expectedResult)
})
it('shoud throw an error when it fails to retrieve the status', async () => {
mockGetUserChallengeDataload.mockRejectedValueOnce(new Error())
await expect(
......
import { Client, Q, QueryDefinition } from 'cozy-client'
import {
ECOGESTURE_DOCTYPE,
PROFILE_DOCTYPE,
EGL_DAY_DOCTYPE,
EGL_MONTH_DOCTYPE,
EGL_YEAR_DOCTYPE,
ENEDIS_DAY_DOCTYPE,
ENEDIS_MINUTE_DOCTYPE,
ENEDIS_MONTH_DOCTYPE,
ENEDIS_YEAR_DOCTYPE,
GRDF_DAY_DOCTYPE,
GRDF_MONTH_DOCTYPE,
GRDF_YEAR_DOCTYPE,
CHALLENGE_DOCTYPE,
DUEL_DOCTYPE,
QUIZ_DOCTYPE,
EXPLORATION_DOCTYPE,
} from 'doctypes'
import { FluidType } from 'enum/fluid.enum'
import { Dataload, FluidStatus, Profile, UserChallenge } from 'models'
import EcogestureService from 'services/ecogesture.service'
import ChallengeService from 'services/challenge.service'
import ecogestureData from 'db/ecogestureData.json'
import challengeEntityData from 'db/challengeEntity.json'
import duelEntityData from 'db/duelEntity.json'
import quizEntityData from 'db/quizEntity.json'
import explorationEntityData from 'db/explorationEntity.json'
import ProfileService from 'services/profile.service'
import profileData from 'db/profileData.json'
import KonnectorStatusService from 'services/konnectorStatus.service'
import KonnectorService from 'services/konnector.service'
import AccountService from 'services/account.service'
import FluidService from 'services/fluid.service'
import DuelService from 'services/duel.service'
import QuizService from 'services/quiz.service'
import ExplorationService from 'services/exploration.service'
import { hashFile } from 'utils/hash'
import { getActualAnalysisDate } from 'utils/date'
import { TimeStep } from 'enum/timeStep.enum'
import ConsumptionDataManager from './consumption.service'
import { UserChallengeUpdateFlag } from 'enum/userChallenge.enum'
import { getRoundFloat } from 'utils/math'
import { DateTime } from 'luxon'
export default class InitializationService {
private readonly _client: Client
constructor(_client: Client) {
this._client = _client
}
/*
* Call a query with where clause to create the index if not exist
*/
private async createIndex(
doctype: string,
timestep: TimeStep
): Promise<object> {
const getMongoSelector = () => {
switch (timestep) {
case TimeStep.YEAR:
return {
year: {
$lte: 9999,
},
}
case TimeStep.MONTH:
return {
year: {
$lte: 9999,
},
month: {
$lte: 12,
},
}
case TimeStep.DAY:
case TimeStep.HALF_AN_HOUR:
return {
year: {
$lte: 9999,
},
month: {
$lte: 12,
},
day: {
$lte: 31,
},
}
default:
return {}
}
}
const query: QueryDefinition = Q(doctype)
.where(getMongoSelector())
.limitBy(1)
return await this._client.query(query)
}
/*
* create index for each Doctype
* sucess return: true
* failure throw error
*/
public async initIndex(): Promise<boolean> {
try {
const accountService = new AccountService(this._client)
const konnectorService = new KonnectorService(this._client)
await Promise.all([
this.createIndex(EGL_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(EGL_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(EGL_DAY_DOCTYPE, TimeStep.DAY),
this.createIndex(ENEDIS_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(ENEDIS_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(ENEDIS_DAY_DOCTYPE, TimeStep.DAY),
this.createIndex(ENEDIS_MINUTE_DOCTYPE, TimeStep.HALF_AN_HOUR),
this.createIndex(GRDF_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(GRDF_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(GRDF_DAY_DOCTYPE, TimeStep.DAY),
konnectorService.createIndexKonnector(),
accountService.createIndexAccount(),
])
console.log(
'%c Initialization: Indexes created',
'background: #222; color: white'
)
return true
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
/*
* Check if profil exist
* If not, the profil is created
* sucess return: profil
* failure return: null
*/
public async initProfile(): Promise<Profile | null> {
const profileService = new ProfileService(this._client)
try {
const loadedProfile = await profileService.getProfile()
if (!loadedProfile) {
// Population with the data
const { data: newProfile } = await this._client.create(
PROFILE_DOCTYPE,
profileData[0]
)
if (newProfile) {
console.log(
'%c Initialization: Profile created',
'background: #222; color: white'
)
} else {
throw new Error('initProfile: Profile not created')
}
} else {
console.log(
'%c Initialization: Profile loaded',
'background: #222; color: white'
)
// TODO ensure that actual profile has all needed attributes
}
const updatedProfile = await profileService.updateProfile({
lastConnectionDate: DateTime.local().setZone('utc', {
keepLocalTime: true,
}),
})
return updatedProfile
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
public async initEcogesture(
hash: string
): Promise<{ result: boolean; profile: Profile | null }> {
const hashEcogestureType = hashFile(ecogestureData)
const ecogestureService = new EcogestureService(this._client)
const profileService = new ProfileService(this._client)
// Populate data if none ecogesture exists
const loadedEcogestures = await ecogestureService.getAllEcogestures()
if (
!loadedEcogestures ||
(loadedEcogestures && loadedEcogestures.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= ecogestureData.length - 1; i++) {
await this._client.create(ECOGESTURE_DOCTYPE, ecogestureData[i])
}
// Check of created document based on count
const checkCount = await ecogestureService.getAllEcogestures()
if (
!checkCount ||
(checkCount && checkCount.length !== ecogestureData.length)
) {
throw new Error(
'initEcogesture: Created ecogesture type entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
ecogestureHash: hashEcogestureType,
})
if (updatedProfile) {
console.log(
'%c Initialization: Ecogesture created',
'background: #222; color: white'
)
return { result: true, profile: updatedProfile }
} else {
throw new Error('initEcogesture: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== hashEcogestureType) {
// Update the doctype
try {
// Deletion of all documents
await ecogestureService.deleteAllEcogestures()
// Population with the data
await Promise.all(
ecogestureData.map(async ecogesture => {
await this._client.create(ECOGESTURE_DOCTYPE, ecogesture)
})
)
// Check of created document based on count
const checkCount = await ecogestureService.getAllEcogestures()
if (
!checkCount ||
(checkCount && checkCount.length !== ecogestureData.length)
) {
throw new Error(
'initEcogesture: Created ecogesture type entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
ecogestureHash: hashEcogestureType,
})
if (updatedProfile) {
console.log(
'%c Initialization: Ecogesture updated',
'background: #222; color: white'
)
return { result: true, profile: updatedProfile }
} else {
throw new Error('initEcogesture: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Ecogesture loaded',
'background: #222; color: white'
)
return { result: true, profile: null }
}
}
public async initChallengeEntity(
hash: string
): Promise<{
result: boolean
profile: Profile | null
}> {
const challengeHash = hashFile(challengeEntityData)
const challengeService = new ChallengeService(this._client)
const profileService = new ProfileService(this._client)
// Populate data if none challengeEntity exists
const loadedChallengeEntity = await challengeService.getAllChallengeEntities()
if (
!loadedChallengeEntity ||
(loadedChallengeEntity && loadedChallengeEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= challengeEntityData.length - 1; i++) {
await this._client.create(CHALLENGE_DOCTYPE, challengeEntityData[i])
}
// Check of created document
const checkCount = await challengeService.getAllChallengeEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== challengeEntityData.length)
) {
throw new Error(
'initChallengeEntity: Created challenge type entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
challengeHash: challengeHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Challenge entities created',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initChallengeEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== challengeHash) {
// Update the doctype
try {
// Deletion of all documents
await challengeService.deleteAllChallengeEntities()
// Population with the data
await Promise.all(
challengeEntityData.map(async challengeEntity => {
await this._client.create(CHALLENGE_DOCTYPE, challengeEntity)
})
)
// Check of created document
const checkCount = await challengeService.getAllChallengeEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== challengeEntityData.length)
) {
throw new Error(
'initChallengeEntity: Created challenge entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
challengeHash: challengeHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Challenge entities updated',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initChallengeEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Challenge Entity loaded',
'background: #222; color: white'
)
return { result: true, profile: null }
}
}
public async initDuelEntity(
hash: string
): Promise<{
result: boolean
profile: Profile | null
}> {
const hashDuelEntity = hashFile(duelEntityData)
const duelService = new DuelService(this._client)
const profileService = new ProfileService(this._client)
// Populate data if none DuelEntity exists
const loadedDuelTypes = await duelService.getAllDuelEntities()
if (!loadedDuelTypes || (loadedDuelTypes && loadedDuelTypes.length === 0)) {
// Populate the doctype with data
try {
for (let i = 0; i <= duelEntityData.length - 1; i++) {
await this._client.create(DUEL_DOCTYPE, duelEntityData[i])
}
// Check of created document
const checkCount = await duelService.getAllDuelEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== duelEntityData.length)
) {
throw new Error(
'initDuelEntity: Created duel entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
duelHash: hashDuelEntity,
})
if (updatedProfile) {
console.log(
'%c Initialization: UserDuel entities created',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initDuelEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== hashDuelEntity) {
// Update the doctype
try {
// Deletion of all documents
await duelService.deleteAllDuelEntities()
// Population with the data
await Promise.all(
duelEntityData.map(async duelEntity => {
await this._client.create(DUEL_DOCTYPE, duelEntity)
})
)
// Check of created document
const checkCount = await duelService.getAllDuelEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== duelEntityData.length)
) {
throw new Error(
'initChallengeEntity: Created duel entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
duelHash: hashDuelEntity,
})
if (updatedProfile) {
console.log(
'%c Initialization: UserDuel entities updated',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initDuelEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Challenge Entity loaded',
'background: #222; color: white'
)
return { result: true, profile: null }
}
}
public async initQuizEntity(
hash: string
): Promise<{
result: boolean
profile: Profile | null
}> {
const quizHash = hashFile(quizEntityData)
const quizService = new QuizService(this._client)
const profileService = new ProfileService(this._client)
// Populate data if none quizEntity exists
const loadedQuizEntity = await quizService.getAllQuizEntities()
if (
!loadedQuizEntity ||
(loadedQuizEntity && loadedQuizEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= quizEntityData.length - 1; i++) {
await this._client.create(QUIZ_DOCTYPE, quizEntityData[i])
}
// Check of created document
const checkCount = await quizService.getAllQuizEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== quizEntityData.length)
) {
throw new Error(
'initQuizEntity: Created quiz type entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
quizHash: quizHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Quiz entities created',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initQuizEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== quizHash) {
// Update the doctype
try {
// Deletion of all documents
await quizService.deleteAllQuizEntities()
// Population with the data
await Promise.all(
quizEntityData.map(async quizEntity => {
await this._client.create(QUIZ_DOCTYPE, quizEntity)
})
)
// Check of created document
const checkCount = await quizService.getAllQuizEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== quizEntityData.length)
) {
throw new Error(
'initQuizEntity: Created quiz entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
quizHash: quizHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Quiz entities updated',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initQuizEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Quiz Entity loaded',
'background: #222; color: white'
)
return { result: true, profile: null }
}
}
public async initExplorationEntity(
hash: string
): Promise<{
result: boolean
profile: Profile | null
}> {
const explorationHash = hashFile(explorationEntityData)
const explorationService = new ExplorationService(this._client)
const profileService = new ProfileService(this._client)
// Populate data if none explorationEntity exists
const loadedExplorationEntity = await explorationService.getAllExplorationEntities()
if (
!loadedExplorationEntity ||
(loadedExplorationEntity && loadedExplorationEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= explorationEntityData.length - 1; i++) {
await this._client.create(
EXPLORATION_DOCTYPE,
explorationEntityData[i]
)
}
// Check of created document
const checkCount = await explorationService.getAllExplorationEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== explorationEntityData.length)
) {
throw new Error(
'initExplorationEntity: Created exploration type entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
explorationHash: explorationHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Exploration entities created',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initExplorationEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== explorationHash) {
// Update the doctype
try {
// Deletion of all documents
await explorationService.deleteAllExplorationEntities()
// Population with the data
await Promise.all(
explorationEntityData.map(async explorationEntity => {
await this._client.create(EXPLORATION_DOCTYPE, explorationEntity)
})
)
// Check of created document
const checkCount = await explorationService.getAllExplorationEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== explorationEntityData.length)
) {
throw new Error(
'initExplorationEntity: Created exploration entities does not match'
)
}
// Update profil with the hash
const updatedProfile = await profileService.updateProfile({
explorationHash: explorationHash,
})
if (updatedProfile) {
console.log(
'%c Initialization: Exploration entities updated',
'background: #222; color: white'
)
return {
result: true,
profile: updatedProfile,
}
} else {
throw new Error('initExplorationEntity: Profile not updated')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Exploration Entity loaded',
'background: #222; color: white'
)
return { result: true, profile: null }
}
}
public async initAnalysis(
profile: Profile
): Promise<{
result: boolean
profile: Profile | null
}> {
try {
const actualAnalysisDate = getActualAnalysisDate()
if (
profile.monthlyAnalysisDate &&
actualAnalysisDate <= profile.monthlyAnalysisDate
) {
return { result: true, profile: profile }
} else {
const profileService = new ProfileService(this._client)
const updatedProfile = await profileService.updateProfile({
monthlyAnalysisDate: actualAnalysisDate,
haveSeenLastAnalysis: profile.isFirstConnection ? true : false,
})
if (updatedProfile) {
console.log(
'%c Initialization: Analysis information from profile updated',
'background: #222; color: white'
)
return { result: true, profile: updatedProfile }
} else {
throw new Error('initAnalysis: Profile not updated')
}
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
/*
* Check if FluidTypes exist
* sucess return: FluidType[]
* failure throw error
*/
public async initFluidTypes(): Promise<FluidType[]> {
const kss = new KonnectorStatusService(this._client)
try {
const fluidtypes = await kss.getKonnectorAccountStatus()
if (fluidtypes) {
console.log(
'%c Initialization: Fluid Types loaded',
'background: #222; color: white'
)
return fluidtypes
} else {
throw new Error('initFluidTypes: FluidTypes not found')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
/*
* For each fluid get the trigger status and the last data date
* sucess return: FluidStatus[]
* failure throw error
*/
public async initFluidStatus(): Promise<FluidStatus[]> {
const fs = new FluidService(this._client)
try {
const fluidStatus = await fs.getFluidStatus()
if (fluidStatus) {
console.log(
'%c Initialization: Fluid Status loaded',
'background: #222; color: white'
)
return fluidStatus
} else {
throw new Error('initFluidStatus: fluidStatus not found')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
/*
* Build the userChallengeList
* sucess return: UserChallenge[]
* failure throw error
*/
public async initUserChallenges(
fluidStatus: FluidStatus[]
): Promise<UserChallenge[]> {
const challengeService = new ChallengeService(this._client)
try {
const userChallengeList = await challengeService.buildUserChallengeList(
fluidStatus
)
if (userChallengeList) {
console.log(
'%c Initialization: Challenges loaded',
'background: #222; color: white'
)
return userChallengeList
} else {
throw new Error('initUserChallenges: userChallengeList not found')
}
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
/*
* Retrieve dataloads for ongoing duel
* sucess return: UserChallenge, Dataload[]
* failure throw error
*/
public async initDuelProgress(
userChallenge: UserChallenge
): Promise<{
updatedUserChallenge: UserChallenge
dataloads: Dataload[]
}> {
const challengeService = new ChallengeService(this._client)
const consumptionService = new ConsumptionDataManager(this._client)
try {
const dataloads: Dataload[] = await challengeService.getUserChallengeDataload(
userChallenge
)
const userConsumption: number = getRoundFloat(
consumptionService.calculatePerformanceIndicatorValue(dataloads)
)
const _userChallenge: UserChallenge = {
...userChallenge,
duel: {
...userChallenge.duel,
userConsumption: userConsumption,
},
}
const updatedUserChallenge: UserChallenge = await challengeService.updateUserChallenge(
_userChallenge,
UserChallengeUpdateFlag.DUEL_CONSUMPTION
)
return { updatedUserChallenge, dataloads }
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
}
import { Client, Q, QueryDefinition } from 'cozy-client'
import {
ECOGESTURE_DOCTYPE,
PROFILE_DOCTYPE,
EGL_DAY_DOCTYPE,
EGL_MONTH_DOCTYPE,
EGL_YEAR_DOCTYPE,
ENEDIS_DAY_DOCTYPE,
ENEDIS_MINUTE_DOCTYPE,
ENEDIS_MONTH_DOCTYPE,
ENEDIS_YEAR_DOCTYPE,
GRDF_DAY_DOCTYPE,
GRDF_MONTH_DOCTYPE,
GRDF_YEAR_DOCTYPE,
CHALLENGE_DOCTYPE,
DUEL_DOCTYPE,
QUIZ_DOCTYPE,
EXPLORATION_DOCTYPE,
} from 'doctypes'
import { FluidType } from 'enum/fluid.enum'
import { Dataload, FluidStatus, Profile, UserChallenge } from 'models'
import EcogestureService from 'services/ecogesture.service'
import ChallengeService from 'services/challenge.service'
import ecogestureData from 'db/ecogestureData.json'
import challengeEntityData from 'db/challengeEntity.json'
import duelEntityData from 'db/duelEntity.json'
import quizEntityData from 'db/quizEntity.json'
import explorationEntityData from 'db/explorationEntity.json'
import ProfileService from 'services/profile.service'
import profileData from 'db/profileData.json'
import KonnectorStatusService from 'services/konnectorStatus.service'
import KonnectorService from 'services/konnector.service'
import AccountService from 'services/account.service'
import FluidService from 'services/fluid.service'
import DuelService from 'services/duel.service'
import QuizService from 'services/quiz.service'
import ExplorationService from 'services/exploration.service'
import { hashFile } from 'utils/hash'
import { getActualAnalysisDate } from 'utils/date'
import { TimeStep } from 'enum/timeStep.enum'
import ConsumptionDataManager from './consumption.service'
import { UserChallengeUpdateFlag } from 'enum/userChallenge.enum'
import { getRoundFloat } from 'utils/math'
import { DateTime } from 'luxon'
export default class InitializationService {
private readonly _client: Client
constructor(_client: Client) {
this._client = _client
}
/*
* Call a query with where clause to create the index if not exist
*/
private async createIndex(
doctype: string,
timestep: TimeStep
): Promise<object> {
const getMongoSelector = () => {
switch (timestep) {
case TimeStep.YEAR:
return {
year: {
$lte: 9999,
},
}
case TimeStep.MONTH:
return {
year: {
$lte: 9999,
},
month: {
$lte: 12,
},
}
case TimeStep.DAY:
case TimeStep.HALF_AN_HOUR:
return {
year: {
$lte: 9999,
},
month: {
$lte: 12,
},
day: {
$lte: 31,
},
}
default:
return {}
}
}
const query: QueryDefinition = Q(doctype)
.where(getMongoSelector())
.limitBy(1)
return await this._client.query(query)
}
/*
* create index for each Doctype
* sucess return: true
* failure throw error
*/
public async initIndex(): Promise<boolean> {
try {
const accountService = new AccountService(this._client)
const konnectorService = new KonnectorService(this._client)
await Promise.all([
this.createIndex(EGL_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(EGL_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(EGL_DAY_DOCTYPE, TimeStep.DAY),
this.createIndex(ENEDIS_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(ENEDIS_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(ENEDIS_DAY_DOCTYPE, TimeStep.DAY),
this.createIndex(ENEDIS_MINUTE_DOCTYPE, TimeStep.HALF_AN_HOUR),
this.createIndex(GRDF_YEAR_DOCTYPE, TimeStep.YEAR),
this.createIndex(GRDF_MONTH_DOCTYPE, TimeStep.MONTH),
this.createIndex(GRDF_DAY_DOCTYPE, TimeStep.DAY),
konnectorService.createIndexKonnector(),
accountService.createIndexAccount(),
])
console.log(
'%c Initialization: Indexes created',
'background: #222; color: white'
)
return true
} catch (error) {
console.log('Initialization error - initIndex: ', error)
throw error
}
}
/*
* Check if profil exist
* If not, the profil is created
* sucess return: profil
* failure return: null
*/
public async initProfile(): Promise<Profile | null> {
const profileService = new ProfileService(this._client)
try {
const loadedProfile = await profileService.getProfile()
if (!loadedProfile) {
// Population with the data
const { data: newProfile } = await this._client.create(
PROFILE_DOCTYPE,
profileData[0]
)
if (newProfile) {
console.log(
'%c Initialization: Profile created',
'background: #222; color: white'
)
} else {
throw new Error('initProfile: Profile not created')
}
} else {
console.log(
'%c Initialization: Profile loaded',
'background: #222; color: white'
)
}
const updatedProfile = await profileService.updateProfile({
lastConnectionDate: DateTime.local().setZone('utc', {
keepLocalTime: true,
}),
})
return updatedProfile
} catch (error) {
console.log('Initialization error - initProfile: ', error)
throw error
}
}
public async initEcogesture(hash: string): Promise<string> {
const hashEcogestureType = hashFile(ecogestureData)
const ecogestureService = new EcogestureService(this._client)
// Populate data if none ecogesture exists
const loadedEcogestures = await ecogestureService.getAllEcogestures()
if (
!loadedEcogestures ||
(loadedEcogestures && loadedEcogestures.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= ecogestureData.length - 1; i++) {
await this._client.create(ECOGESTURE_DOCTYPE, ecogestureData[i])
}
// Check of created document based on count
const checkCount = await ecogestureService.getAllEcogestures()
if (
!checkCount ||
(checkCount && checkCount.length !== ecogestureData.length)
) {
throw new Error(
'initEcogesture: Created ecogesture type entities does not match'
)
}
console.log(
'%c Initialization: Ecogesture created',
'background: #222; color: white'
)
return hashEcogestureType
} catch (error) {
console.log('Initialization error - initEcogesture: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== hashEcogestureType) {
// Update the doctype
try {
// Deletion of all documents
await ecogestureService.deleteAllEcogestures()
// Population with the data
await Promise.all(
ecogestureData.map(async ecogesture => {
await this._client.create(ECOGESTURE_DOCTYPE, ecogesture)
})
)
// Check of created document based on count
const checkCount = await ecogestureService.getAllEcogestures()
if (
!checkCount ||
(checkCount && checkCount.length !== ecogestureData.length)
) {
throw new Error(
'initEcogesture: Created ecogesture type entities does not match'
)
}
console.log(
'%c Initialization: Ecogesture updated',
'background: #222; color: white'
)
return hashEcogestureType
} catch (error) {
console.log('Initialization error - initEcogesture: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Ecogesture loaded',
'background: #222; color: white'
)
return hashEcogestureType
}
}
public async initChallengeEntity(hash: string): Promise<string> {
const challengeHash = hashFile(challengeEntityData)
const challengeService = new ChallengeService(this._client)
// Populate data if none challengeEntity exists
const loadedChallengeEntity = await challengeService.getAllChallengeEntities()
if (
!loadedChallengeEntity ||
(loadedChallengeEntity && loadedChallengeEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= challengeEntityData.length - 1; i++) {
await this._client.create(CHALLENGE_DOCTYPE, challengeEntityData[i])
}
// Check of created document
const checkCount = await challengeService.getAllChallengeEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== challengeEntityData.length)
) {
throw new Error(
'initChallengeEntity: Created challenge entities does not match'
)
}
console.log(
'%c Initialization: Challenge entities created',
'background: #222; color: white'
)
return challengeHash
} catch (error) {
console.log('Initialization error - initChallengeEntity: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== challengeHash) {
// Update the doctype
try {
// Deletion of all documents
await challengeService.deleteAllChallengeEntities()
// Population with the data
await Promise.all(
challengeEntityData.map(async challengeEntity => {
await this._client.create(CHALLENGE_DOCTYPE, challengeEntity)
})
)
// Check of created document
const checkCount = await challengeService.getAllChallengeEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== challengeEntityData.length)
) {
throw new Error(
'initChallengeEntity: Created challenge entities does not match'
)
}
console.log(
'%c Initialization: Challenge entities updated',
'background: #222; color: white'
)
return challengeHash
} catch (error) {
console.log('Initialization error - initChallengeEntity: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Challenge Entity loaded',
'background: #222; color: white'
)
return challengeHash
}
}
public async initDuelEntity(hash: string): Promise<string> {
const hashDuelEntity = hashFile(duelEntityData)
const duelService = new DuelService(this._client)
// Populate data if none DuelEntity exists
const loadedDuelTypes = await duelService.getAllDuelEntities()
if (!loadedDuelTypes || (loadedDuelTypes && loadedDuelTypes.length === 0)) {
// Populate the doctype with data
try {
for (let i = 0; i <= duelEntityData.length - 1; i++) {
await this._client.create(DUEL_DOCTYPE, duelEntityData[i])
}
// Check of created document
const checkCount = await duelService.getAllDuelEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== duelEntityData.length)
) {
throw new Error(
'initDuelEntity: Created duel entities does not match'
)
}
console.log(
'%c Initialization: UserDuel entities created',
'background: #222; color: white'
)
return hashDuelEntity
} catch (error) {
console.log('Initialization error - initDuelEntity: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== hashDuelEntity) {
// Update the doctype
try {
// Deletion of all documents
await duelService.deleteAllDuelEntities()
// Population with the data
await Promise.all(
duelEntityData.map(async duelEntity => {
await this._client.create(DUEL_DOCTYPE, duelEntity)
})
)
// Check of created document
const checkCount = await duelService.getAllDuelEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== duelEntityData.length)
) {
throw new Error(
'initDuelEntity: Created duel entities does not match'
)
}
console.log(
'%c Initialization: UserDuel entities updated',
'background: #222; color: white'
)
return hashDuelEntity
} catch (error) {
console.log('Initialization error - initDuelEntity: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Challenge Entity loaded',
'background: #222; color: white'
)
return hashDuelEntity
}
}
public async initQuizEntity(hash: string): Promise<string> {
const quizHash = hashFile(quizEntityData)
const quizService = new QuizService(this._client)
// Populate data if none quizEntity exists
const loadedQuizEntity = await quizService.getAllQuizEntities()
if (
!loadedQuizEntity ||
(loadedQuizEntity && loadedQuizEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= quizEntityData.length - 1; i++) {
await this._client.create(QUIZ_DOCTYPE, quizEntityData[i])
}
// Check of created document
const checkCount = await quizService.getAllQuizEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== quizEntityData.length)
) {
throw new Error(
'initQuizEntity: Created quiz entities does not match'
)
}
console.log(
'%c Initialization: Quiz entities created',
'background: #222; color: white'
)
return quizHash
} catch (error) {
console.log('Initialization error - initQuizEntity: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== quizHash) {
// Update the doctype
try {
// Deletion of all documents
await quizService.deleteAllQuizEntities()
// Population with the data
await Promise.all(
quizEntityData.map(async quizEntity => {
await this._client.create(QUIZ_DOCTYPE, quizEntity)
})
)
// Check of created document
const checkCount = await quizService.getAllQuizEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== quizEntityData.length)
) {
throw new Error(
'initQuizEntity: Created quiz entities does not match'
)
}
console.log(
'%c Initialization: Quiz entities updated',
'background: #222; color: white'
)
return quizHash
} catch (error) {
console.log('Initialization error - initQuizEntity: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Quiz Entity loaded',
'background: #222; color: white'
)
return quizHash
}
}
public async initExplorationEntity(hash: string): Promise<string> {
const explorationHash = hashFile(explorationEntityData)
const explorationService = new ExplorationService(this._client)
// Populate data if none explorationEntity exists
const loadedExplorationEntity = await explorationService.getAllExplorationEntities()
if (
!loadedExplorationEntity ||
(loadedExplorationEntity && loadedExplorationEntity.length === 0)
) {
// Populate the doctype with data
try {
for (let i = 0; i <= explorationEntityData.length - 1; i++) {
await this._client.create(
EXPLORATION_DOCTYPE,
explorationEntityData[i]
)
}
// Check of created document
const checkCount = await explorationService.getAllExplorationEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== explorationEntityData.length)
) {
throw new Error(
'initExplorationEntity: Created exploration entities does not match'
)
}
console.log(
'%c Initialization: Exploration entities created',
'background: #222; color: white'
)
return explorationHash
} catch (error) {
console.log('Initialization error - initExplorationEntity: ', error)
throw error
}
}
// Update if the hash is not the same as the one from profile
if (hash !== explorationHash) {
// Update the doctype
try {
// Deletion of all documents
await explorationService.deleteAllExplorationEntities()
// Population with the data
await Promise.all(
explorationEntityData.map(async explorationEntity => {
await this._client.create(EXPLORATION_DOCTYPE, explorationEntity)
})
)
// Check of created document
const checkCount = await explorationService.getAllExplorationEntities()
if (
!checkCount ||
(checkCount && checkCount.length !== explorationEntityData.length)
) {
throw new Error(
'initExplorationEntity: Created exploration entities does not match'
)
}
console.log(
'%c Initialization: Exploration entities updated',
'background: #222; color: white'
)
return explorationHash
} catch (error) {
console.log('Initialization error - initExplorationEntity: ', error)
throw error
}
} else {
// Doctype already up to date
console.log(
'%c Initialization: Exploration Entity loaded',
'background: #222; color: white'
)
return explorationHash
}
}
public async initAnalysis(
profile: Profile
): Promise<{
monthlyAnalysisDate: DateTime
haveSeenLastAnalysis: boolean
}> {
try {
const actualAnalysisDate = getActualAnalysisDate()
if (
profile.monthlyAnalysisDate &&
actualAnalysisDate <= profile.monthlyAnalysisDate
) {
return {
monthlyAnalysisDate: profile.monthlyAnalysisDate,
haveSeenLastAnalysis: profile.haveSeenLastAnalysis,
}
} else {
console.log(
'%c Initialization: Analysis information from profile updated',
'background: #222; color: white'
)
return {
monthlyAnalysisDate: actualAnalysisDate,
haveSeenLastAnalysis: profile.isFirstConnection ? true : false,
}
}
} catch (error) {
console.log('Initialization error - initAnalysis: ', error)
throw error
}
}
/*
* Check if FluidTypes exist
* sucess return: FluidType[]
* failure throw error
*/
public async initFluidTypes(): Promise<FluidType[]> {
const kss = new KonnectorStatusService(this._client)
try {
const fluidtypes = await kss.getKonnectorAccountStatus()
if (fluidtypes) {
console.log(
'%c Initialization: Fluid Types loaded',
'background: #222; color: white'
)
return fluidtypes
} else {
throw new Error('initFluidTypes: FluidTypes not found')
}
} catch (error) {
console.log('Initialization error - initFluidTypes: ', error)
throw error
}
}
/*
* For each fluid get the trigger status and the last data date
* sucess return: FluidStatus[]
* failure throw error
*/
public async initFluidStatus(): Promise<FluidStatus[]> {
const fs = new FluidService(this._client)
try {
const fluidStatus = await fs.getFluidStatus()
if (fluidStatus) {
console.log(
'%c Initialization: Fluid Status loaded',
'background: #222; color: white'
)
return fluidStatus
} else {
throw new Error('initFluidStatus: fluidStatus not found')
}
} catch (error) {
console.log('Initialization error - initFluidStatus: ', error)
throw error
}
}
/*
* Build the userChallengeList
* sucess return: UserChallenge[]
* failure throw error
*/
public async initUserChallenges(
fluidStatus: FluidStatus[]
): Promise<UserChallenge[]> {
const challengeService = new ChallengeService(this._client)
try {
const userChallengeList = await challengeService.buildUserChallengeList(
fluidStatus
)
if (userChallengeList) {
console.log(
'%c Initialization: Challenges loaded',
'background: #222; color: white'
)
return userChallengeList
} else {
throw new Error('initUserChallenges: userChallengeList not found')
}
} catch (error) {
console.log('Initialization error - initUserChallenges: ', error)
throw error
}
}
/*
* Retrieve dataloads for ongoing duel
* sucess return: UserChallenge, Dataload[]
* failure throw error
*/
public async initDuelProgress(
userChallenge: UserChallenge
): Promise<{
updatedUserChallenge: UserChallenge
dataloads: Dataload[]
}> {
const challengeService = new ChallengeService(this._client)
const consumptionService = new ConsumptionDataManager(this._client)
try {
const dataloads: Dataload[] = await challengeService.getUserChallengeDataload(
userChallenge
)
const userConsumption: number = getRoundFloat(
consumptionService.calculatePerformanceIndicatorValue(dataloads)
)
const _userChallenge: UserChallenge = {
...userChallenge,
duel: {
...userChallenge.duel,
userConsumption: userConsumption,
},
}
const updatedUserChallenge: UserChallenge = await challengeService.updateUserChallenge(
_userChallenge,
UserChallengeUpdateFlag.DUEL_CONSUMPTION
)
return { updatedUserChallenge, dataloads }
} catch (error) {
console.log('Initialization error: ', error)
throw error
}
}
}
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'
interface UpdateProfile {
type: typeof UPDATE_PROFILE
payload?: Profile
}
export type ProfileActionTypes = UpdateProfile
export function updateProfileSuccess(updatedProfile: Profile): UpdateProfile {
return {
type: UPDATE_PROFILE,
payload: updatedProfile,
}
}
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))
}
}
}
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'
export interface UpdateProfile {
type: typeof UPDATE_PROFILE
payload?: Profile
}
export type ProfileActionTypes = UpdateProfile
export function updateProfileSuccess(updatedProfile: Profile): UpdateProfile {
return {
type: UPDATE_PROFILE,
payload: updatedProfile,
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function updateProfile(upd: Partial<Profile>): any {
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))
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment