periodicjs
Version:
Periodic is a rapid enterprise application framework for data driven web and mobile applications.
841 lines (840 loc) • 23.9 kB
JavaScript
'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 express = require('../../../lib/init/express');
const testPathDir = path.resolve(__dirname, '../../mock/spec/periodic');
const folderStructure = require('../../../lib/init/folderStructure');
const initTestExpressPathDir = path.join(testPathDir, 'TestExpress');
const initTestExpressEndPathDir = path.join(testPathDir, 'TestExpressEnd');
const __STRUCTURE_DIR = path.resolve(__dirname, '../../../__STRUCTURE');
chai.use(require('sinon-chai'));
chai.use(require('chai-as-promised'));
describe('Periodic Init Express', function() {
this.timeout(10000);
before('initialize Express test periodic dir', (done) => {
Promise.all([
fs.ensureDir(initTestExpressPathDir),
fs.ensureDir(initTestExpressEndPathDir),
fs.copy(__STRUCTURE_DIR, initTestExpressPathDir)
])
.then(() => {
done();
}).catch(done);
});
describe('configureViews', () => {
it('should handle errors', () => {
expect(express.configureViews()).to.eventually.be.rejected;
});
it('sets express non ejs view with proxy options', (done) => {
const setSpy = sinon.spy();
const enableSpy = sinon.spy();
const engineSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
trust_proxy: true,
},
views: {
engine: 'jsx',
lru_cache: true,
lru: 100,
package: 'ejs',
}
}
},
app: {
set: setSpy,
enable: enableSpy,
engine: engineSpy,
// set: setSpy,
},
};
express.configureViews.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(setSpy.calledTwice).to.be.true;
expect(enableSpy.calledOnce).to.be.true;
expect(engineSpy.calledThrice).to.be.true;
// expect(mockThis.config.time_end).to.be.a('number');
done();
})
.catch(done);
});
it('sets express ejs view without proxy options', (done) => {
const setSpy = sinon.spy();
const enableSpy = sinon.spy();
const engineSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
trust_proxy: false,
},
views: {
// engine: 'ejs',
lru_cache: false,
lru: 100,
package: 'ejs',
}
}
},
app: {
set: setSpy,
enable: enableSpy,
engine: engineSpy,
// set: setSpy,
},
};
express.configureViews.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(setSpy.calledTwice).to.be.true;
expect(enableSpy.called).to.not.be.true;
expect(engineSpy.calledThrice).to.be.true;
// expect(mockThis.config.time_end).to.be.a('number');
done();
})
.catch(done);
});
});
describe('configureExpress', () => {
it('has configurable flash settings', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
use_flash: false,
config: {
trust_proxy: false,
},
body_parser: {
urlencoded: {
limit: '1mb',
extended: true,
},
json: {
limit: '1mb'
},
},
cookies: {
cookie_parser: 'defaultcookiejson',
},
views: {
// engine: 'ejs',
lru_cache: false,
lru: 100,
package: 'ejs',
}
}
},
app: {
use: useSpy,
},
};
express.configureExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
// expect(enableSpy.called).to.not.be.true;
// expect(engineSpy.calledThrice).to.be.true;
// expect(mockThis.config.time_end).to.be.a('number');
done();
})
.catch(done);
});
it('should handle errors', () => {
expect(express.configureExpress()).to.eventually.be.rejected;
});
});
describe('customizeExpress', () => {
it('should handle errors', () => {
expect(express.customizeExpress()).to.eventually.be.rejected;
});
});
describe('staticCacheExpress', () => {
it('has configurable static caching', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
use_static_caching: false,
},
body_parser: {
urlencoded: {
limit: '1mb',
extended: true,
},
json: {
limit: '1mb'
},
},
},
},
app: {
use: useSpy,
},
};
express.staticCacheExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('can use disabled static caching settings', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
use_static_caching: true,
},
body_parser: {
urlencoded: {
limit: '1mb',
extended: true,
},
json: {
limit: '1mb'
},
},
},
},
app: {
use: useSpy,
},
};
express.staticCacheExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should handle errors', () => {
expect(express.staticCacheExpress()).to.eventually.be.rejected;
});
});
describe('compressExpress', () => {
it('should handle errors', () => {
expect(express.compressExpress()).to.eventually.be.rejected;
});
it('should use express compression', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
use_compression: true,
},
},
},
app: {
use: useSpy,
},
};
express.compressExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should not use express compression', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
use_compression: false,
},
}
},
app: {
use: useSpy,
},
};
express.compressExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.not.be.true;
done();
})
.catch(done);
});
});
describe('logExpress', () => {
it('should handle errors', () => {
expect(express.logExpress()).to.eventually.be.rejected;
});
it('should generate the right colored response', () => {
function getColoredResponse(options) {
const { color, status } = options;
return '\x1b[' + color + 'm' + status + '\x1b[90m';
}
expect(express.morganColors({}, { statusCode: 501 })).to.eql(getColoredResponse({ color: 31, status: 501 }));
expect(express.morganColors({}, { statusCode: 401 })).to.eql(getColoredResponse({ color: 33, status: 401 }));
expect(express.morganColors({}, { statusCode: 301 })).to.eql(getColoredResponse({ color: 36, status: 301 }));
expect(express.morganColors({}, { statusCode: 200 })).to.eql(getColoredResponse({ color: 32, status: 200 }));
});
it('should use express debugging', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
debug: true,
},
},
},
app: {
use: useSpy,
},
};
express.logExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should not use express debugging', (done) => {
const useSpy = sinon.spy();
const mockThis = {
config: {
app_root: initTestExpressPathDir,
},
settings: {
express: {
config: {
debug: false,
},
}
},
app: {
use: useSpy,
},
};
express.logExpress.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.not.be.true;
done();
})
.catch(done);
});
});
describe('expressSessions', () => {
it('should handle errors', () => {
expect(express.expressSessions()).to.eventually.be.rejected;
});
it('should skip sessions', () => {
expect(express.skipSessions({
req: {
headers: {
authorization: true,
},
}
})).to.be.true;
expect(express.skipSessions({
req: {
headers: {},
query: {
skip_session: true,
},
}
})).to.be.true;
expect(express.skipSessions({
req: {
headers: {},
controllerData: {
skip_session: true,
},
}
})).to.be.true;
expect(express.skipSessions({
req: {
headers: {},
query: {},
controllerData: {},
}
})).to.be.false;
});
it('should skip session middleware', (done) => {
const mockThis = {
config: {},
settings: {
express: {
sessions: {
enabled: false,
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
expect(result).to.be.true;
done();
})
.catch(done);
});
it('should only support specific session stores', (done) => {
const mockThis = {
config: {},
settings: {
express: {
sessions: {
enabled: true,
config: {
secret: 'testsessions',
},
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
done(new Error('Should be actually rejected'));
})
.catch(e => {
expect(e.message).to.eql('Invalid express session type');
done();
});
});
it('should pass enabledSessionMiddleware', () => {
const mockAuthReq = {
headers: {
authorization: true,
},
};
const mockSessionReq = {
headers: {},
query: {},
controllerData: {},
};
const mockRes = {};
const sessionMiddlewareSpy = sinon.spy();
const nextSpy = sinon.spy();
express.enabledSessionMiddleware(sessionMiddlewareSpy, mockAuthReq, mockRes, nextSpy);
expect(nextSpy.called).to.be.false;
express.enabledSessionMiddleware(sessionMiddlewareSpy, mockSessionReq, mockRes, nextSpy);
expect(sessionMiddlewareSpy.called).to.be.false;
});
it('should support loki session stores', (done) => {
const useSpy = sinon.spy();
const mockThis = {
app: {
use: useSpy,
},
config: {},
settings: {
express: {
sessions: {
enabled: true,
type: 'loki',
config: {
secret: 'sessiontest',
},
},
config: {
csrf: true,
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should support mongo session stores', (done) => {
const useSpy = sinon.spy();
const mockThis = {
app: {
use: useSpy,
},
config: {},
settings: {
express: {
sessions: {
enabled: true,
type: 'mongo',
config: {
secret: 'sessiontest',
},
store_settings: {
url: 'mongodb://localhost:27017/session_db',
},
},
config: {
csrf: true,
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should support sql session stores', (done) => {
const useSpy = sinon.spy();
const mockThis = {
app: {
use: useSpy,
},
config: {},
settings: {
express: {
sessions: {
enabled: true,
type: 'sql',
config: {
secret: 'sessiontest',
},
store_settings: {
db: [
"travis_ci_test", //database
"", //username
"", //password
{
"dialect": "postgres",
"port": 5432,
"host": "127.0.0.1",
logging: false,
}, //options
],
options: {},
modelName: 'session',
},
},
config: {
csrf: true,
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should support redis session stores', (done) => {
const useSpy = sinon.spy();
const mockThis = {
app: {
use: useSpy,
},
config: {},
settings: {
express: {
sessions: {
enabled: true,
type: 'redis',
config: {
secret: 'sessiontest',
},
store_settings: {
// client An existing client
host: 'localhost',
port: 6379,
},
},
config: {
csrf: true,
},
},
},
};
express.expressSessions.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(useSpy.called).to.be.true;
done();
})
.catch(done);
});
});
describe('expressLocals', () => {
it('should handle errors', () => {
expect(express.expressLocals()).to.eventually.be.rejected;
});
it('useCSRFMiddleware handle CRSF', () => {
const csrfSpy = sinon.spy();
const mockReq = {
csrfToken: csrfSpy,
};
const mockRes = {
locals: {},
};
const nextSpy = sinon.spy();
const mockCSRFThis = {
settings: {
express: {
config: {
csrf: true,
},
},
},
};
const mockNoCSRFThis = {
settings: {
express: {
config: {
csrf: false,
},
},
},
};
express.useCSRFMiddleware.call(mockCSRFThis, mockReq, mockRes, nextSpy);
expect(csrfSpy.called).to.be.true;
express.useCSRFMiddleware.call(mockNoCSRFThis, mockReq, mockRes, nextSpy);
expect(nextSpy.called).to.be.true;
});
it('useLocalsMiddleware handle CRSF', () => {
const mockReq = {
headers: {},
connection: {},
user: {
id: 1,
},
};
const mockRes = {
locals: {},
};
const nextSpy = sinon.spy();
const mockThis = {
app: {
locals: {},
},
};
express.useLocalsMiddleware.call(mockThis, mockReq, mockRes, nextSpy);
expect(nextSpy.called).to.be.true;
// expect(mockThis.app.locals.isLoggedIn({})).to.eql(mockReq.user);
expect(mockRes.locals.isLoggedIn).to.be.true;
});
});
describe('expressRouting', () => {
it('should handle errors', () => {
expect(express.expressRouting()).to.eventually.be.rejected;
});
it('should return a promise', () => {
// this.settings.express.views.page_data
// this.app.locals.page_data
const mockThis = {
app: {
locals: {
page_data:{},
},
get:()=>{},
},
routers:[],
settings: {
express: {
views: {
page_data:{},
},
},
},
};
const expressPromise = express.expressRouting.call(mockThis);
expect(expressPromise).to.be.an.instanceof(Promise);
// console.log({ expressPromise });
expect(expressPromise).to.eventually.be.fulfilled;
});
});
describe('expressStatus', () => {
it('should handle errors', () => {
expect(express.expressStatus()).to.eventually.be.rejected;
});
it('should log current environment', (done) => {
const debugSpy = sinon.spy();
const warnSpy = sinon.spy();
const mockThis = {
environment: 'test',
config: {
debug: true,
},
logger: {
debug: debugSpy,
warn: warnSpy,
},
utilities: require('../../../lib/utilities'),
settings: {
application: {
check_for_updates: true,
version: '10.0.0',
}
}
};
express.expressStatus.call(mockThis)
.then(result => {
expect(result).to.be.true;
expect(debugSpy.called).to.be.true;
done();
})
.catch(done);
});
it('should handleLatestPeriodicVersionCheckError', () => {
const warnSpy = sinon.spy();
const mockThis = {
logger: {
warn: warnSpy,
}
}
express.handleLatestPeriodicVersionCheckError.call(mockThis);
expect(warnSpy.called).to.be.true;
});
it('should displayOutOfDatePeriodic', () => {
const warnSpy = sinon.spy();
const debugSpy = sinon.spy();
const mockThis = {
logger: {
debug: debugSpy,
warn: warnSpy,
},
settings: {
application: {
version: '10.0.0',
},
},
}
express.displayOutOfDatePeriodic.call(mockThis, { latestPeriodicVersion: '10.0.0' });
expect(debugSpy.called).to.be.true;
});
});
describe('expressErrors', () => {
it('should handle errors', () => {
expect(express.expressErrors()).to.eventually.be.rejected;
});
it('catchAllErrorMiddleware should skip middleware if no errors', () => {
const statusSpy = sinon.spy();
const sendSpy = sinon.spy();
const mockReq = {
query: {
format: 'json',
},
is: (type) => true,
};
const mockRes = {
status: statusSpy,
send: sendSpy,
};
const mockError = new Error('error for test');
const nextSpy = sinon.spy();
const statusSpy2 = sinon.spy();
const renderSpy = sinon.spy();
const mockReqAllError = {
query: {},
is: (type) => false,
}
const mockResAllError = {
status: statusSpy2,
render: renderSpy,
};
express.catchAllErrorMiddleware(mockError, mockReq, mockRes, nextSpy);
expect(sendSpy.called).to.be.true;
expect(statusSpy.called).to.be.true;
express.catchAllErrorMiddleware.call({
settings: {
express: {
views: {
custom_error_view: 'someerrorview',
},
},
},
}, mockError, mockReqAllError, mockResAllError, nextSpy);
expect(statusSpy2.called).to.be.true;
expect(renderSpy.called).to.be.true;
});
it('catchAllErrorMiddleware should respond with errors', () => {
const nextSpy = sinon.spy();
express.catchAllErrorMiddleware(false, null, null, nextSpy);
expect(nextSpy.called).to.be.true;
});
it('errorLogMiddleware should set error on next call', () => {
const nextSpy = sinon.spy();
const errorSpy = sinon.spy();
const mockReq = {
headers: {},
connection: {},
user: {
email: 'test@domain.tld',
}
};
const mockReq2 = {
headers: {},
connection: {},
};
const mockRes = {};
const mockError = new Error('middleware error test');
express.errorLogMiddleware.call({
logger: {
error: errorSpy,
},
}, mockError, mockReq, mockRes, nextSpy);
expect(nextSpy.called).to.be.true;
expect(errorSpy.called).to.be.true;
express.errorLogMiddleware.call({
logger: {
error: errorSpy,
},
}, mockError, mockReq2, mockRes, nextSpy);
});
});
after('remove Express test periodic dir', (done) => {
Promise.all([
fs.remove(initTestExpressPathDir),
fs.remove(initTestExpressEndPathDir),
])
.then(() => {
done();
}).catch(done);
});
});