periodicjs
Version:
Periodic is a rapid enterprise application framework for data driven web and mobile applications.
456 lines (450 loc) • 15.1 kB
JavaScript
;
/*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 config = require('../../../lib/init/config');
const configSequelizeSchema = require('../../../lib/schemas/config.sequelize');
const testPathDir = path.resolve(__dirname, '../../mock/spec/periodic');
const initTestPathDir = path.join(testPathDir, 'configTest');
const CoreData = require('periodicjs.core.data');
const initTestConfigJsonFile = path.join(initTestPathDir, 'content/config/config.json');
const configTestConfigJson = require('../../mock/config/config_test_config');
let configPeriodic;
chai.use(require('sinon-chai'));
chai.use(require('chai-as-promised'));
require('mocha-sinon');
describe('Periodic Init Config', function() {
this.timeout(10000);
before('initialize config test periodic dir', (done) => {
fs.ensureDir(initTestPathDir)
.then(() => {
return fs.ensureDir(path.join(initTestPathDir, 'content/config'))
})
.then(() => {
return fs.ensureFile(initTestConfigJsonFile)
})
.then(() => {
return fs.outputJson(initTestConfigJsonFile, configTestConfigJson({
dbpathprefix: initTestPathDir,
settingsProp: {
logger: {
use_winston_logger: false,
},
},
}));
})
.then(() => {
// process.env.ENV = 'test';
configPeriodic = new periodicClass({});
configPeriodic.init({
app_root: initTestPathDir,
cli: true,
environment: 'test',
})
.then(done.bind(done, undefined))
.catch(done);
}).catch(done);
});
describe('loadConfiguration', () => {
it('should return a promise', (done) => {
const testConfigPeriodic = Object.assign({}, configPeriodic);
const configLoadPromise = config.loadConfiguration.call(testConfigPeriodic);
expect(configLoadPromise).to.be.a('promise');
expect(configLoadPromise).to.eventually.eql(true);
const testErrorConfigPeriodic = Object.assign({}, configPeriodic);
Object.defineProperty(testErrorConfigPeriodic, 'settings', {
enumerable: false,
configurable: false,
writable: false,
});
const configErrorLoadPromise = config.loadConfiguration.call(testErrorConfigPeriodic);
configErrorLoadPromise
.then((config) => {
// console.log({ config });
done(new Error('was not supposed to succeed'));
})
.catch(configError => {
// console.log({ configError });
expect(configError).to.be.an('error');
done();
});
expect(configErrorLoadPromise).to.eventually.be.rejected;
});
it('should set the config configuration and settings properly', () => {
const configTestJson = configTestConfigJson({
dbpathprefix: initTestPathDir,
settingsProp: {
logger: {
use_winston_logger: false,
},
},
});
expect(configPeriodic.config.configuration).to.eql(configTestJson.configuration);
expect(configPeriodic.settings.name).to.eql(configTestJson.settings.name);
});
it('should handle errors', () => {
expect(config.loadConfiguration()).to.eventually.be.rejected;
});
it('should handle invalid configuration types', (done) => {
Promise.all([
(new Promise((resolve, reject) => {
const invalidConfigurationType = configTestConfigJson({
config_type: 'invalidConfigType',
dbpathprefix: initTestPathDir,
settingsProp: {
logger: {
use_winston_logger: false,
},
},
});
const testInvalidPeriodicConfig = {
config: Object.assign({
app_root: initTestPathDir,
}, invalidConfigurationType)
};
config.loadConfiguration.call(testInvalidPeriodicConfig, invalidConfigurationType.configuration)
.then(() => {
reject(new Error('was not supposed to succeed'));
})
.catch(e => {
expect(e.message).to.eql('invalid configuration type');
resolve(true);
});
})),
new Promise((resolve, reject) => {
const config_configuration_db_invalid = configTestConfigJson({
db: 'invalidDB',
dbpathprefix: initTestPathDir
});
const invalidTestPeriodicDbConfig = {
config: Object.assign({
app_root: initTestPathDir,
}, config_configuration_db_invalid)
};
config.loadConfiguration.call(invalidTestPeriodicDbConfig, config_configuration_db_invalid.configuration)
.then(() => {
reject(new Error('was not supposed to succeed'));
})
.catch(e => {
expect(e.message).to.eql('invalid configuration db');
resolve(true);
});
})
])
.then((result) => {
// console.log({ result });
done();
})
.catch(done);
});
});
describe('configureLowkie', () => {
it('should handle errors', () => {
expect(config.configureLowkie()).to.eventually.be.rejected;
});
});
describe('configureMongoose', () => {
it('should handle errors', () => {
expect(config.configureMongoose()).to.eventually.be.rejected;
});
it('should connect using mongo', (done) => {
const mongoconfig = configTestConfigJson({
db: 'mongoose',
db_config_options: {
"url": "mongodb://localhost:27017/test_config_db",
"connection_options": {}
},
settingsProp: {
logger: {
use_winston_logger: false,
},
},
});
const mongoPeriodicInstance = {
config: Object.assign({
app_root: initTestPathDir,
}, mongoconfig),
core: {
data: CoreData,
},
dbs: new Map(),
datas: new Map(),
};
config.loadConfiguration.call(mongoPeriodicInstance, mongoconfig.configuration)
.then((result) => {
expect(result).to.be.true;
expect(mongoPeriodicInstance.datas.has('configuration')).to.be.true;
expect(mongoPeriodicInstance.dbs.has('configuration')).to.be.true;
done();
})
.catch(done);
});
it('should log disconnect messages using mongo', (done) => {
const spy = sinon.spy();
const mongoconfig = configTestConfigJson({
db: 'mongoose',
db_config_options: {
"url": "mongodb://localhost:27017/test_config_db",
"connection_options": {}
},
settingsProp: {
logger: {
use_winston_logger: false,
},
},
});
const mongoPeriodicInstance = {
config: Object.assign({
app_root: initTestPathDir,
}, mongoconfig),
core: {
data: CoreData,
},
dbs: new Map(),
datas: new Map(),
logger: {
error: spy,
}
};
config.loadConfiguration.call(mongoPeriodicInstance, mongoconfig.configuration)
.then((result) => {
expect(result).to.be.true;
mongoPeriodicInstance.dbs.get('configuration').on('disconnected', () => {
expect(spy.called).to.be.true;
done();
});
mongoPeriodicInstance.dbs.get('configuration').emit('disconnected');
})
.catch(done);
});
/*
it('should close mongo connection after node process ends', (done) => {
const processExitSpy = sinon.spy();
const sillySpy = sinon.spy();
const errorSpy = sinon.spy();
process.exit = sinon.stub(process, 'exit', processExitSpy);
const mongoconfig = configTestConfigJson({
db: 'mongoose',
db_config_options: {
"url": "mongodb://localhost:27017/test_config_db2",
"connection_options":{}
}
});
const mongoPeriodicInstance = {
config: Object.assign({
app_root: initTestPathDir,
}, mongoconfig),
core: {
data: CoreData,
},
dbs: new Map(),
datas: new Map(),
logger: {
silly:sillySpy,
error:errorSpy,
}
};
config.loadConfiguration.call(mongoPeriodicInstance, mongoconfig.configuration)
.then((result) => {
expect(result).to.be.true;
mongoPeriodicInstance.dbs.get('configuration').once('disconnected', () => {
expect(processExitSpy.called).to.be.true;
expect(sillySpy.called).to.be.true;
expect(errorSpy.called).to.be.true;
process.exit.restore();
// done();
});
process.emit('SIGINT');
})
.catch(done);
});*/
});
describe('configureSequelize', () => {
it('should handle errors', () => {
expect(config.configureSequelize()).to.eventually.be.rejected;
});
it('should connect using sql', (done) => {
const sqlconfig = configTestConfigJson({
db: 'sequelize',
db_config_options: {
"database": "travis_ci_test",
"username": "",
"password": "",
"connection_options": {
"dialect": "postgres",
"port": 5432,
"host": "127.0.0.1",
"logging": false
},
},
settingsProp: {
logger: {
use_winston_logger: false,
},
},
});
const sqlPeriodicInstance = {
config: Object.assign({
app_root: initTestPathDir,
}, sqlconfig),
core: {
data: CoreData,
},
dbs: new Map(),
datas: new Map(),
};
config.loadConfiguration.call(sqlPeriodicInstance, sqlconfig.configuration)
.then((result) => {
expect(result).to.be.true;
expect(sqlPeriodicInstance.datas.has('configuration')).to.be.true;
expect(sqlPeriodicInstance.dbs.has('configuration')).to.be.true;
done();
})
.catch(done);
});
});
describe('configuration sql schema json', () => {
it('should store json configurations in sql', () => {
expect(configSequelizeSchema.options.getterMethods.config.call({
dataValues: {
config: '{"data":true}'
}
})).to.eql({ data: true });
});
it('should store json values in sql', () => {
const mockThis = {
// config:false,
setDataValue: function(prop, val) {
this[prop] = val;
}
}
configSequelizeSchema.options.setterMethods.config.call(mockThis, { data: true });
expect(mockThis.config).to.eql(JSON.stringify({ data: true }))
});
});
describe('loadAppSettings', () => {
it('should attempt to load settings from configuration db', (done) => {
const testConfigPeriodic = Object.assign({}, configPeriodic);
// console.log({ testConfigPeriodic });
config.loadAppSettings.call(configPeriodic)
.then((updatedSettings) => {
// console.log({ updatedSettings });
expect(updatedSettings).to.eql(configPeriodic.settings);
done();
})
.catch(done);
});
it('should override settings from config.json', (done) => {
const ORIGINALNAME = 'ORIGINAL NAME';
const testPeriodicInstance = {
config: {
process: {
runtime: 'test',
},
},
settings: {
name: ORIGINALNAME,
},
status: {
emit: () => {}
},
configuration: {
load: () => new Promise((resolve, reject) => {
resolve({
name: 'ENV SPECIFIC NAME',
});
}),
},
};
config.loadAppSettings.call(testPeriodicInstance)
.then((updatedSettings) => {
expect(testPeriodicInstance.settings.name).to.eql(ORIGINALNAME);
done();
})
.catch(done);
});
it('should merge settings from env', (done) => {
const ENVNAME = 'ENV SPECIFIC NAME';
const testPeriodicInstance = {
config: {
process: {
runtime: 'test',
},
},
settings: {
// name:ORIGINALNAME,
},
status: {
emit: () => {}
},
configuration: {
load: () => new Promise((resolve, reject) => {
resolve({
config: {
name: ENVNAME,
}
});
}),
},
};
config.loadAppSettings.call(testPeriodicInstance)
.then((updatedSettings) => {
expect(testPeriodicInstance.settings.name).to.eql(ENVNAME);
done();
})
.catch(done);
});
it('should return a promise', () => {
// const loadSpy = sinon.spy();
const testPeriodicInstance = {
config: {
process: {
runtime: 'test',
},
},
configuration: {
load: () => new Promise((resolve, reject) => { resolve(true) }),
},
status: {
emit: () => {},
},
};
const configLoadAppPromise = config.loadAppSettings.call(testPeriodicInstance);
expect(configLoadAppPromise).to.be.a('promise');
});
it('should handle errors', (done) => {
function foo() { throw new Error('Error On this.configuration.load'); }
const testPeriodicInstance = {
config: {
process: {
runtime: 'test',
},
},
configuration: {
load: () => {},
},
};
const fooSpy = sinon.stub(testPeriodicInstance.configuration, 'load', foo);
config.loadAppSettings.call(testPeriodicInstance)
.then((m) => {
done(new Error('was not supposed to succeed'));
})
.catch((m) => {
expect(fooSpy.threw()).to.be.ok;
done();
});
});
});
after('remove config test periodic dir', (done) => {
fs.remove(initTestPathDir)
.then(() => {
done();
}).catch(done);
});
});