import { inject , TestBed } from "@angular/core/testing" ; import { ZonesService } from "./zones.service" ; import * as _ from "lodash" ; import { ZONE_DEFINITIONS } from "../zone-definitions" ; import { UserZonesModel , ZoneModel } from "@elevate/shared/models" ; import { userSettingsData } from "@elevate/shared/data" ; import { ZoneChangeWhisperModel } from "./zone-change-whisper.model" ; import { ZoneChangeOrderModel } from "./zone-change-order.model" ; import { ZoneDefinitionModel } from "../../shared/models/zone-definition.model" ; import { CoreModule } from "../../core/core.module" ; import { SharedModule } from "../../shared/shared.module" ; describe ( "ZonesService" , ( ) => { let zonesService ; let saveZonesSpy ; beforeEach ( ( done ) => { TestBed . configureTestingModule ( { imports : [ CoreModule , SharedModule ] } ) ; zonesService = TestBed . get ( ZonesService ) ; saveZonesSpy = spyOn ( zonesService . userSettingsService , "saveZones" ) ; saveZonesSpy . and . returnValue ( Promise . resolve ( ) ) ; zonesService . currentZones = [ { from : 0 , to : 10 } , { from : 10 , to : 20 } , { from : 20 , to : 30 } , { from : 30 , to : 40 } , { from : 40 , to : 50 } , { from : 50 , to : 60 } , { from : 60 , to : 70 } , { from : 70 , to : 80 } , { from : 80 , to : 90 } , { from : 90 , to : 100 } ] ; done ( ) ; } ) ; it ( "should be created" , inject ( [ ZonesService ] , ( zoneService ) => { expect ( zoneService ) . toBeTruthy ( ) ; } ) ) ; it ( "should add a last zone" , ( done ) => { const expectedZonesLength = 11 ; const expectedZoneIdAdded = 11 ; const addZoneLastPromise = zonesService . addLastZone ( ) ; addZoneLastPromise . then ( ( result ) => { const lastAddedZone = _ . last ( zonesService . currentZones ) ; expect ( result ) . not . toBeNull ( ) ; expect ( result ) . toEqual ( "Zone <" + expectedZoneIdAdded + "> has been added." ) ; expect ( zonesService . currentZones . length ) . toBe ( expectedZonesLength ) ; expect ( lastAddedZone . from ) . toBe ( 95 ) ; expect ( lastAddedZone . to ) . toBe ( 100 ) ; done ( ) ; } ) ; } ) ; it ( "should not add last zone if MAX zone count reached" , ( done ) => { const MAX_ZONE_COUNT = 10 ; spyOn ( zonesService , "getMaxZoneCount" ) . and . returnValue ( MAX_ZONE_COUNT ) ; const addZoneLastPromise = zonesService . addLastZone ( ) ; addZoneLastPromise . then ( ( result ) => { expect ( result ) . toBeNull ( ) ; done ( ) ; } , ( error ) => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "You can't add more than " + MAX_ZONE_COUNT + " zones..." ) ; expect ( zonesService . currentZones . length ) . toBe ( MAX_ZONE_COUNT ) ; done ( ) ; } ) ; } ) ; it ( "should remove a last zone" , ( done ) => { const expectedZonesLength = 9 ; const expectedZoneIdRemoved = 10 ; const removeZoneLastPromise = zonesService . removeLastZone ( ) ; removeZoneLastPromise . then ( ( result ) => { expect ( result ) . not . toBeNull ( ) ; expect ( result ) . toEqual ( "Zone <" + expectedZoneIdRemoved + "> has been removed." ) ; expect ( zonesService . currentZones . length ) . toBe ( expectedZonesLength ) ; const lastZone = _ . last ( zonesService . currentZones ) ; expect ( lastZone . from ) . toBe ( 80 ) ; expect ( lastZone . to ) . toBe ( 90 ) ; done ( ) ; } ) ; } ) ; it ( "should not remove last zone if MIN zone count reached" , ( done ) => { const MIN_ZONE_COUNT = 10 ; spyOn ( zonesService , "getMinZoneCount" ) . and . returnValue ( MIN_ZONE_COUNT ) ; const removeZoneLastPromise = zonesService . removeLastZone ( ) ; removeZoneLastPromise . then ( ( result ) => { expect ( result ) . toBeNull ( ) ; done ( ) ; } , ( error ) => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "You can't remove more than " + MIN_ZONE_COUNT + " zones..." ) ; expect ( zonesService . currentZones . length ) . toBe ( MIN_ZONE_COUNT ) ; done ( ) ; } ) ; } ) ; it ( "should remove zone at index" , ( done ) => { const removeIndex = 4 ; const expectedZonesLength = 9 ; const removeZoneAtIndexPromise = zonesService . removeZoneAtIndex ( removeIndex ) ; removeZoneAtIndexPromise . then ( ( result ) => { expect ( result ) . not . toBeNull ( ) ; expect ( result ) . toEqual ( "Zone <" + ( removeIndex + 1 ) + "> has been removed." ) ; expect ( zonesService . currentZones . length ) . toBe ( expectedZonesLength ) ; const previousZone = zonesService . currentZones [ removeIndex - 1 ] ; const newNextZone = zonesService . currentZones [ removeIndex ] ; expect ( newNextZone . from ) . toBe ( previousZone . to ) ; done ( ) ; } ) ; } ) ; it ( "should remove zone at index of first zone" , ( done ) => { const removeIndex = 0 ; const expectedZonesLength = 9 ; const oldNextZone = _ . clone ( zonesService . currentZones [ removeIndex + 1 ] ) ; const removeZoneAtIndexPromise = zonesService . removeZoneAtIndex ( removeIndex ) ; removeZoneAtIndexPromise . then ( ( result ) => { expect ( result ) . not . toBeNull ( ) ; expect ( result ) . toEqual ( "Zone <" + ( removeIndex + 1 ) + "> has been removed." ) ; expect ( zonesService . currentZones . length ) . toBe ( expectedZonesLength ) ; const newFirstZone = zonesService . currentZones [ removeIndex ] ; expect ( newFirstZone . from ) . toBe ( oldNextZone . from ) ; expect ( newFirstZone . to ) . toBe ( oldNextZone . to ) ; done ( ) ; } ) ; } ) ; it ( "should remove zone at index of last zone" , ( done ) => { const removeIndex = 9 ; const expectedZonesLength = 9 ; const oldPreviousZone = _ . clone ( zonesService . currentZones [ removeIndex - 1 ] ) ; const removeZoneAtIndexPromise = zonesService . removeZoneAtIndex ( removeIndex ) ; removeZoneAtIndexPromise . then ( ( result ) => { expect ( result ) . not . toBeNull ( ) ; expect ( result ) . toEqual ( "Zone <" + ( removeIndex + 1 ) + "> has been removed." ) ; expect ( zonesService . currentZones . length ) . toBe ( expectedZonesLength ) ; const newLastZone = _ . last ( zonesService . currentZones ) ; expect ( newLastZone . from ) . toBe ( oldPreviousZone . from ) ; expect ( newLastZone . to ) . toBe ( oldPreviousZone . to ) ; done ( ) ; } ) ; } ) ; it ( "should not remove zone at index if MIN zone count reached" , ( done ) => { const MIN_ZONE_COUNT = 10 ; const removeIndex = 6 ; spyOn ( zonesService , "getMinZoneCount" ) . and . returnValue ( MIN_ZONE_COUNT ) ; const removeZoneAtIndexPromise = zonesService . removeZoneAtIndex ( removeIndex ) ; removeZoneAtIndexPromise . then ( ( result ) => { expect ( result ) . toBeNull ( ) ; done ( ) ; } , ( error ) => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "You can't remove more than " + MIN_ZONE_COUNT + " zones..." ) ; expect ( zonesService . currentZones . length ) . toBe ( MIN_ZONE_COUNT ) ; done ( ) ; } ) ; } ) ; it ( "should notify the previous Zone \"TO\" when his own \"FROM\" has been changed" , ( done ) => { const index = 2 ; const updatedFromValue = zonesService . currentZones [ index ] . from + 1 ; const zoneChange = { sourceId : index , from : true , to : false , value : updatedFromValue } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( _ . isEmpty ( change ) ) . toBeFalsy ( ) ; expect ( change . sourceId ) . toEqual ( index ) ; expect ( change . destinationId ) . toEqual ( index - 1 ) ; expect ( change . to ) . toBeTruthy ( ) ; expect ( change . from ) . toBeFalsy ( ) ; expect ( change . value ) . toEqual ( updatedFromValue ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should not notify the previous Zone if \"FROM\" has changed & zone edited is the first" , ( done ) => { const index = 0 ; const updatedFromValue = zonesService . currentZones [ index ] . from + 1 ; const zoneChange = { sourceId : index , from : true , to : false , value : updatedFromValue } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( change ) . toBeNull ( ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should notify the next Zone \"FROM\" when his own \"TO\" has been changed" , ( done ) => { const index = 7 ; const updatedToValue = zonesService . currentZones [ index ] . to - 1 ; const zoneChange = { sourceId : index , from : false , to : true , value : updatedToValue } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( _ . isEmpty ( change ) ) . toBeFalsy ( ) ; expect ( change . sourceId ) . toEqual ( index ) ; expect ( change . destinationId ) . toEqual ( index + 1 ) ; expect ( change . from ) . toBeTruthy ( ) ; expect ( change . to ) . toBeFalsy ( ) ; expect ( change . value ) . toEqual ( updatedToValue ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should notify the next Zone \"FROM\" when his own \"TO\" has been changed & zone edited is the first" , ( done ) => { const index = 0 ; const updatedToValue = zonesService . currentZones [ index ] . to + 4 ; const zoneChange = { sourceId : index , from : false , to : true , value : updatedToValue } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( _ . isEmpty ( change ) ) . toBeFalsy ( ) ; expect ( change . sourceId ) . toEqual ( index ) ; expect ( change . destinationId ) . toEqual ( index + 1 ) ; expect ( change . from ) . toBeTruthy ( ) ; expect ( change . to ) . toBeFalsy ( ) ; expect ( change . value ) . toEqual ( updatedToValue ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should not notify the next Zone if \"TO\" has changed & zone edited is the latest" , ( done ) => { const index = 9 ; const updatedToValue = zonesService . currentZones [ index ] . to + 1 ; const zoneChange = { sourceId : index , from : false , to : true , value : updatedToValue } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( change ) . toBeNull ( ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should fail when \"FROM\" & \"TO\" change are equals" , ( done ) => { const zoneChange = { sourceId : 5 , from : true , to : true , value : 99 } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( change ) . toBeNull ( ) ; done ( ) ; } , error => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toBe ( "Impossible to notify both 'from' & 'to' changes at the same time" ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should fail when value is not a number" , ( done ) => { const zoneChange = { sourceId : 3 , from : true , to : false , value : null } ; zonesService . zoneChangeOrderUpdates . subscribe ( ( change ) => { expect ( change ) . toBeNull ( ) ; done ( ) ; } , error => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toBe ( "Value provided is not a number" ) ; done ( ) ; } ) ; zonesService . whisperZoneChange ( zoneChange ) ; } ) ; it ( "should return compliant zones" , ( done ) => { const currentZones = zonesService . currentZones ; const error = zonesService . isZonesCompliant ( currentZones ) ; expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; it ( "should return not compliant zones with error on a \"FROM\"" , ( done ) => { const FAKE_WRONG_ZONES = [ { from : 0 , to : 10 } , { from : 10 , to : 20 } , { from : 20 , to : 30 } , { from : 99 , to : 40 } , { from : 40 , to : 50 } , { from : 50 , to : 60 } , { from : 60 , to : 70 } , { from : 70 , to : 80 } , { from : 80 , to : 90 } , { from : 90 , to : 100 } ] ; const error = zonesService . isZonesCompliant ( FAKE_WRONG_ZONES ) ; expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "Not compliant zones provided: pattern is not respected." ) ; done ( ) ; } ) ; it ( "should return not compliant zones with error on a \"TO\"" , ( done ) => { const FAKE_WRONG_ZONES = [ { from : 0 , to : 10 } , { from : 10 , to : 20 } , { from : 20 , to : 30 } , { from : 30 , to : 40 } , { from : 40 , to : 50 } , { from : 50 , to : 61 } , { from : 60 , to : 70 } , { from : 70 , to : 80 } , { from : 80 , to : 90 } , { from : 90 , to : 100 } ] ; const error = zonesService . isZonesCompliant ( FAKE_WRONG_ZONES ) ; expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "Not compliant zones provided: pattern is not respected." ) ; done ( ) ; } ) ; it ( "should return not compliant zones with MAX zone count reached" , ( done ) => { const MAX_ZONE_COUNT = 10 ; const FAKE_WRONG_ZONES = [ { from : 0 , to : 10 } , { from : 10 , to : 20 } , { from : 20 , to : 30 } , { from : 30 , to : 40 } , { from : 40 , to : 50 } , { from : 50 , to : 60 } , { from : 60 , to : 70 } , { from : 70 , to : 80 } , { from : 80 , to : 90 } , { from : 90 , to : 100 } , { from : 100 , to : 110 } , ] ; spyOn ( zonesService , "getMaxZoneCount" ) . and . returnValue ( MAX_ZONE_COUNT ) ; const error = zonesService . isZonesCompliant ( FAKE_WRONG_ZONES ) ; expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "Not compliant zones provided: expected at max " + zonesService . getMaxZoneCount ( ) + " zones" ) ; done ( ) ; } ) ; it ( "should return not compliant zones with MIN zone count reached" , ( done ) => { const MIN_ZONE_COUNT = 5 ; const FAKE_WRONG_ZONES = [ { from : 0 , to : 10 } , { from : 10 , to : 20 } , { from : 20 , to : 30 } , { from : 30 , to : 40 } ] ; spyOn ( zonesService , "getMinZoneCount" ) . and . returnValue ( MIN_ZONE_COUNT ) ; const error = zonesService . isZonesCompliant ( FAKE_WRONG_ZONES ) ; expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "Not compliant zones provided: expected at least " + zonesService . getMinZoneCount ( ) + " zones" ) ; done ( ) ; } ) ; it ( "should return not compliant zones is zone empty" , ( done ) => { const zones = null ; const error = zonesService . isZonesCompliant ( zones ) ; expect ( error ) . not . toBeNull ( ) ; done ( ) ; } ) ; it ( "should reset zones to default" , ( done ) => { const FAKE_EXISTING_ZONES = [ { from : 0 , to : 110 } , { from : 110 , to : 210 } , { from : 210 , to : 310 } , { from : 310 , to : 410 } , { from : 410 , to : 510 } , { from : 510 , to : 611 } , { from : 610 , to : 710 } , { from : 710 , to : 810 } , { from : 810 , to : 910 } , { from : 910 , to : 1100 } , ] ; const SPEED_ZONE_DEFINITION_MOCKED = _ . find ( ZONE_DEFINITIONS , { value : "speed" } ) ; const expectedResetZones = UserZonesModel . deserialize ( userSettingsData . zones . speed ) ; zonesService . currentZones = FAKE_EXISTING_ZONES ; zonesService . zoneDefinition = SPEED_ZONE_DEFINITION_MOCKED ; const saveZonesSpy = spyOn ( zonesService , "saveZones" ) . and . returnValue ( Promise . resolve ( true ) ) ; const zonesUpdatesSpy = spyOn ( zonesService . zonesUpdates , "next" ) ; const promiseReset = zonesService . resetZonesToDefault ( ) ; promiseReset . then ( ( ) => { expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( zonesUpdatesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( zonesService . currentZones . length ) . toEqual ( expectedResetZones . length ) ; expect ( zonesService . currentZones . length ) . not . toEqual ( FAKE_EXISTING_ZONES . length ) ; expect ( zonesService . currentZones ) . toEqual ( expectedResetZones ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; } ) ; it ( "should save zones" , ( done ) => { const zonesCompliantSpy = spyOn ( zonesService , "isZonesCompliant" ) . and . returnValue ( null ) ; const zoneModels = [ { from : 0 , to : 110 } , { from : 110 , to : 210 } ] ; saveZonesSpy . and . returnValue ( Promise . resolve ( zoneModels ) ) ; const markLocalStorageClearSpy = spyOn ( zonesService . userSettingsService , "clearLocalStorageOnNextLoad" ) ; const promiseSave = zonesService . saveZones ( ) ; promiseSave . then ( ( ) => { expect ( zonesCompliantSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( markLocalStorageClearSpy ) . toHaveBeenCalledTimes ( 1 ) ; done ( ) ; } , error => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; } ) ; it ( "should not save zones that are not compliant" , ( done ) => { const fakeError = "FakeError" ; const zonesCompliantSpy = spyOn ( zonesService , "isZonesCompliant" ) . and . returnValue ( fakeError ) ; saveZonesSpy . and . returnValue ( Promise . resolve ( true ) ) ; const markLocalStorageClearSpy = spyOn ( zonesService . userSettingsService , "clearLocalStorageOnNextLoad" ) ; const promiseSave = zonesService . saveZones ( ) ; promiseSave . then ( ( ) => { expect ( true ) . toBeFalsy ( "Test should no go there" ) ; done ( ) ; } , error => { expect ( error ) . toBe ( fakeError ) ; expect ( zonesCompliantSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 0 ) ; expect ( markLocalStorageClearSpy ) . toHaveBeenCalledTimes ( 0 ) ; done ( ) ; } ) ; } ) ; it ( "should not save zones on saveZones rejection" , ( done ) => { const fakeError = "UpdateZones Error!" ; const zonesCompliantSpy = spyOn ( zonesService , "isZonesCompliant" ) . and . returnValue ( null ) ; saveZonesSpy . and . returnValue ( Promise . reject ( fakeError ) ) ; const markLocalStorageClearSpy = spyOn ( zonesService . userSettingsService , "clearLocalStorageOnNextLoad" ) ; const promiseSave = zonesService . saveZones ( ) ; promiseSave . then ( ( ) => { expect ( true ) . toBeFalsy ( "Test should no go there" ) ; done ( ) ; } , error => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toBe ( fakeError ) ; expect ( zonesCompliantSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( markLocalStorageClearSpy ) . toHaveBeenCalledTimes ( 0 ) ; done ( ) ; } ) ; } ) ; it ( "should not save zones on clearLocalStorageOnNextLoad rejection" , ( done ) => { const fakeError = "clearLocalStorageOnNextLoad Error!" ; const zonesCompliantSpy = spyOn ( zonesService , "isZonesCompliant" ) . and . returnValue ( null ) ; const zoneModels = [ { from : 0 , to : 110 } , { from : 110 , to : 210 } ] ; saveZonesSpy . and . returnValue ( Promise . resolve ( zoneModels ) ) ; const markLocalStorageClearSpy = spyOn ( zonesService . userSettingsService , "clearLocalStorageOnNextLoad" ) . and . returnValue ( Promise . reject ( fakeError ) ) ; const promiseSave = zonesService . saveZones ( ) ; promiseSave . then ( ( ) => { expect ( true ) . toBeFalsy ( "Test should no go there" ) ; done ( ) ; } , error => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toBe ( fakeError ) ; expect ( zonesCompliantSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( markLocalStorageClearSpy ) . toHaveBeenCalledTimes ( 1 ) ; done ( ) ; } ) ; } ) ; it ( "should notify step changes" , ( done ) => { const step = 0.25 ; const stepUpdatesSpy = spyOn ( zonesService . stepUpdates , "next" ) ; zonesService . notifyStepChange ( step ) ; expect ( stepUpdatesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( stepUpdatesSpy ) . toHaveBeenCalledWith ( step ) ; done ( ) ; } ) ; it ( "should import zones" , ( done ) => { const jsonInput = "[{\"from\":120,\"to\":140},{\"from\":140,\"to\":150},{\"from\":150,\"to\":160}]" ; const zonesToImport = < ZoneModel [ ] > JSON . parse ( jsonInput ) ; const saveZonesSpy = spyOn ( zonesService , "saveZones" ) . and . returnValue ( Promise . resolve ( true ) ) ; const zonesUpdatesSpy = spyOn ( zonesService . zonesUpdates , "next" ) ; const promiseImport = zonesService . importZones ( jsonInput ) ; promiseImport . then ( ( ) => { expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( zonesUpdatesSpy ) . toHaveBeenCalledTimes ( 1 ) ; expect ( zonesService . currentZones ) . toEqual ( zonesToImport ) ; expect ( zonesService . currentZones . length ) . toEqual ( zonesToImport . length ) ; done ( ) ; } , ( error ) => { expect ( error ) . toBeNull ( ) ; done ( ) ; } ) ; } ) ; it ( "should not import zones with wrong JSON data" , ( done ) => { const wrongJsonInput = ( "[{\"from\":120,\"to\":140},{\"from\":140,\"to\":150},{\"from\":150,\"to\":160}]" ) . replace ( "," , "" ) ; const saveZonesSpy = spyOn ( zonesService , "saveZones" ) . and . returnValue ( Promise . resolve ( true ) ) ; const zonesUpdatesSpy = spyOn ( zonesService . zonesUpdates , "next" ) ; const promiseImport = zonesService . importZones ( wrongJsonInput ) ; promiseImport . then ( ( ) => { expect ( true ) . toBeFalsy ( "Test should no go there" ) ; done ( ) ; } , ( error ) => { expect ( saveZonesSpy ) . toHaveBeenCalledTimes ( 0 ) ; expect ( zonesUpdatesSpy ) . toHaveBeenCalledTimes ( 0 ) ; expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toBe ( "Provided zones do not respect expected format" ) ; done ( ) ; } ) ; } ) ; it ( "should not import zones with not compliant zones but valid JSON" , ( done ) => { const expectedError = "149" ; const jsonInput = "[{\"from\":120,\"to\":140},{\"from\":140,\"to\":150},{\"from\":" + expectedError + ",\"to\":160}]" ; const zonesUpdatesSpy = spyOn ( zonesService . zonesUpdates , "next" ) ; const promiseImport = zonesService . importZones ( jsonInput ) ; promiseImport . then ( ( ) => { expect ( true ) . toBeFalsy ( "Test should no go there" ) ; done ( ) ; } , ( error ) => { expect ( error ) . not . toBeNull ( ) ; expect ( error ) . toEqual ( "Not compliant zones provided: pattern is not respected." ) ; expect ( zonesUpdatesSpy ) . toHaveBeenCalledTimes ( 0 ) ; done ( ) ; } ) ; } ) ; } ) ;