import * as ServicesLib from 'src/lib/services'; import {DashboardsFactory} from 'tests/__fixtures__/dashboards'; import {FakeService, FakeWidget} from 'tests/__fixtures__/services'; describe('src/lib/services', () => { describe('ServiceState', () => { describe('constructor', () => { it('initializes the instance with a payload', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, error: { message: 'FIAL', }, }); // Then expect(serviceState.payload.data).toEqual({spam: true}); expect(serviceState.payload.error).toEqual({message: 'FIAL'}); }); it('initializes the instance with the default payload', () => { // Given const serviceState = new ServicesLib.ServiceState(); // Then expect(serviceState.payload.data).toBe(null); expect(serviceState.payload.error).toBe(null); }); }); describe('isLoading', () => { it('returns true if both data and error fields are null', () => { // Given const serviceState = new ServicesLib.ServiceState(); // Then expect(serviceState.isLoading()).toBe(true); }); it('returns false if data is null and error is not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ error: { message: 'FIAL', }, }); // Then expect(serviceState.isLoading()).toBe(false); }); it('returns false if data is not null and error is null', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, }); // Then expect(serviceState.isLoading()).toBe(false); }); it('returns false if both data and error fields are not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, error: { message: 'FIAL', }, }); // Then expect(serviceState.isLoading()).toBe(false); }); }); describe('hasData', () => { it('returns false if isLoading is true and data is not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, }); spyOn(serviceState, 'isLoading').and.returnValue(true); // Then expect(serviceState.hasData()).toBe(false); }); it('returns false if isLoading is false and data is null', () => { // Given const serviceState = new ServicesLib.ServiceState(); spyOn(serviceState, 'isLoading').and.returnValue(true); // Then expect(serviceState.hasData()).toBe(false); }); it('returns true if isLoading is false and data is not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, }); spyOn(serviceState, 'isLoading').and.returnValue(false); // Then expect(serviceState.hasData()).toBe(true); }); }); describe('hasError', () => { it('returns false if isLoading is true and error is not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ error: { message: 'FIAL', }, }); spyOn(serviceState, 'isLoading').and.returnValue(true); // Then expect(serviceState.hasError()).toBe(false); }); it('returns false if isLoading is false and error is null', () => { // Given const serviceState = new ServicesLib.ServiceState(); spyOn(serviceState, 'isLoading').and.returnValue(true); // Then expect(serviceState.hasError()).toBe(false); }); it('returns true if isLoading is false and error is not null', () => { // Given const serviceState = new ServicesLib.ServiceState({ error: { message: 'FIAL', }, }); spyOn(serviceState, 'isLoading').and.returnValue(false); // Then expect(serviceState.hasError()).toBe(true); }); }); describe('hasFatalError', () => { it('returns true if hasData is false and hasError is true', () => { // Given const serviceState = new ServicesLib.ServiceState(); spyOn(serviceState, 'hasData').and.returnValue(false); spyOn(serviceState, 'hasError').and.returnValue(true); // Then expect(serviceState.hasFatalError()).toBe(true); }); it('returns false if hasData is true and hasError is true', () => { // Given const serviceState = new ServicesLib.ServiceState(); spyOn(serviceState, 'hasData').and.returnValue(true); spyOn(serviceState, 'hasError').and.returnValue(true); // Then expect(serviceState.hasFatalError()).toBe(false); }); it('returns false if hasData is true and hasError is false', () => { // Given const serviceState = new ServicesLib.ServiceState(); spyOn(serviceState, 'hasData').and.returnValue(true); spyOn(serviceState, 'hasError').and.returnValue(false); // Then expect(serviceState.hasFatalError()).toBe(false); }); }); describe('update', () => { it('returns a new ServiceState with updated payload', () => { // Given const serviceState = new ServicesLib.ServiceState(); // When const result = serviceState.update({ data: { spam: true, }, error: { message: 'FIAL', }, }); // Then expect(result).not.toBe(serviceState); expect(result.payload.data).toEqual({spam: true}); expect(result.payload.error).toEqual({message: 'FIAL'}); expect(serviceState.payload).toEqual({ data: null, error: null, }); }); }); describe('data', () => { it('returns the data payload field', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, error: { message: 'FIAL', }, }); // Then expect(serviceState.data()).toEqual(serviceState.payload.data); }); }); describe('error', () => { it('returns the error payload field', () => { // Given const serviceState = new ServicesLib.ServiceState({ data: { spam: true, }, error: { message: 'FIAL', }, }); // Then expect(serviceState.error()).toEqual(serviceState.payload.error); }); }); }); describe('BaseService', () => { let spec = null; beforeEach(() => { spec = { instance: 'fake_instance', characteristics: { spam: true, }, widgetComponent: FakeWidget, layout: { x: 0, y: 0, w: 1, h: 1, }, }; }); it('includes the subscribable mixin', () => { // Given const service = new FakeService(spec); // Then expect(service.__mixins__).toContain('SubscribableMixin'); }); describe('emptyCharacteristics', () => { it('returns the empty characteristics', () => { // Given const result = FakeService.emptyCharacteristics(); // Then expect(result).toEqual({}); }); }); describe('constructor', () => { it('initializes the instance', () => { // Given const service = new FakeService(spec); // Then expect(service.kind).toEqual(FakeService.kind); expect(service.instance).toEqual(spec.instance); expect(service.characteristics).toEqual(spec.characteristics); expect(service.widget).toEqual(FakeService.widget); expect(service.widgetComponent).toEqual(spec.widgetComponent); expect(service.layout).toEqual(spec.layout); }); }); describe('restart', () => { it('restarts the service', async () => { // Given const service = new FakeService(spec); spyOn(service, 'notify'); spyOn(service, 'start').and.resolveTo(null); spyOn(service, 'stop').and.resolveTo(null); // When await service.restart(); // Then expect(service.notify).toHaveBeenCalledWith(null, {reset: true}); expect(service.stop).toHaveBeenCalledBefore(service.start); expect(service.start).toHaveBeenCalled(); }); }); describe('isDummy', () => { it('returns false', () => { // Given const service = new FakeService(spec); // Then expect(service.isDummy()).toBe(false); }); }); describe('initialState', () => { it('returns null', () => { // Given const service = new FakeService(spec); // Then expect(service.initialState()).toBe(null); }); }); describe('setCharacteristics', () => { it('sets the new characteristics', () => { // Given const service = new FakeService(spec); const newCharacteristics = {spam: false}; // When service.setCharacteristics(newCharacteristics); // Then expect(service.characteristics).not.toBe(newCharacteristics); expect(service.characteristics).toEqual(newCharacteristics); }); }); describe('setLayout', () => { it('sets the new layout', () => { // Given const service = new FakeService(spec); const newLayout = {x: 1, y: 1, w: 2, h: 2}; // When service.setLayout(newLayout); // Then expect(service.layout).not.toBe(newLayout); expect(service.layout).toEqual(newLayout); }); }); describe('toJSON', () => { it('returns a JSON-serializable representation of the service', () => { // Given const service = new FakeService(spec); // When const result = service.toJSON(); // Then expect(result).toEqual({ kind: service.kind, instance: service.instance, characteristics: service.characteristics, layout: service.layout, }); }); }); }); describe('DummyService', () => { let spec = null; beforeEach(() => { spec = { instance: 'fake_instance', characteristics: { spam: true, }, widgetComponent: FakeWidget, layout: { x: 0, y: 0, w: 1, h: 1, }, }; }); describe('constructor', () => { it('initializes the instance', () => { // Given const service = new ServicesLib.DummyService(spec); // Then expect(service.instance).toBe(null); expect(service.widgetComponent).toBe(null); }); }); describe('isDummy', () => { it('returns true', () => { // Given const service = new ServicesLib.DummyService(spec); // Then expect(service.isDummy()).toBe(true); }); }); }); describe('lookupService', () => { let dashboards = null; beforeEach(() => { dashboards = DashboardsFactory(); }); it('returns DummyService instance if the specified kind does not exist', () => { // Given const result = ServicesLib.lookupService( dashboards, 'Testing', 'fake_instance' ); // Then expect(result).toBeInstanceOf(ServicesLib.DummyService); expect(result.isDummy()).toBe(true); }); it('returns DummyService instance if the specified instance does not exist', () => { // Given const result = ServicesLib.lookupService( dashboards, 'FakeService', 'testing' ); // Then expect(result).toBeInstanceOf(ServicesLib.DummyService); expect(result.isDummy()).toBe(true); }); it('returns the service that matches the specified kind and instace', () => { // Given const result = ServicesLib.lookupService( dashboards, 'FakeService', 'fake_instance' ); // Then expect(result).toBe(dashboards[0].services[0]); }); }); describe('lookupServices', () => { let dashboards = null; beforeEach(() => { dashboards = DashboardsFactory(); dashboards[0].services.push(new ServicesLib.DummyService()); dashboards[0].services.push(new FakeService({ instance: 'fake_instance2', })); }); it('returns all instances of services specified by kind', () => { // Givem const result = ServicesLib.lookupServices(dashboards, 'FakeService'); // Then expect(result.length).toEqual(3); expect(result[0]).toBe(dashboards[0].services[0]); expect(result[1]).toBe(dashboards[0].services[1]); expect(result[2]).toBe(dashboards[0].services[3]); }); }); });