UNPKG

periodicjs

Version:

Periodic is a rapid enterprise application framework for data driven web and mobile applications.

539 lines (517 loc) 20.8 kB
'use strict'; /*jshint expr: true*/ const path = require('path'); const events = require('events'); const chai = require('chai'); const sinon = require('sinon'); const fs = require('fs-extra'); const expect = require('chai').expect; const periodic = require('../../../index'); const periodicClass = require('../../../lib/periodicClass'); const setup = require('../../../lib/extension/setup'); chai.use(require('sinon-chai')); chai.use(require('chai-as-promised')); const testPathDir = path.resolve(__dirname, '../../mock/spec/periodic'); const setupDir = path.join(testPathDir, 'ExtSetup'); const containerConfigDir = path.join(setupDir, '/my-example-app/content/container/sample-container/config'); const emptyContainerDir = path.join(setupDir, '/my-example-app/content/container/empty-container'); const sampleExtensionDir = path.join(setupDir, '/my-example-app/node_modules/sample-extension'); const extensionStandardModelDir = path.join(sampleExtensionDir, '/config/databases/standard/models'); const sampleContainerDir = path.join(setupDir, '/my-example-app/content/container/sample-container'); const sampleContainerRouterDir = path.join(sampleContainerDir, '/routers'); const sampleContainerControllerDir = path.join(sampleContainerDir, '/controllers'); const sampleContainerUtilityDir = path.join(sampleContainerDir, '/utilities'); const sampleContainerCommandDir = path.join(sampleContainerDir, '/commands'); const sampleContainerTransformDir = path.join(sampleContainerDir, '/transforms'); const sampleModelFile = path.join(extensionStandardModelDir, '/sample_model.js'); const containerConfigurationFile = path.join(containerConfigDir, '/settings.js'); const extensionConfigurationFile = path.join(sampleExtensionDir, '/config/settings.js'); const containerRuntimeConfigFile = path.join(sampleContainerDir, '/test_runtime.json'); const extensionRuntimeConfigFile = path.join(setupDir, '/my-example-app/content/extension/sample-extension/test_runtime.json'); const containerExtensionModuleFile = path.join(sampleContainerDir, '/index.js'); const emptyContainerExtensionModuleFile = path.join(emptyContainerDir, '/index.js'); const containerRouterFile = path.join(sampleContainerRouterDir, '/index.js'); const containerControllerFile = path.join(sampleContainerControllerDir, '/index.js'); const containerUtilityFile = path.join(sampleContainerUtilityDir, '/index.js'); const containerCommandFile = path.join(sampleContainerCommandDir, '/index.js'); const containerTransformFile = path.join(sampleContainerTransformDir, '/index.js'); describe('Periodic Extension setup', function() { this.timeout(10000); before('initialize test periodic dir', (done) => { Promise.all([ fs.ensureDir(sampleExtensionDir), fs.ensureDir(extensionStandardModelDir), fs.ensureDir(containerConfigDir), fs.ensureDir(emptyContainerDir), fs.ensureDir(sampleContainerRouterDir), fs.ensureDir(sampleContainerControllerDir), fs.ensureDir(sampleContainerUtilityDir), fs.ensureDir(sampleContainerCommandDir), fs.ensureDir(sampleContainerTransformDir), ]) .then((result) => { return Promise.all([ fs.outputFile(sampleModelFile, '', function(jsFileCreated) { return true; }), fs.outputFile(containerConfigurationFile, 'module.exports = {test: true}', function(jsFileCreated) { return true; }), fs.outputFile(containerRuntimeConfigFile, 'module.exports = {test: true}', function(jsFileCreated) { return true; }), fs.outputFile(extensionConfigurationFile, 'module.exports = {test: true}', function(jsFileCreated) { return true; }), fs.outputFile(extensionRuntimeConfigFile, 'module.exports = {test: true}', function(jsFileCreated) { return true; }), fs.outputFile(containerExtensionModuleFile, 'module.exports = function(){return true}', function(fileCreated) { return true; }), fs.outputFile(containerRouterFile, 'module.exports = {}', function(fileCreated) { return true; }), fs.outputFile(containerControllerFile, 'module.exports = {}', function(fileCreated) { return true; }), fs.outputFile(containerUtilityFile, 'module.exports = {}', function(fileCreated) { return true; }), fs.outputFile(containerCommandFile, 'module.exports = {}', function(fileCreated) { return true; }), fs.outputFile(containerTransformFile, 'module.exports = { pre:{"DELETE":function(req, res, next){next()}}, post: {"GET":function(req, res, next){next()}}}', function(fileCreated) { return true; }), fs.outputFile(emptyContainerExtensionModuleFile, 'module.exports = function(){return true}', function(fileCreated) { return true; }), ]); }) .then((created) => { done(); }).catch(done); }); describe('getModelFilesMap', () => { it('should return fullpath of the model file', () => { expect(setup.getModelFilesMap('/dirname', '/path/to/file')).to.eql('/dirname/path/to/file/___FULLPATH___'); }); }); describe('loadExtensionFiles -- has models', () => { it('should load extension files', (done) => { const mockThis = { resources: {  standard_models: [], }, config: { app_root: path.join(setupDir, '/my-example-app'), }, }; const mockOptions = { extension: { name: 'sample-extension', }, container: {}, };       setup.loadExtensionFiles.call(mockThis, mockOptions) .then((hasLoadedExtensions) => { expect(hasLoadedExtensions).to.be.true; done(); }) .catch(e => { done(); }); }); }); describe('loadExtensionFiles -- doesnt have models', () => { it('should return a message if files dont exist', (done) => { const mockThis = { resources: {  standard_models: [], }, config: { app_root: path.join(setupDir, '/app-does-not-exist'), }, configuration: { load: (options) => { return new Promise((resolve, reject) => { done(); resolve(true); }) } } }; const mockOptions = { extension: { name: 'sample-extension', }, container: {}, }       setup.loadExtensionFiles.call(mockThis, mockOptions) .then((loadedExtensions) => { expect(loadedExtensions).to.equal('does not have standard models') done(); }) .catch(e => { done(); }); }); }); describe('loadExtensionSettings', () => { it('should set default settings for container', (done) => { const mockThis = { settings: { container: { 'sample-container': { databases: { 'sample_db': {} } } }, }, resources: { standard_models: [], databases: { container: {} } }, config: { app_root: path.join(setupDir, '/my-example-app'), process: { runtime: 'test_runtime', } }, configuration: { load: (options) => { return new Promise((resolve, reject) => { done(); resolve({ db_based_configs: true }); }) } } } const mockOptions = { container: { name: 'sample-container', type: 'local', }, }; setup.loadExtensionSettings.call(mockThis, mockOptions) .then(resolvedSettings => { expect(resolvedSettings).to.be.true; }) .catch(done); }); it('should set default settings for extensions', (done) => { const mockThis = { settings: { extensions: {}, }, resources: { standard_models: [], databases: { extensions: {} } }, config: { app_root: path.join(setupDir, '/my-example-app'), process: { runtime: 'test_runtime', } }, configuration: { load: (options) => { return new Promise((resolve, reject) => { done(); resolve({ db_based_configs: true }); }) } } } const mockOptions = { extension: { name: sampleExtensionDir, type: 'local', }, }; setup.loadExtensionSettings.call(mockThis, mockOptions) .then(resolvedSettings => { expect(resolvedSettings).to.be.true; }) .catch(done); }); it('should fail when default settings is missing', (done) => { const warnSpy = sinon.spy(); const mockThis = { settings: {}, resources: {}, config: { app_root: path.join(setupDir, '/my-example-app'), debug: true, }, configuration: { process: { runtime: 'test_runtime', }, }, logger: { warn: warnSpy, }, routers: new Map(), } const mockOptions = { container: { name: 'sample-container' } }; try { setup.loadExtensionSettings.call(mockThis, mockOptions) .then(resolvedSettings => { return; }) } catch (e) { expect(warnSpy.called).to.be.true; done(); } }); }); describe('getExtensionFromMap', () => { it('should return objectified extension', () => { expect(setup.getExtensionFromMap('sample-extension')).to.deep.eql({ extension: 'sample-extension' }); }); }); describe('assignExtensionResources', () => { it('should load resources for container', (done) => { const warnSpy = sinon.spy(); const mockThis = { resources: {  standard_models: [], commands: { container: new Map(), } }, logger: { warn: warnSpy, }, transforms: { pre: { }, post: { } }, config: { app_root: path.join(setupDir, '/my-example-app'), }, routers: new Map(), controller: { container: new Map(), }, locals: { container: new Map(), } }; const mockOptions = { container: { name: 'sample-container', type: 'local', }, };       setup.assignExtensionResources.call(mockThis, mockOptions) .then((assignedResources) => { //extensionModule file must export a function expect(assignedResources).to.be.true; expect(warnSpy.called).to.be.false; expect(warnSpy.callCount).to.eql(0); done(); }) .catch(e => { console.log({ e }); done(); }); }); it('should log warnings if files don\'t exist', (done) => { const warnSpy = sinon.spy(); const mockThis = { resources: {  standard_models: [], commands: { container: new Map(), } }, logger: { warn: warnSpy, }, transforms: { pre: { }, post: { } }, config: { app_root: path.join(setupDir, '/my-example-app'), debug: true, }, routers: new Map(), controller: { container: new Map(), }, locals: { container: new Map(), } }; const mockOptions = { container: { name: 'empty-container', type: 'local', }, };       setup.assignExtensionResources.call(mockThis, mockOptions) .then((assignedResources) => { //extensionModule file must export a function expect(assignedResources).to.be.true; expect(warnSpy.called).to.be.true; expect(warnSpy.callCount).to.eql(4); done(); }) .catch(e => { console.log({ e }); done(); }); }); }); // describe('setupExtensions', () => { // it('should load resources for extension', (done) => { // const warnSpy = sinon.spy(); // const mockThis = { // extensions: new Map(), // config: { // process: {}, // }, // settings: { // extensions: { // 'sample-extension': { // databases: { // 'sample_db': {} // } // } // }, // }, // resources: { // standard_models: [], // databases: { // extensions: {} // } // }, // configuration: { // load: (options) => { // return new Promise((resolve, reject) => { // done(); // resolve(true); // }) // } // } // }; // mockThis.extensions.set('sample-extension', { // name: 'sample-extension', // resources: {  // standard_models: [], // commands: { // extensions: new Map(), // } // }, // logger: { // warn: warnSpy, // }, // transforms: { // pre: { // }, // post: { // } // }, // config: { // app_root: path.join(setupDir, '/my-example-app'), // }, // routers: new Map(), // controller: { // extensions: new Map(), // }, // locals: { // extensions: new Map(), // } // });      // setup.setupExtensions.call(mockThis) // .then((setupExtensions) => { // //extensionModule file must export a function // console.log({ setupExtensions }) // expect(setupExtensions).to.be.true; // done(); // }) // .catch(e => { // console.log({ e }); // done(); // }); // }); // }); describe('setupContainer', () => { it('should setup container', (done) => { const warnSpy = sinon.spy(); const mockThis = { config: { process: {}, app_root: path.join(setupDir, '/my-example-app') }, resources: {  standard_models: [], commands: { container: new Map(), } }, databases: { 'sample_db': {} }, settings: { container: { name: 'sample-container', type: 'local', logger: { warn: warnSpy, }, transforms: { pre: { }, post: { } }, config: { app_root: path.join(setupDir, '/my-example-app'), }, routers: new Map(), controller: { container: new Map(), }, locals: { container: new Map(), } }, }, resources: { standard_models: [], databases: { container: {} } }, configuration: { load: (options) => { return new Promise((resolve, reject) => { resolve(true); }) } } };     setup.setupContainer.call(mockThis) .then((setupContainer) => { expect(setupContainer).to.equal('does not have standard models'); done(); }) .catch(e => { console.log({ e }); done(); }); }); }); after('remove test periodic dir', (done) => { Promise.all([ fs.remove(setupDir), ]) .then(() => { done(); }).catch(done); }); });