import {DateTime} from 'luxon'; import {Clock} from 'src/lib/clock'; import * as TimeService from 'src/services/time'; describe('src/services/time', () => { describe('TimeService', () => { let fakeClock = null; beforeEach(() => { fakeClock = jasmine.createSpyObj('FakeClock', [ 'addEventListener', 'removeEventListener', ]); fakeClock.now = DateTime.local(); spyOn(Clock, 'instance').and.returnValue(fakeClock); }); describe('emptyCharacteristics', () => { it('returns empty characteristics', () => { // Given const result = TimeService.TimeService.emptyCharacteristics(); // Then expect(result).toEqual({ locale: '', timeFormat: '', dateFormat: 'DATE_HUGE', }); }); }); describe('payloadFromDateTime', () => { let now = null; beforeEach(() => { now = DateTime.local(1985, 10, 3, 8, 0, 0); spyOn(now, 'setLocale').and.callFake(() => { return now; }); spyOn(now, 'toFormat').and.returnValue('Formatted Time String'); spyOn(now, 'toLocaleString'); now.toLocaleString.withArgs(DateTime.TIME_SIMPLE).and.returnValue( 'Simple Time String' ); now.toLocaleString.withArgs(DateTime.DATE_HUGE).and.returnValue( 'Huge Date String' ); now.toLocaleString.withArgs(DateTime.DATE_FULL).and.returnValue( 'Full Date String' ); }); it('sets locale if it is specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); characteristics.locale = 'en-us'; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When service.payloadFromDateTime(now); // Then expect(now.setLocale).toHaveBeenCalledWith('en-us'); }); it('does not set locale if it is not specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When service.payloadFromDateTime(now); // Then expect(now.setLocale).not.toHaveBeenCalled(); }); it('uses timeFormat to format the time string if it is specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); characteristics.timeFormat = 'hh:mm a'; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When const result = service.payloadFromDateTime(now); // Then expect(result.data.time).toEqual('Formatted Time String'); expect(now.toFormat).toHaveBeenCalledWith('hh:mm a'); expect(now.toLocaleString).not.toHaveBeenCalledWith( DateTime.TIME_SIMPLE ); }); it('uses default time format to format the time string if timeFormat is not specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When const result = service.payloadFromDateTime(now); // Then expect(result.data.time).toEqual('Simple Time String'); expect(now.toFormat).not.toHaveBeenCalled(); expect(now.toLocaleString).toHaveBeenCalledWith(DateTime.TIME_SIMPLE); }); it('uses default date format to format the date string if dateFormat is not specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); characteristics.dateFormat = ''; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When const result = service.payloadFromDateTime(now); // Then expect(result.data.date).toEqual('Huge Date String'); expect(now.toLocaleString).toHaveBeenCalledWith(DateTime.DATE_HUGE); }); it('uses dateFormat to format the date string if it is specified', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); characteristics.dateFormat = 'DATE_FULL'; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When const result = service.payloadFromDateTime(now); // Then expect(result.data.date).toEqual('Full Date String'); expect(now.toLocaleString).toHaveBeenCalledWith(DateTime.DATE_FULL); }); }); describe('onClockTick', () => { it('notfies subscribers with payload', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const fakePayload = { data: { date: '1987-10-03', time: '08:00 AM', }, }; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); spyOn(service, 'payloadFromDateTime').and.returnValue(fakePayload); spyOn(service, 'notify'); // When service.onClockTick(fakeClock); // Then expect(service.notify).toHaveBeenCalledWith(fakePayload); expect(service.payloadFromDateTime).toHaveBeenCalledWith( fakeClock.now ); }); }); describe('initialState', () => { it('returns payload from the current timestamp', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const fakePayload = { data: { date: '1987-10-03', time: '08:00 AM', }, }; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); spyOn(service, 'payloadFromDateTime').and.returnValue(fakePayload); // When const result = service.initialState(); // Then expect(result).toEqual(fakePayload); expect(service.payloadFromDateTime).toHaveBeenCalledWith( fakeClock.now ); }); }); describe('setCharacteristics', () => { it('triggers the onClockTick to update', () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const newCharacteristics = { ...characteristics, locale: 'en-us', }; const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); spyOn(service, 'onClockTick'); // When service.setCharacteristics(newCharacteristics); // Then expect(service.characteristics).toEqual(newCharacteristics); expect(service.onClockTick).toHaveBeenCalledWith(fakeClock); }); }); describe('start', () => { it('adds event listener for the clock tick event', async () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When await service.start(); // Then expect(fakeClock.addEventListener).toHaveBeenCalledWith( 'tick', service.onClockTick ); }); }); describe('start', () => { it('removes event listener for the clock tick event', async () => { // Given const characteristics = TimeService.TimeService.emptyCharacteristics(); const service = new TimeService.TimeService({ instance: 'testing', characteristics: characteristics, }); // When await service.stop(); // Then expect(fakeClock.removeEventListener).toHaveBeenCalledWith( 'tick', service.onClockTick ); }); }); }); });