Skip to content
Snippets Groups Projects
utils.spec.ts 14.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • import {
      FluidSlugType,
      FluidState,
      FluidType,
      KonnectorUpdate,
      Season,
    } from 'enums'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { DateTime } from 'luxon'
    
    import { FluidStatus } from 'models'
    
    import {
    
      formatListWithAnd,
    
      formatNumberValues,
    
      formatOffPeakHours,
      formatTwoDigits,
    
      getChallengeTitleWithLineReturn,
    
      getFluidName,
    
      getKonnectorUpdateError,
      getMonthFullName,
      getMonthName,
    
      getSeason,
    
      isKonnectorActive,
    
      isValidOffPeakHours,
      parseOffPeakHours,
      roundOffPeakHours,
      splitOffPeakHours,
    
    } from './utils'
    
    describe('utils test', () => {
      describe('getKonnectorSlug', () => {
        it('should return correct slug for elec', () => {
          const slug = getKonnectorSlug(FluidType.ELECTRICITY)
          expect(slug).toBe(FluidSlugType.ELECTRICITY)
        })
        it('should return correct slug for water', () => {
          const slug = getKonnectorSlug(FluidType.WATER)
          expect(slug).toBe(FluidSlugType.WATER)
        })
        it('should return correct slug for gas', () => {
          const slug = getKonnectorSlug(FluidType.GAS)
          expect(slug).toBe(FluidSlugType.GAS)
        })
    
        it('should throw error for invalid fluid type', () => {
          expect(() => getKonnectorSlug(99 as FluidType.GAS)).toThrow(
            'unknown fluidtype'
          )
        })
    
      describe('getKonnectorUpdateError', () => {
        it('should return KonnectorUpdate.ERROR_UPDATE_OAUTH for USER_ACTION_NEEDED.OAUTH_OUTDATED', () => {
          const result = getKonnectorUpdateError(
            'USER_ACTION_NEEDED.OAUTH_OUTDATED'
          )
          expect(result).toBe(KonnectorUpdate.ERROR_UPDATE_OAUTH)
        })
        it('should return KonnectorUpdate.LOGIN_FAILED for LOGIN_FAILED', () => {
          const result = getKonnectorUpdateError('LOGIN_FAILED')
          expect(result).toBe(KonnectorUpdate.LOGIN_FAILED)
        })
    
        it('should return KonnectorUpdate.ERROR_UPDATE for CHALLENGE_ASKED', () => {
    
          const result = getKonnectorUpdateError('CHALLENGE_ASKED')
    
          expect(result).toBe(KonnectorUpdate.ERROR_UPDATE)
    
        })
        it('should return KonnectorUpdate.ERROR_UPDATE for an unknown type', () => {
          const result = getKonnectorUpdateError('UNKNOWN_TYPE')
          expect(result).toBe(KonnectorUpdate.ERROR_UPDATE)
        })
      })
    
      describe('isKonnectorActive', () => {
        describe('for MULTIFLUID', () => {
          it('should return false when all fluids are not connected', () => {
            const fluidStatus = [
              { status: FluidState.NOT_CONNECTED },
              { status: FluidState.KONNECTOR_NOT_FOUND },
              { status: FluidState.NOT_CONNECTED },
            ] as FluidStatus[]
            const result = isKonnectorActive(fluidStatus, FluidType.MULTIFLUID)
            expect(result).toBe(false)
          })
          it('should return true when some fluids are connected', () => {
            const fluidStatus = [
              { status: FluidState.DONE },
              { status: FluidState.NOT_CONNECTED },
              { status: FluidState.DONE },
            ] as FluidStatus[]
            const result = isKonnectorActive(fluidStatus, FluidType.MULTIFLUID)
            expect(result).toBe(true)
          })
        })
    
        describe('for SINGLE fluids', () => {
          it('should return false for a single fluid not connected', () => {
            const fluidStatus = [
              {},
              {
                status: FluidState.NOT_CONNECTED,
                fluidType: FluidType.GAS,
              },
              {
                status: FluidState.KONNECTOR_NOT_FOUND,
                fluidType: FluidType.WATER,
              },
            ] as FluidStatus[]
            expect(isKonnectorActive(fluidStatus, FluidType.GAS)).toBe(false)
            expect(isKonnectorActive(fluidStatus, FluidType.WATER)).toBe(false)
          })
          it('should return true for a single fluid connected', () => {
            const fluidStatus = [
              {
                status: FluidState.DONE,
                fluidType: FluidType.ELECTRICITY,
              },
              { status: FluidState.ERROR, fluidType: FluidType.WATER },
    
              { status: FluidState.LOGIN_FAILED, fluidType: FluidType.GAS },
    
            ] as FluidStatus[]
            expect(isKonnectorActive(fluidStatus, FluidType.ELECTRICITY)).toBe(true)
            expect(isKonnectorActive(fluidStatus, FluidType.GAS)).toBe(true)
            expect(isKonnectorActive(fluidStatus, FluidType.WATER)).toBe(true)
          })
        })
      })
    
    
      describe('formatNumberValues test', () => {
        it('should return --,-- if there is not value', () => {
          const result = formatNumberValues(null)
          expect(result).toBe('--,--')
        })
    
        it('should return a value at english number format two digits decimal', () => {
          const result = formatNumberValues(2000.555)
          expect(result).toEqual('2 000,56')
        })
    
        it('should return a float value', () => {
          const result = formatNumberValues(2000.55, '', true)
          expect(result).toEqual(2000)
        })
      })
    
      describe('getSeason test', () => {
        it('should return summer', () => {
          const now = DateTime.local().setZone('utc', {
            keepLocalTime: true,
          })
          jest
            .spyOn(DateTime, 'local')
            .mockReturnValueOnce(now.set({ day: 12, month: 6, year: 2021 }))
          const result = getSeason()
          expect(result).toBe(Season.SUMMER)
        })
    
        it('should return winter', () => {
          const now = DateTime.local().setZone('utc', {
            keepLocalTime: true,
          })
          jest
            .spyOn(DateTime, 'local')
            .mockReturnValueOnce(now.set({ day: 1, month: 12, year: 2021 }))
          const result = getSeason()
          expect(result).toBe(Season.WINTER)
        })
    
        it('should return none', () => {
          const now = DateTime.local().setZone('utc', {
            keepLocalTime: true,
          })
          jest
            .spyOn(DateTime, 'local')
            .mockReturnValueOnce(now.set({ day: 1, month: 10, year: 2021 }))
          const result = getSeason()
          expect(result).toBe(Season.NONE)
        })
      })
    
    
      describe('getChallengeTitleWithLineReturn test', () => {
        it('should return Simone\\nVEILLE', () => {
          expect(getChallengeTitleWithLineReturn('CHALLENGE0001')).toBe(
            'Simone\nVEILLE'
          )
        })
        it('should return undefined', () => {
          expect(getChallengeTitleWithLineReturn('CHALLENGE0000')).toBe(undefined)
        })
      })
    
    
      describe('getMonthFullName', () => {
        it('should return the name of the month', () => {
          expect(getMonthFullName(3)).toBe('Mars')
        })
      })
    
    
      describe('getMonthName', () => {
    
        it('should return the name of the month', () => {
          expect(getMonthName(DateTime.local(2023, 6, 1))).toBe('juin')
        })
      })
    
      describe('getMonthNameWithPrep', () => {
    
        it('should return the name of the month with " de "', () => {
    
          const date = DateTime.fromISO('2020-11-29T23:59:59.999Z')
          expect(getMonthNameWithPrep(date)).toBe('de novembre')
        })
    
    
        it('should return the name of the month with " d\'"', () => {
    
          const date = DateTime.fromISO('2020-10-29T23:59:59.999Z')
          expect(getMonthNameWithPrep(date)).toBe('d’octobre')
        })
      })
    
    
      describe('getFluidName', () => {
        it('should return electricity', () => {
          expect(getFluidName(FluidType.ELECTRICITY)).toBe('electricity')
        })
        it('should return water', () => {
          expect(getFluidName(FluidType.WATER)).toBe('water')
        })
        it('should return gas', () => {
          expect(getFluidName(FluidType.GAS)).toBe('gas')
        })
        it('should return multifluid', () => {
          expect(getFluidName(FluidType.MULTIFLUID)).toBe('multifluid')
        })
      })
    
      describe('getFluidTypeTranslation', () => {
        it('should return electricity', () => {
          expect(getFluidTypeTranslation(FluidType.ELECTRICITY)).toBe(
            "d'électricité"
          )
        })
        it('should return water', () => {
          expect(getFluidTypeTranslation(FluidType.WATER)).toBe("d'eau")
        })
        it('should return gas', () => {
          expect(getFluidTypeTranslation(FluidType.GAS)).toBe('de gaz')
        })
        it('should throw error for invalid fluid type', () => {
          expect(() => getFluidTypeTranslation(99 as FluidType.GAS)).toThrow(
            'unexpected fluidtype'
          )
        })
      })
    
      describe('getPartnerKey', () => {
        it('should return enedis', () => {
          expect(getPartnerKey(FluidType.ELECTRICITY)).toBe('enedis')
        })
        it('should return egl', () => {
          expect(getPartnerKey(FluidType.WATER)).toBe('egl')
        })
        it('should return grdf', () => {
          expect(getPartnerKey(FluidType.GAS)).toBe('grdf')
        })
        it('should throw error for invalid fluid type', () => {
          expect(() => getPartnerKey(99 as FluidType.GAS)).toThrow(
            'unknown fluidtype'
          )
        })
      })
    
    
      describe('getFluidLabel', () => {
        it('should return elec', () => {
          expect(getFluidLabel(FluidType.ELECTRICITY)).toBe('elec')
        })
        it('should return gas', () => {
          expect(getFluidLabel(FluidType.GAS)).toBe('gaz')
        })
        it('should return water', () => {
          expect(getFluidLabel(FluidType.WATER)).toBe('water')
        })
        it('should return multi', () => {
          expect(getFluidLabel(FluidType.MULTIFLUID)).toBe('multi')
        })
      })
    
    
      describe('formatListWithAnd', () => {
        it('should return empty string', () => {
          expect(formatListWithAnd([])).toBe('')
        })
        it('should return single element', () => {
          expect(formatListWithAnd(['pomme'])).toBe('pomme')
        })
        it('should return two elements joined by "et"', () => {
          expect(formatListWithAnd(['pomme', 'banane'])).toBe('pomme et banane')
        })
        it('should return elements joined by commas except the last one with "et"', () => {
          expect(formatListWithAnd(['pomme', 'banane', 'cerise'])).toBe(
            'pomme, banane et cerise'
          )
        })
      })
    
    
      describe('isValidOffPeakHours', () => {
        it('should return true for valid off-peak hours format', () => {
          expect(isValidOffPeakHours('4H00-6H00')).toBe(true)
          expect(isValidOffPeakHours('14H26-18H20')).toBe(true)
          expect(isValidOffPeakHours('0H00-23H59')).toBe(true)
        })
    
        it('should return false for invalid off-peak hours format', () => {
          expect(isValidOffPeakHours('invalid')).toBe(false) // unexpected string
          expect(isValidOffPeakHours('2H30')).toBe(false) // Missing end of range
          expect(isValidOffPeakHours('2H60-6H00')).toBe(false) // Minutes out of range
          expect(isValidOffPeakHours('24H00-6H00')).toBe(false) // Hour out of range
        })
      })
    
      describe('parseOffPeakHours', () => {
        it('should return empty array', () => {
          expect(parseOffPeakHours('')).toStrictEqual([])
        })
        it('should return single interval', () => {
          expect(parseOffPeakHours('22H00-6H00')).toStrictEqual([
            { start: { hour: 22, minute: 0 }, end: { hour: 6, minute: 0 } },
          ])
        })
        it('should return two intervals', () => {
          expect(parseOffPeakHours('3H00-8H00;13H30-16H30')).toStrictEqual([
            { start: { hour: 3, minute: 0 }, end: { hour: 8, minute: 0 } },
            { start: { hour: 13, minute: 30 }, end: { hour: 16, minute: 30 } },
          ])
        })
        it('should return empty array because range is incomplete', () => {
          expect(parseOffPeakHours('3H00-')).toStrictEqual([])
        })
        it('should return empty array because time is not valid', () => {
          expect(parseOffPeakHours('51H00-98H99')).toStrictEqual([])
        })
      })
      describe('formatTwoDigits', () => {
        it('should return number with padding', () => {
          expect(formatTwoDigits(5)).toBe('05')
        })
        it('should return number without padding', () => {
          expect(formatTwoDigits(42)).toBe('42')
        })
      })
      describe('formatOffPeakHours', () => {
        it('should format correctly', () => {
          expect(
            formatOffPeakHours({
              start: { hour: 2, minute: 0 },
              end: { hour: 10, minute: 30 },
            })
          ).toBe('02H00-10H30')
        })
      })
      describe('splitOffPeakHours', () => {
        it('should split off-peak hours that cross midnight', () => {
          const offPeakHours = [
            { start: { hour: 22, minute: 0 }, end: { hour: 6, minute: 0 } },
          ]
          const expectedSplitOffPeakHours = [
            { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } },
            { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } },
          ]
          const result = splitOffPeakHours(offPeakHours)
          expect(result).toEqual(expectedSplitOffPeakHours)
        })
        it('should not split off-peak hours that do not cross midnight', () => {
          const offPeakHours = [
            { start: { hour: 8, minute: 0 }, end: { hour: 12, minute: 0 } },
          ]
          const result = splitOffPeakHours(offPeakHours)
          expect(result).toEqual(offPeakHours)
        })
      })
      describe('roundOffPeakHours', () => {
        it('rounds off-peak hours to the nearest half-hour', () => {
          const offPeakHours = [
            { start: { hour: 2, minute: 2 }, end: { hour: 10, minute: 58 } },
            { start: { hour: 1, minute: 58 }, end: { hour: 11, minute: 2 } },
            { start: { hour: 7, minute: 15 }, end: { hour: 14, minute: 45 } },
            { start: { hour: 1, minute: 30 }, end: { hour: 3, minute: 0 } },
          ]
          const roundedOffPeakHours = roundOffPeakHours(offPeakHours)
          expect(roundedOffPeakHours).toEqual([
            { start: { hour: 2, minute: 0 }, end: { hour: 11, minute: 0 } },
            { start: { hour: 2, minute: 0 }, end: { hour: 11, minute: 0 } },
            { start: { hour: 7, minute: 30 }, end: { hour: 15, minute: 0 } },
            { start: { hour: 1, minute: 30 }, end: { hour: 3, minute: 0 } },
          ])
        })
        it('rounds off-peak hours to midnight', () => {
          const offPeakHours = [
            { start: { hour: 0, minute: 5 }, end: { hour: 4, minute: 0 } },
            { start: { hour: 23, minute: 55 }, end: { hour: 4, minute: 0 } },
            { start: { hour: 16, minute: 0 }, end: { hour: 23, minute: 55 } },
            { start: { hour: 16, minute: 0 }, end: { hour: 0, minute: 5 } },
          ]
          const roundedOffPeakHours = roundOffPeakHours(offPeakHours)
          expect(roundedOffPeakHours).toEqual([
            { start: { hour: 0, minute: 0 }, end: { hour: 4, minute: 0 } },
            { start: { hour: 0, minute: 0 }, end: { hour: 4, minute: 0 } },
            { start: { hour: 16, minute: 0 }, end: { hour: 23, minute: 59 } },
            { start: { hour: 16, minute: 0 }, end: { hour: 23, minute: 59 } },
          ])
        })
      })
    
    
      describe('getFluidUnit', () => {
        it('should return kWh for ELECTRICITY', () => {
          expect(getFluidUnit(FluidType.ELECTRICITY)).toBe('kWh')
        })
        it('should return L for WATER', () => {
          expect(getFluidUnit(FluidType.WATER)).toBe('L')
        })
        it('should return € for MULTIFLUID', () => {
          expect(getFluidUnit(FluidType.MULTIFLUID)).toBe('')
        })
        it('should throw error for invalid fluid type', () => {
          expect(() => getFluidUnit(99 as FluidType.GAS)).toThrow(
            'unknown fluidtype'
          )
        })
      })