Newer
Older
import { QueryResult } from 'cozy-client'
import { ENEDIS_MINUTE_DOCTYPE } from 'doctypes'
import { DataloadState, FluidType, TimeStep } from 'enums'

Hugo SUBTIL
committed
import { DateTime } from 'luxon'
import {
Datachart,
Dataload,
DataloadEntity,
FluidPrice,
FluidStatus,
TimePeriod,
} from 'models'
import { mockAvgTemperature } from 'tests/__mocks__/avgTemperature.mock'
import mockClient from 'tests/__mocks__/client.mock'
import {
fetchDayDataComplete,
fetchDayDataIncomplete,
} from 'tests/__mocks__/fetchDayData.mock'
import { fluidPrices } from 'tests/__mocks__/fluidPrice.mock'
import { fluidStatusConnectedData } from 'tests/__mocks__/fluidStatusData.mock'
import { loadDayData } from 'tests/__mocks__/loadDayData.mock'
import ConsumptionDataManager from './consumption.service'
import ConsumptionValidatorService from './consumptionValidator.service'

Hugo SUBTIL
committed
const mockFetchFluidData = jest.fn()
const mockFetchFluidMaxData = jest.fn()
const mockGetFirstDateData = jest.fn()

Hugo SUBTIL
committed
const mockGetLastDateData = jest.fn()
const mockGetEntries = jest.fn()
jest.mock('./queryRunner.service', () => {
return jest.fn(() => ({
fetchFluidData: mockFetchFluidData,
fetchFluidMaxData: mockFetchFluidMaxData,
getFirstDateData: mockGetFirstDateData,
getLastDateData: mockGetLastDateData,
getEntries: mockGetEntries,
}))

Hugo SUBTIL
committed
})
describe('Consumption service', () => {
const consumptionDataManager = new ConsumptionDataManager(mockClient)
const fluidStatus: FluidStatus[] = fluidStatusConnectedData

Hugo SUBTIL
committed
const mockTimePeriod: TimePeriod = {
startDate: DateTime.fromISO('2020-08-01T00:00:00.000Z'),
endDate: DateTime.fromISO('2020-08-03T23:59:59.999Z'),

Hugo SUBTIL
committed
}
const mockTimePeriodComparison: TimePeriod = {
startDate: DateTime.fromISO('2020-07-01T00:00:00.000Z'),
endDate: DateTime.fromISO('2020-07-03T23:59:59.999Z'),

Hugo SUBTIL
committed
}
const mockFetchDataActual: Dataload[] = [
{
date: DateTime.fromISO('2020-08-01T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 291.9,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-08-02T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 260.15,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
]
const mockFetchDataComparison: Dataload[] = [
{
date: DateTime.fromISO('2020-07-01T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 228.23,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-07-02T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 238.71,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
]

Hugo SUBTIL
committed
describe('getGraphData method', () => {
it('should return null because input is invalid', async () => {
const result = await consumptionDataManager.getGraphData({
timePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,
fluidTypes: [],
fluidStatus: [],
compareTimePeriod: mockTimePeriodComparison,
isHome: false,
})

Hugo SUBTIL
committed
expect(result).toBeNull()
})
it('should return a mapped data for one fluid', async () => {
const fluidTypes: FluidType[] = [FluidType.ELECTRICITY]

Hugo SUBTIL
committed
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataComparison)
const mockResult: Datachart = {

Hugo SUBTIL
committed
actualData: [
{
date: DateTime.fromISO('2020-08-01T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 291.9,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-08-02T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 260.15,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-08-03T00:00:00.000Z'),

Hugo SUBTIL
committed
value: -1,
state: DataloadState.HOLE,

Hugo SUBTIL
committed
valueDetail: null,
},
],
comparisonData: [
{
date: DateTime.fromISO('2020-07-01T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 228.23,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-07-02T00:00:00.000Z'),

Hugo SUBTIL
committed
value: 238.71,
state: DataloadState.VALID,

Hugo SUBTIL
committed
valueDetail: null,
},
{
date: DateTime.fromISO('2020-07-03T00:00:00.000Z'),

Hugo SUBTIL
committed
value: -1,
state: DataloadState.HOLE,

Hugo SUBTIL
committed
valueDetail: null,
},
],
}
const result = await consumptionDataManager.getGraphData({
timePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,

Hugo SUBTIL
committed
fluidTypes,
compareTimePeriod: mockTimePeriodComparison,
isHome: false,
})

Hugo SUBTIL
committed
expect(result).toEqual(mockResult)
})
it('should return a mapped data for multiple fluid', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _fluid of allFluids) {

Hugo SUBTIL
committed
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataComparison)
}
const mockResult: Datachart = {

Hugo SUBTIL
committed
actualData: [
{
date: DateTime.fromISO('2020-08-01T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 73.44203999999999, state: DataloadState.VALID },
{ value: 1.0187309999999998, state: DataloadState.VALID },
{ value: 43.612778999999996, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-08-02T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 65.45374, state: DataloadState.VALID },
{ value: 0.9079234999999999, state: DataloadState.VALID },
{ value: 38.86901149999999, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-08-03T00:00:00.000Z'),

Hugo SUBTIL
committed
value: -1,
state: DataloadState.AGGREGATED_HOLE_OR_MISSING,

Hugo SUBTIL
committed
valueDetail: null,
},
],
comparisonData: [
{
date: DateTime.fromISO('2020-07-01T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 57.422667999999994, state: DataloadState.VALID },
{ value: 0.7965227, state: DataloadState.VALID },
{ value: 34.099844299999994, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-07-02T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 60.059436, state: DataloadState.VALID },
{ value: 0.8330979000000001, state: DataloadState.VALID },
{ value: 35.6656611, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-07-03T00:00:00.000Z'),

Hugo SUBTIL
committed
value: -1,
state: DataloadState.AGGREGATED_HOLE_OR_MISSING,

Hugo SUBTIL
committed
valueDetail: null,
},
],
}
const result = await consumptionDataManager.getGraphData({
timePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,
fluidTypes: allFluids,
compareTimePeriod: mockTimePeriodComparison,
isHome: true,
})

Hugo SUBTIL
committed
expect(result).toEqual(mockResult)
})
it('should return a mapped data for multi fluid without comparison date', async () => {
const mockResult: Datachart = {

Hugo SUBTIL
committed
actualData: [
{
date: DateTime.fromISO('2020-08-01T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 73.44203999999999, state: DataloadState.VALID },
{ value: 1.0187309999999998, state: DataloadState.VALID },
{ value: 43.612778999999996, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-08-02T00:00:00.000Z'),
state: DataloadState.AGGREGATED_VALID,
valueDetail: [
{ value: 65.45374, state: DataloadState.VALID },
{ value: 0.9079234999999999, state: DataloadState.VALID },
{ value: 38.86901149999999, state: DataloadState.VALID },

Hugo SUBTIL
committed
},
{
date: DateTime.fromISO('2020-08-03T00:00:00.000Z'),

Hugo SUBTIL
committed
value: -1,
state: DataloadState.AGGREGATED_HOLE_OR_MISSING,

Hugo SUBTIL
committed
valueDetail: null,
},
],
comparisonData: [],
}
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
const result = await consumptionDataManager.getGraphData({
timePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,
fluidTypes: allFluids,
fluidStatus,
})

Hugo SUBTIL
committed
expect(result).toEqual(mockResult)
})
it('should return null because of wrong parameters', async () => {
const fluidTypes = [FluidType.WATER]
const result = await consumptionDataManager.getGraphData({
timePeriod: mockTimePeriod,
timeStep: TimeStep.HALF_AN_HOUR,
fluidTypes,
fluidStatus,
compareTimePeriod: mockTimePeriodComparison,
isHome: true,
})

Hugo SUBTIL
committed
expect(result).toBeNull()
})
it('should return null when not matching both cases', async () => {
const fluidTypes: FluidType[] = []

Hugo SUBTIL
committed
const wrongTimePeriod = {
startDate: DateTime.fromISO('2020-08-03T23:59:59.999Z'),
endDate: DateTime.fromISO('2020-08-01T00:00:00.000Z'),

Hugo SUBTIL
committed
}
jest
.spyOn(ConsumptionValidatorService.prototype, 'ValidateGetGraphData')
.mockReturnValueOnce(true)
const result = await consumptionDataManager.getGraphData({
timePeriod: wrongTimePeriod,
timeStep: TimeStep.DAY,

Hugo SUBTIL
committed
fluidTypes,
compareTimePeriod: mockTimePeriodComparison,
isHome: false,
})

Hugo SUBTIL
committed
expect(result).toBeNull()
})
})

Hugo SUBTIL
committed
describe('getMaxLoad method', () => {
it('should return the maxed value for a time period for the home', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _fluid of allFluids) {

Hugo SUBTIL
committed
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataComparison)
}
const result = await consumptionDataManager.getMaxLoad({
maxTimePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,
fluidTypes: allFluids,
compareMaxTimePeriod: mockTimePeriodComparison,
isHome: true,
})

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
it('should return the maxed value for a time period', async () => {
const fluidTypes: FluidType[] = [FluidType.ELECTRICITY]

Hugo SUBTIL
committed
const expectedResult = 63.1254
mockFetchFluidMaxData.mockResolvedValueOnce(expectedResult)
const result = await consumptionDataManager.getMaxLoad({
maxTimePeriod: mockTimePeriod,
timeStep: TimeStep.DAY,
compareMaxTimePeriod: mockTimePeriodComparison,
})

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
})
describe('getLastDataload method', () => {
it('should return the last dataload', async () => {
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
const result = await consumptionDataManager.getLastDataload(0)
expect(result).toEqual(mockFetchDataActual)
})
})

Hugo SUBTIL
committed
describe('getPerformanceIndicators method', () => {
it('should return the performance indicator', async () => {
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataComparison)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataComparison)
// Incomplete Data to test all possibilities

Hugo SUBTIL
committed
mockFetchFluidData.mockResolvedValueOnce([
{
date: DateTime.fromISO('2020-08-01T00:23:20.000Z'),

Hugo SUBTIL
committed
value: 298.283,
},
])
mockFetchFluidData.mockResolvedValueOnce([
{
date: DateTime.fromISO('2020-08-01T03:10:00.000Z'),

Hugo SUBTIL
committed
value: 398.283,
},
])
const mockTimePeriodComplete = {
startDate: DateTime.fromISO('2020-08-01T00:00:00.000Z'),
endDate: DateTime.fromISO('2020-08-02T23:59:59.999Z'),

Hugo SUBTIL
committed
}
const mockTimePeriodComparisonComplete = {
startDate: DateTime.fromISO('2020-07-01T00:00:00.000Z'),
endDate: DateTime.fromISO('2020-07-02T23:59:59.999Z'),

Hugo SUBTIL
committed
}
const expectedResult = [
{
compareValue: 466.94,
percentageVariation: 0.18227181222426858,

Hugo SUBTIL
committed
value: 552.05,
price: null,
},
{
compareValue: 466.94,
percentageVariation: 0.18227181222426858,

Hugo SUBTIL
committed
value: 552.05,
price: null,
},
{
compareValue: null,
percentageVariation: null,
value: null,
price: null,
},
]
const result = await consumptionDataManager.getPerformanceIndicators(
mockTimePeriodComplete,
TimeStep.DAY,

Hugo SUBTIL
committed
mockTimePeriodComparisonComplete
)
expect(result).toEqual(expectedResult)
})
})
describe('getFluidsWithData method', () => {
it('should return the array of fluidTypes that have entries', async () => {
mockGetEntries.mockResolvedValueOnce({ data: [1] })
mockGetEntries.mockResolvedValueOnce({ data: [] })
mockGetEntries.mockResolvedValueOnce({ data: [1] })
const result = await consumptionDataManager.getFluidsWithData(
TimeStep.MONTH
)
expect(result).toStrictEqual([FluidType.ELECTRICITY, FluidType.GAS])
})
})
describe('fetchAllFirstDateData method', () => {

Hugo SUBTIL
committed
it('should return the latest date data of one fluid', async () => {
const fluidTypes: FluidType[] = [FluidType.ELECTRICITY]
const expectedResult = [DateTime.fromISO('2020-09-03T23:59:59.999Z')]
mockGetFirstDateData.mockResolvedValueOnce(

Hugo SUBTIL
committed
DateTime.fromISO('2020-09-03T23:59:59.999Z')
)
const result =
await consumptionDataManager.fetchAllFirstDateData(fluidTypes)

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
it('should return the latest date data of All fluid', async () => {
mockGetFirstDateData.mockResolvedValueOnce(

Hugo SUBTIL
committed
DateTime.fromISO('2020-09-02T23:59:59.999Z')
)
mockGetFirstDateData.mockResolvedValueOnce(

Hugo SUBTIL
committed
DateTime.fromISO('2020-09-03T23:59:59.999Z')
)
mockGetFirstDateData.mockResolvedValueOnce(

Hugo SUBTIL
committed
DateTime.fromISO('2020-09-01T23:59:59.999Z')
)
const expectedResult = [
DateTime.fromISO('2020-09-02T23:59:59.999Z'),
DateTime.fromISO('2020-09-03T23:59:59.999Z'),
DateTime.fromISO('2020-09-01T23:59:59.999Z'),
]
await consumptionDataManager.fetchAllFirstDateData(allFluids)

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
})

Hugo SUBTIL
committed
describe('fetchAllLastDateData method', () => {
it('should return the latest date data of one fluid', async () => {
const fluidTypes: FluidType[] = [FluidType.ELECTRICITY]

Hugo SUBTIL
committed
const expectedResult = [DateTime.fromISO('2020-09-03T23:59:59.999Z')]
mockGetLastDateData.mockResolvedValueOnce(
DateTime.fromISO('2020-09-03T23:59:59.999Z')
)
const result =
await consumptionDataManager.fetchAllLastDateData(fluidTypes)

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
it('should return the latest date data of All fluid', async () => {
mockGetLastDateData.mockResolvedValueOnce(
DateTime.fromISO('2020-09-02T23:59:59.999Z')
)
mockGetLastDateData.mockResolvedValueOnce(
DateTime.fromISO('2020-09-03T23:59:59.999Z')
)
mockGetLastDateData.mockResolvedValueOnce(
DateTime.fromISO('2020-09-01T23:59:59.999Z')
)
const expectedResult = [
DateTime.fromISO('2020-09-02T23:59:59.999Z'),
DateTime.fromISO('2020-09-03T23:59:59.999Z'),
DateTime.fromISO('2020-09-01T23:59:59.999Z'),
]
await consumptionDataManager.fetchAllLastDateData(allFluids)

Hugo SUBTIL
committed
expect(result).toEqual(expectedResult)
})
})

Hugo SUBTIL
committed
describe('checkDoctypeEntries method', () => {
it('should return a boolean if doctype are correct', async () => {
const fluidType: FluidType = FluidType.GAS

Hugo SUBTIL
committed
mockGetEntries.mockResolvedValueOnce({ data: [1] })
let result = await consumptionDataManager.checkDoctypeEntries(
fluidType,
TimeStep.DAY
)
expect(result).toBeTruthy()
mockGetEntries.mockResolvedValueOnce({ data: [] })
result = await consumptionDataManager.checkDoctypeEntries(

Hugo SUBTIL
committed
TimeStep.DAY
)
expect(result).toBeFalsy()
})
})

Hugo SUBTIL
committed
describe('getFirstDataDateFromDoctypeWithPrice', () => {
it('should Get the first entry of a given data doctype', async () => {
const data: QueryResult<FluidPrice[]> = {
data: [fluidPrices[0]],
bookmark: '',
next: false,
skip: 0,
}
mockClient.query.mockResolvedValueOnce(data)
const result =
await consumptionDataManager.getFirstDataDateFromDoctypeWithPrice(
ENEDIS_MINUTE_DOCTYPE
)

Hugo SUBTIL
committed
expect(result).toEqual(data.data[0])
})
})

Hugo SUBTIL
committed
describe('getLastHourData', () => {
it('should get last hour data', async () => {
const mockQueryResult: QueryResult<DataloadEntity[]> = {
data: [loadDayData[0]],
bookmark: '',
next: false,
skip: 0,
}
mockClient.query.mockResolvedValueOnce(mockQueryResult)
const result = await consumptionDataManager.getLastHourData(
mockClient,
12
)
expect(result).toEqual(mockQueryResult.data)
expect(result.length).toEqual(1)
})
})
describe('fetchAvgTemperature', () => {
it('should return the average temperature when data is available', async () => {
mockClient
.getStackClient()
.fetchJSON.mockResolvedValueOnce(mockAvgTemperature)
const result = await consumptionDataManager.fetchAvgTemperature(2023, 5)
expect(result).toBe(mockAvgTemperature.values[0].average_measurement)
})
it('should throw an error when no data is available', async () => {
mockClient
.getStackClient()
// eslint-disable-next-line camelcase
.fetchJSON.mockResolvedValueOnce({ nb_results: 0 })
const result = await consumptionDataManager.fetchAvgTemperature(2023, 5)
expect(result).toBe(null)
})
})

Hugo SUBTIL
committed
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
describe('saveDoc & saveDocs', () => {
it('should saveDoc', async () => {
const mockQueryResult: QueryResult<DataloadEntity> = {
data: loadDayData[0],
bookmark: '',
next: false,
skip: 0,
}
mockClient.save.mockResolvedValueOnce(mockQueryResult)
const result = await consumptionDataManager.saveDoc(loadDayData[0])
expect(result).toEqual(mockQueryResult.data)
})
it('should saveDocs', async () => {
const mockQueryResult: QueryResult<DataloadEntity[]> = {
data: loadDayData,
bookmark: '',
next: false,
skip: 0,
}
mockClient.saveAll.mockResolvedValueOnce(mockQueryResult)
const result = await consumptionDataManager.saveDocs(loadDayData)
expect(result).toEqual(mockQueryResult.data)
expect(result.length).toEqual(4)
})
})
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
describe('getFluidsWithDataForTimePeriod', () => {
const allFluids = [FluidType.ELECTRICITY, FluidType.WATER, FluidType.GAS]
const timePeriods: TimePeriod = {
startDate: DateTime.local(2023, 5, 1),
endDate: DateTime.local(2023, 6, 1),
}
it('should return 2 fluids', async () => {
mockFetchFluidData.mockResolvedValueOnce(null)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
mockFetchFluidData.mockResolvedValueOnce(mockFetchDataActual)
const fluidsWithData =
await consumptionDataManager.getFluidsWithDataForTimePeriod(
allFluids,
timePeriods
)
expect(fluidsWithData).toEqual([FluidType.WATER, FluidType.GAS])
})
it('should return no fluids', async () => {
mockFetchFluidData.mockResolvedValue(null)
const fluidsWithData =
await consumptionDataManager.getFluidsWithDataForTimePeriod(
allFluids,
timePeriods
)
expect(fluidsWithData).toEqual([])
})
})
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
describe('getFluidsWithIncompleteDataForTimePeriod', () => {
const allFluids = [FluidType.ELECTRICITY, FluidType.WATER, FluidType.GAS]
const month = DateTime.local(2023, 7, 1)
it('should return 2 fluids', async () => {
mockFetchFluidData.mockResolvedValueOnce(fetchDayDataComplete)
mockFetchFluidData.mockResolvedValueOnce(fetchDayDataIncomplete)
mockFetchFluidData.mockResolvedValueOnce(fetchDayDataIncomplete)
const fluidsWithIncompleteData =
await consumptionDataManager.getFluidsWithIncompleteData(
allFluids,
month
)
expect(fluidsWithIncompleteData).toEqual([FluidType.WATER, FluidType.GAS])
})
it('should return no fluids', async () => {
mockFetchFluidData.mockResolvedValue(fetchDayDataComplete)
const fluidsWithData =
await consumptionDataManager.getFluidsWithIncompleteData(
allFluids,
month
)
expect(fluidsWithData).toEqual([])
})
})