UNPKG

@feature-hub/core

Version:

Create scalable web applications using micro frontends.

201 lines 10.4 kB
"use strict"; // tslint:disable:no-implicit-dependencies Object.defineProperty(exports, "__esModule", { value: true }); const create_feature_hub_1 = require("../create-feature-hub"); const feature_app_manager_1 = require("../feature-app-manager"); const feature_service_registry_1 = require("../feature-service-registry"); const logger_1 = require("./logger"); describe('createFeatureHub()', () => { let featureHubOptions; beforeEach(() => { featureHubOptions = { logger: logger_1.logger }; }); describe('without any options', () => { it('creates a Feature Hub that contains a Feature App manager', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator'); expect(featureAppManager).toBeInstanceOf(feature_app_manager_1.FeatureAppManager); }); it('creates a Feature Hub that contains a Feature Service registry', () => { const { featureServiceRegistry } = (0, create_feature_hub_1.createFeatureHub)('test:integrator'); expect(featureServiceRegistry).toBeInstanceOf(feature_service_registry_1.FeatureServiceRegistry); }); it('creates a Feature Hub that contains an empty set of Feature Services', () => { const { featureServices } = (0, create_feature_hub_1.createFeatureHub)('test:integrator'); expect(featureServices).toEqual({}); }); }); describe('featureAppManager#getAsyncFeatureAppDefinition', () => { describe('without a module loader', () => { it('throws an error', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator'); expect(() => featureAppManager.getAsyncFeatureAppDefinition('http://example.com/test.js')).toThrow(new Error('No module loader provided.')); }); }); describe('with a module loader', () => { let mockModuleLoader; beforeEach(() => { mockModuleLoader = jest.fn(async () => Promise.resolve()); featureHubOptions = Object.assign(Object.assign({}, featureHubOptions), { moduleLoader: mockModuleLoader }); }); it('uses the module loader to load the Feature App definition', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); const url = 'http://example.com/test.js'; featureAppManager.getAsyncFeatureAppDefinition(url, 'a'); expect(mockModuleLoader).toHaveBeenCalledWith(url, 'a'); }); }); }); describe('featureAppManager#createFeatureAppScope', () => { let mockFeatureApp; let mockFeatureAppCreate; let mockFeatureAppDefinition; beforeEach(() => { mockFeatureApp = {}; mockFeatureAppCreate = jest.fn(() => mockFeatureApp); mockFeatureAppDefinition = { dependencies: { externals: { foo: '^1.0.0' } }, create: mockFeatureAppCreate, }; }); it('creates a Feature App', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); const { featureApp } = featureAppManager.createFeatureAppScope('test:feature-app', mockFeatureAppDefinition); expect(mockFeatureAppCreate).toHaveBeenCalledWith({ featureAppId: 'test:feature-app', featureServices: {}, }); expect(featureApp).toBe(mockFeatureApp); }); describe('with provided externals', () => { beforeEach(() => { featureHubOptions = Object.assign(Object.assign({}, featureHubOptions), { providedExternals: {} }); }); it('throws for a Feature App with mismatching externals', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); expect(() => featureAppManager.createFeatureAppScope('test:feature-app', mockFeatureAppDefinition)).toThrow(new Error('The external dependency "foo" as required by "test:feature-app" is not provided.')); }); }); describe('with an onBind callback', () => { it('calls the onBind callback successfully', () => { const mockOnBind = jest.fn(); const featureAppId = 'testId'; const featureAppName = 'testName'; const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', Object.assign(Object.assign({}, featureHubOptions), { onBind: mockOnBind })); const parentFeatureApp = { featureAppId: 'parentTestId', featureAppName: 'parentTestName', }; featureAppManager.createFeatureAppScope(featureAppId, mockFeatureAppDefinition, { featureAppName, parentFeatureApp }); expect(mockOnBind.mock.calls).toEqual([ [ { featureAppDefinition: mockFeatureAppDefinition, featureAppId, featureAppName, parentFeatureApp, }, ], ]); }); }); }); describe('with Feature Service definitions', () => { let mockFeatureServiceCreate; let mockFeatureServiceV1Binder; let mockFeatureServiceV1; beforeEach(() => { mockFeatureServiceV1 = {}; mockFeatureServiceV1Binder = jest.fn(() => ({ featureService: mockFeatureServiceV1, })); mockFeatureServiceCreate = jest.fn(() => ({ '1.0.0': mockFeatureServiceV1Binder, })); featureHubOptions = Object.assign(Object.assign({}, featureHubOptions), { featureServiceDefinitions: [ { id: 'test:feature-service', dependencies: { externals: { foo: '^1.0.0' } }, create: mockFeatureServiceCreate, }, ] }); }); it('registers and creates the Feature Services', () => { (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); expect(mockFeatureServiceCreate).toHaveBeenCalledWith({ featureServices: {}, }); }); describe('and with provided externals', () => { beforeEach(() => { featureHubOptions = Object.assign(Object.assign({}, featureHubOptions), { providedExternals: {} }); }); it('throws for a Feature Service with mismatching externals', () => { expect(() => (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions)).toThrow(new Error('The external dependency "foo" as required by "test:feature-service" is not provided.')); }); }); describe('and without Feature Service dependencies', () => { it('creates a Feature Hub that contains an empty set of Feature Services', () => { const { featureServices } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); expect(featureServices).toEqual({}); }); }); describe('and with Feature Service dependencies', () => { beforeEach(() => { featureHubOptions = Object.assign(Object.assign({}, featureHubOptions), { featureServiceDependencies: { 'test:feature-service': '^1.0.0' } }); }); it('creates a Feature Hub that contains Feature Services that are bound to the integrator', () => { const { featureServices } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', featureHubOptions); expect(mockFeatureServiceV1Binder.mock.calls).toEqual([ ['test:integrator', undefined], ]); expect(featureServices['test:feature-service']).toBe(mockFeatureServiceV1); }); }); }); describe('logging', () => { let featureAppDefinition; let featureServiceDefinitions; let expectedLogCalls; beforeEach(() => { featureAppDefinition = { create: jest.fn(() => ({})) }; featureServiceDefinitions = [ { id: 'test:feature-service', create: () => ({ '1.0.0': jest.fn() }) }, ]; expectedLogCalls = [ [ 'The Feature Service "test:feature-service" has been successfully registered by registrant "test:integrator".', ], [ 'The Feature App with the ID "test:feature-app" has been successfully created.', ], ]; }); describe('with a custom logger', () => { it('logs messages using the custom logger', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', { featureServiceDefinitions, logger: logger_1.logger, }); featureAppManager.createFeatureAppScope('test:feature-app', featureAppDefinition); expect(logger_1.logger.info.mock.calls).toEqual(expectedLogCalls); }); }); describe('without a custom logger', () => { let consoleInfoSpy; beforeEach(() => { consoleInfoSpy = jest.spyOn(console, 'info'); }); afterEach(() => { consoleInfoSpy.mockRestore(); }); it('logs messages using the console', () => { const { featureAppManager } = (0, create_feature_hub_1.createFeatureHub)('test:integrator', { featureServiceDefinitions, }); featureAppManager.createFeatureAppScope('test:feature-app', featureAppDefinition); expect(consoleInfoSpy.mock.calls).toEqual(expectedLogCalls); }); }); }); }); //# sourceMappingURL=create-feature-hub.test.js.map