diff --git a/src/services/ecogesture.service.spec.ts b/src/services/ecogesture.service.spec.ts index 7661d09988966dbcbb92224529baf1d9e08d473b..d002f5f570f4570d153231970d9bd059ea4f9de7 100644 --- a/src/services/ecogesture.service.spec.ts +++ b/src/services/ecogesture.service.spec.ts @@ -1,6 +1,11 @@ import { QueryResult } from 'cozy-client' import ecogestureData from 'db/ecogestureData.json' -import { EquipmentType, IndividualOrCollective, WarmingType } from 'enums' +import { + EquipmentType, + IndividualOrCollective, + Season, + WarmingType, +} from 'enums' import { Ecogesture } from 'models' import { ProfileEcogesture } from 'models/profileEcogesture.model' import mockClient from 'tests/__mocks__/client.mock' @@ -14,7 +19,7 @@ import { } from 'tests/__mocks__/ecogesturesData.mock' import { mockProfileEcogesture } from 'tests/__mocks__/profileEcogesture.mock' import { getError } from 'tests/__mocks__/testUtils' -import { SUMMER_MONTH_END, SUMMER_MONTH_START } from 'utils/date' +import * as dateUtils from 'utils/date' import { hashFile } from 'utils/hash' import EcogestureService from './ecogesture.service' @@ -49,10 +54,6 @@ const mockQueryResultEmpty: QueryResult<Ecogesture[]> = { skip: 0, } -const currentMonth = new Date().getMonth() + 1 -const isSummerOrSpring = - currentMonth >= SUMMER_MONTH_START && currentMonth <= SUMMER_MONTH_END - describe('Ecogesture service', () => { const ecogestureService = new EcogestureService(mockClient) describe('getAllEcogestures', () => { @@ -198,56 +199,75 @@ describe('Ecogesture service', () => { }) describe('getEcogestureListByProfile', () => { - it('should return ecogesture list according to profile ecogesture, sorted and filtered, depending on the current season (WINTER/SUMMER)', async () => { - const mockProfileEcogestureFull: ProfileEcogesture = { - ...mockProfileEcogesture, - equipments: [EquipmentType.WASHING_MACHINE, EquipmentType.DISHWASHER], - } - + const mockProfileEcogestureFull: ProfileEcogesture = { + ...mockProfileEcogesture, + equipments: [ + EquipmentType.WASHING_MACHINE, + EquipmentType.DISHWASHER, + EquipmentType.AIR_CONDITIONING, + ], + } + it('should return ecogesture list according to profile ecogesture, sorted and filtered, for SUMMER season', async () => { mockClient.query.mockResolvedValueOnce(mockQueryResultMockedEcogestures) - + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(Season.SUMMER) const result = await ecogestureService.getEcogestureListByProfile( mockProfileEcogestureFull ) - - expect(result.length).toBe(2) - if (isSummerOrSpring) { - // eslint-disable-next-line jest/no-conditional-expect - expect(result[1]).toBe(mockedEcogesturesData[0]) - } else { - // eslint-disable-next-line jest/no-conditional-expect - expect(result[0]).toBe(mockedEcogesturesData[0]) - } + expect(result[0]).toBe(mockedEcogesturesData[1]) + expect(result[1]).toBe(mockedEcogesturesData[2]) + expect(result[2]).toBe(mockedEcogesturesData[0]) + }) + it('should return ecogesture list according to profile ecogesture, sorted and filtered, for WINTER season', async () => { + mockClient.query.mockResolvedValueOnce(mockQueryResultMockedEcogestures) + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(Season.WINTER) + const result = await ecogestureService.getEcogestureListByProfile( + mockProfileEcogestureFull + ) + expect(result[0]).toBe(mockedEcogesturesData[0]) + expect(result[1]).toBe(mockedEcogesturesData[2]) + expect(result[2]).toBe(mockedEcogesturesData[1]) + }) + it('should return ecogesture list according to profile ecogesture, sorted and filtered, for NO season', async () => { + mockClient.query.mockResolvedValueOnce(mockQueryResultMockedEcogestures) + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(null) + const result = await ecogestureService.getEcogestureListByProfile( + mockProfileEcogestureFull + ) + expect(result[0]).toBe(mockedEcogesturesData[0]) + expect(result[1]).toBe(mockedEcogesturesData[1]) + expect(result[2]).toBe(mockedEcogesturesData[2]) }) }) describe('calculateScore', () => { - describe('during summer season', () => { - if (isSummerOrSpring) { - it('should return correct scores for each ecogesture', () => { - const scores = mockedEcogesturesData.map(ecogesture => - ecogestureService.calculateScore(ecogesture) - ) - - expect(scores[0]).toBe(0) - expect(scores[1]).toBe(8) - expect(scores[2]).toBe(1) - }) - } + it('should return correct scores for each ecogesture for SUMMER season', () => { + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(Season.SUMMER) + const scores = mockedEcogesturesData.map(ecogesture => + ecogestureService.calculateScore(ecogesture) + ) + expect(scores[0]).toBe(0) + expect(scores[1]).toBe(8) + expect(scores[2]).toBe(1) }) - describe('during winter season', () => { - if (!isSummerOrSpring) { - it('should return correct scores for each ecogesture', () => { - const scores = mockedEcogesturesData.map(ecogesture => - ecogestureService.calculateScore(ecogesture) - ) + it('should return correct scores for each ecogesture for WINTER season', () => { + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(Season.WINTER) + const scores = mockedEcogesturesData.map(ecogesture => + ecogestureService.calculateScore(ecogesture) + ) + expect(scores[0]).toBe(8) + expect(scores[1]).toBe(0) + expect(scores[2]).toBe(1) + }) - expect(scores[0]).toBe(8) - expect(scores[1]).toBe(0) - expect(scores[2]).toBe(1) - }) - } + it('should return correct scores for each ecogesture for NO season', () => { + jest.spyOn(dateUtils, 'getCurrentSeason').mockReturnValue(null) + const scores = mockedEcogesturesData.map(ecogesture => + ecogestureService.calculateScore(ecogesture) + ) + expect(scores[0]).toBe(7) + expect(scores[1]).toBe(7) + expect(scores[2]).toBe(1) }) }) diff --git a/src/services/ecogesture.service.ts b/src/services/ecogesture.service.ts index c03e9950fc72a43365805a4f5d03bbaea6769406..819959ca2fe0ba3a17142f7c3541d203c1e959ab 100644 --- a/src/services/ecogesture.service.ts +++ b/src/services/ecogesture.service.ts @@ -128,16 +128,17 @@ export default class EcogestureService { const score = ecogesture.efficiency * 2 - ecogesture.difficulty const currentSeason = getCurrentSeason() - const oppositeSeason = getOppositeSeason(currentSeason) if (ecogesture.season !== Season.NONE) { if (ecogesture.season === currentSeason) { return score + 1 - } else if (ecogesture.season === oppositeSeason) { + } else if ( + currentSeason && + ecogesture.season === getOppositeSeason(currentSeason) + ) { return 0 } } - return score } diff --git a/src/utils/date.spec.ts b/src/utils/date.spec.ts index a1028add5844625ad644a9bd30cdacc365924758..1211870ea45c7af7833c5de84cffd1c79f7aac43 100644 --- a/src/utils/date.spec.ts +++ b/src/utils/date.spec.ts @@ -1,4 +1,4 @@ -import { FluidType, TimeStep } from 'enums' +import { FluidType, Season, TimeStep } from 'enums' import { DateTime } from 'luxon' import { Dataload } from 'models' import { graphData } from 'tests/__mocks__/chartData.mock' @@ -7,6 +7,7 @@ import { convertDateToMonthYearString, convertDateToShortDateString, getActualAnalysisDate, + getCurrentSeason, getLagDays, isLastDateReached, isLastPeriodReached, @@ -436,4 +437,50 @@ describe('date utils', () => { expect(result).toEqual(mockDate) }) }) + + describe('getCurrentSeason test', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + it('should return Season.SUMMER if the current month is between summer dates', () => { + const now = DateTime.local().setZone('utc', { + keepLocalTime: true, + }) + jest + .spyOn(DateTime, 'local') + .mockReturnValue(now.set({ month: 9, day: 21 })) + const currentSeason = getCurrentSeason() + expect(currentSeason).toEqual(Season.SUMMER) + }) + it('should return Season.WINTER if the current month is between winter dates', () => { + const now = DateTime.local().setZone('utc', { + keepLocalTime: true, + }) + jest + .spyOn(DateTime, 'local') + .mockReturnValue(now.set({ month: 3, day: 31 })) + const currentSeason = getCurrentSeason() + expect(currentSeason).toEqual(Season.WINTER) + }) + it('should return null if the current month is between summer and winter dates', () => { + const now = DateTime.local().setZone('utc', { + keepLocalTime: true, + }) + jest + .spyOn(DateTime, 'local') + .mockReturnValue(now.set({ month: 10, day: 2, year: 2024 })) + const currentSeason = getCurrentSeason() + expect(currentSeason).toBeNull() + }) + it('should return null if the current month is between winter and summer dates', () => { + const now = DateTime.local().setZone('utc', { + keepLocalTime: true, + }) + jest + .spyOn(DateTime, 'local') + .mockReturnValue(now.set({ month: 4, day: 20 })) + const currentSeason = getCurrentSeason() + expect(currentSeason).toBeNull() + }) + }) }) diff --git a/src/utils/date.ts b/src/utils/date.ts index 764ea5c0efa2af60aac76e79a30a5ec56d2ffcd3..434975bc19903b67813df3b1867bcd20dcfc8940 100644 --- a/src/utils/date.ts +++ b/src/utils/date.ts @@ -3,8 +3,17 @@ import { DateTime } from 'luxon' import { Dataload } from 'models' import { getMonthNameWithPrep } from './utils' -export const SUMMER_MONTH_START = 3 -export const SUMMER_MONTH_END = 8 +/** Between 21st of June and 20th of September */ +export const SUMMER_WEEK_DATES = { + start: 25, + end: 38, +} as const + +/** Between 31st of October and 30th of March */ +const WINTER_WEEK_DATES = { + start: 44, + end: 13, +} as const export function compareDates(dateA: DateTime, dateB: DateTime) { return dateA < dateB ? -1 : 1 @@ -150,16 +159,25 @@ export const getActualAnalysisDate = (): DateTime => { /** * Determines the current season based on the month of the year. - * @returns {Season} Returns Season.SUMMER if the current month is between March and August, and Season.WINTER for the rest of the months. + * @returns + * - Returns Season.SUMMER if the current month is between summer dates, + * - Returns Season.WINTER if the current month is between winter dates, + * - Otherwise returns null. */ -export function getCurrentSeason(): Season { - const currentMonth = new Date().getMonth() + 1 - - if (currentMonth >= SUMMER_MONTH_START && currentMonth <= SUMMER_MONTH_END) { +export function getCurrentSeason() { + const weekNumber = DateTime.local().weekNumber + if ( + weekNumber >= SUMMER_WEEK_DATES.start && + weekNumber <= SUMMER_WEEK_DATES.end + ) { return Season.SUMMER - } else { + } else if ( + weekNumber >= WINTER_WEEK_DATES.start || + weekNumber <= WINTER_WEEK_DATES.end + ) { return Season.WINTER } + return null } export function getOppositeSeason(currentSeason: Season): Season { diff --git a/src/utils/hash.spec.ts b/src/utils/hash.spec.ts index 54472af2ea4a7571e44487cdf60c31ee4c6edbbd..cd4a4d02c8a416016bceb54d98f71f1df89334f7 100644 --- a/src/utils/hash.spec.ts +++ b/src/utils/hash.spec.ts @@ -5,7 +5,7 @@ describe('hash utils test', () => { describe('hashFile test', () => { it('should return the correct hash of the file', () => { const result = hashFile(mockedEcogesturesData) - expect(result).toBe('cfe97043548a13a186b9545388804615c4feeb6f') + expect(result).toBe('bc5a72e07c44368c1841021ef0d42d9ed61de250') }) }) }) diff --git a/tests/__mocks__/ecogesturesData.mock.ts b/tests/__mocks__/ecogesturesData.mock.ts index 9cbfc7b6db7546cb975a9540bdfdc513289f45e3..c72c461c3c39c50fb934b4b4aabe63c86c23b0a1 100644 --- a/tests/__mocks__/ecogesturesData.mock.ts +++ b/tests/__mocks__/ecogesturesData.mock.ts @@ -64,7 +64,7 @@ export const mockedEcogesturesData: Ecogesture[] = [ "Utilisez la température la plus basse possible : de nombreux produits nettoyants sont efficaces à froid et un cycle à 90 °C consomme 3 fois plus d'énergie qu'un lavage à 40 °C. En effet, 80 % de l'énergie consommée par un lave-linge ou un lave-vaisselle sert au chauffage de l'eau ! Que ce soit pour la vaisselle ou le linge, les programmes de lavage intensif consomment jusqu'à 40 % de plus. Si possible, rincez à l'eau froide : la température de rinçage n'a pas d'effet sur le nettoyage du linge ou de la vaisselle. Attention cependant avec les tissus qui peuvent rétrécir : ce qui fait rétrécir, c'est le passage d'une température à une autre. Mieux vaut alors faire le cycle complet à l'eau froide pour les premiers lavages de tissus sensibles. Pour du linge ou de la vaisselle peu sales, utilisez la touche \"Eco\". Elle réduit la température de lavage et allonge sa durée (c’est le chauffage de l’eau qui consomme le plus). Vous économiserez jusqu’à 45 % par rapport aux cycles longs. Néanmoins, pour vous prémunir contre les bouchons de graisse dans les canalisations, faites quand même un cycle à chaud une fois par mois environ.", longName: 'J’utilise le plus souvent les cycles courts à basse température pour laver le linge et la vaisselle.', - shortName: 'Accelerateur de particules', + shortName: 'Accélérateur de particules', usage: Usage.ELECTRICITY_SPECIFIC, impactLevel: 2, efficiency: 1,