Skip to content

Commit

Permalink
🚨 adapt fork logic
Browse files Browse the repository at this point in the history
refs #6982
- write json file instead of js file
- simplifiy how we pass config for a forked child process

[ci skip]
  • Loading branch information
kirrg001 authored and ErisDS committed Sep 20, 2016
1 parent b158a3a commit 66dbd5f
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 121 deletions.
30 changes: 16 additions & 14 deletions core/test/functional/routes/admin_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ var request = require('supertest'),

testUtils = require('../../utils'),
ghost = require('../../../../core'),
i18n = require('../../../../core/server/i18n');
i18n = require('../../../../core/server/i18n'),
config = require('../../../../core/server/config');

i18n.init();

describe('Admin Routing', function () {
Expand Down Expand Up @@ -111,17 +113,18 @@ describe('Admin Routing', function () {
// we'll use X-Forwarded-Proto: https to simulate an 'https://' request behind a proxy
describe('Require HTTPS - no redirect', function () {
var forkedGhost, request;
before(function (done) {
var configTestHttps = testUtils.fork.config();
configTestHttps.forceAdminSSL = {redirect: false};
configTestHttps.urlSSL = 'https://localhost/';

testUtils.fork.ghost(configTestHttps, 'testhttps')
before(function (done) {
testUtils.fork.ghost({
forceAdminSSL: {redirect: false},
urlSSL: 'https://localhost/'
}, 'testhttps')
.then(function (child) {
forkedGhost = child;
request = require('supertest');
request = request(configTestHttps.url.replace(/\/$/, ''));
}).then(done)
request = request(config.get('url').replace(/\/$/, ''));
})
.then(done)
.catch(done);
});

Expand Down Expand Up @@ -150,15 +153,14 @@ describe('Admin Routing', function () {
describe('Require HTTPS - redirect', function () {
var forkedGhost, request;
before(function (done) {
var configTestHttps = testUtils.fork.config();
configTestHttps.forceAdminSSL = {redirect: true};
configTestHttps.urlSSL = 'https://localhost/';

testUtils.fork.ghost(configTestHttps, 'testhttps')
testUtils.fork.ghost({
forceAdminSSL: {redirect: true},
urlSSL: 'https://localhost/'
}, 'testhttps')
.then(function (child) {
forkedGhost = child;
request = require('supertest');
request = request(configTestHttps.url.replace(/\/$/, ''));
request = request(config.get('url').replace(/\/$/, ''));
}).then(done)
.catch(done);
});
Expand Down
180 changes: 92 additions & 88 deletions core/test/functional/routes/frontend_spec.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@

// # Frontend Route tests
// As it stands, these tests depend on the database, and as such are integration tests.
// Mocking out the models to not touch the DB would turn these into unit tests, and should probably be done in future,
// But then again testing real code, rather than mock code, might be more useful...

var request = require('supertest'),
should = require('should'),
moment = require('moment'),
cheerio = require('cheerio'),

testUtils = require('../../utils'),
ghost = require('../../../../core');
var request = require('supertest'),
should = require('should'),
moment = require('moment'),
cheerio = require('cheerio'),
testUtils = require('../../utils'),
ghost = require('../../../../core');

describe('Frontend Routing', function () {
function doEnd(done) {
Expand Down Expand Up @@ -49,7 +47,75 @@ describe('Frontend Routing', function () {
});
});

after(testUtils.teardown);
describe('Date permalinks', function () {
before(function (done) {
// Only way to swap permalinks setting is to login and visit the URL because
// poking the database doesn't work as settings are cached
testUtils.togglePermalinks(request, 'date')
.then(function () {
done();
})
.catch(done);
});

after(function (done) {
testUtils.togglePermalinks(request)
.then(function () {
done();
})
.catch(done);
});

it('should load a post with date permalink', function (done) {
var date = moment().format('YYYY/MM/DD');

request.get('/' + date + '/welcome-to-ghost/')
.expect(200)
.expect('Content-Type', /html/)
.end(doEnd(done));
});

it('expect redirect because of wrong/old permalink prefix', function (done) {
var date = moment().format('YYYY/MM/DD');

request.get('/2016/04/01/welcome-to-ghost/')
.expect('Content-Type', /html/)
.end(function (err, res) {
res.status.should.eql(301);
request.get('/' + date + '/welcome-to-ghost/')
.expect(200)
.expect('Content-Type', /html/)
.end(doEnd(done));
});
});

it('should serve RSS with date permalink', function (done) {
request.get('/rss/')
.expect('Content-Type', 'text/xml; charset=utf-8')
.expect('Cache-Control', testUtils.cacheRules.public)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}

should.not.exist(res.headers['x-cache-invalidate']);
should.not.exist(res.headers['X-CSRF-Token']);
should.not.exist(res.headers['set-cookie']);
should.exist(res.headers.date);

var content = res.text,
todayMoment = moment(),
dd = todayMoment.format('DD'),
mm = todayMoment.format('MM'),
yyyy = todayMoment.format('YYYY'),
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/welcome-to-ghost/';

content.indexOf(postLink).should.be.above(0);
done();
});
});
});

describe('Test with Initial Fixtures', function () {
after(testUtils.teardown);
Expand Down Expand Up @@ -152,7 +218,7 @@ describe('Frontend Routing', function () {

it('should not work with date permalinks', function (done) {
// get today's date
var date = moment().format('YYYY/MM/DD');
var date = moment().format('YYYY/MM/DD');

request.get('/' + date + '/welcome-to-ghost/')
.expect('Cache-Control', testUtils.cacheRules.private)
Expand Down Expand Up @@ -234,7 +300,7 @@ describe('Frontend Routing', function () {

it('should not work with date permalinks', function (done) {
// get today's date
var date = moment().format('YYYY/MM/DD');
var date = moment().format('YYYY/MM/DD');

request.get('/' + date + '/welcome-to-ghost/amp/')
.expect('Cache-Control', testUtils.cacheRules.private)
Expand Down Expand Up @@ -286,7 +352,6 @@ describe('Frontend Routing', function () {

describe('Static page', function () {
before(addPosts);

after(testUtils.teardown);

it('should redirect without slash', function (done) {
Expand Down Expand Up @@ -344,7 +409,6 @@ describe('Frontend Routing', function () {

describe('Post preview', function () {
before(addPosts);

after(testUtils.teardown);

it('should display draft posts accessed via uuid', function (done) {
Expand Down Expand Up @@ -390,7 +454,6 @@ describe('Frontend Routing', function () {

describe('Post with Ghost in the url', function () {
before(addPosts);

after(testUtils.teardown);

// All of Ghost's admin depends on the /ghost/ in the url to work properly
Expand All @@ -405,11 +468,11 @@ describe('Frontend Routing', function () {

describe('Subdirectory (no slash)', function () {
var forkedGhost, request;
before(function (done) {
var configTest = testUtils.fork.config();
configTest.url = 'http://localhost/blog';

testUtils.fork.ghost(configTest, 'testsubdir')
before(function (done) {
testUtils.fork.ghost({
url: 'http://localhost/blog'
}, 'testsubdir')
.then(function (child) {
forkedGhost = child;
request = require('supertest');
Expand Down Expand Up @@ -483,10 +546,9 @@ describe('Frontend Routing', function () {
var forkedGhost, request;

before(function (done) {
var configTest = testUtils.fork.config();
configTest.url = 'http://localhost/blog/';

testUtils.fork.ghost(configTest, 'testsubdir')
testUtils.fork.ghost({
url: 'http://localhost/blog/'
}, 'testsubdir')
.then(function (child) {
forkedGhost = child;
request = require('supertest');
Expand Down Expand Up @@ -575,15 +637,17 @@ describe('Frontend Routing', function () {
var forkedGhost, request;

before(function (done) {
var configTestHttps = testUtils.fork.config();
configTestHttps.forceAdminSSL = {redirect: false};
configTestHttps.urlSSL = 'https://localhost/';

testUtils.fork.ghost(configTestHttps, 'testhttps')
testUtils.fork.ghost({
forceAdminSSL: {redirect: false},
urlSSL: 'https://localhost/',
server: {
port: 2370
}
}, 'testhttps')
.then(function (child) {
forkedGhost = child;
request = require('supertest');
request = request(configTestHttps.url.replace(/\/$/, ''));
request = request('http://127.0.0.1:2370');
}).then(done).catch(done);
});

Expand Down Expand Up @@ -613,66 +677,6 @@ describe('Frontend Routing', function () {
});
});

describe('Date permalinks', function () {
before(function (done) {
// Only way to swap permalinks setting is to login and visit the URL because
// poking the database doesn't work as settings are cached
testUtils.togglePermalinks(request, 'date').then(function () {
done();
});
});

it('should load a post with date permalink', function (done) {
var date = moment().format('YYYY/MM/DD');

request.get('/' + date + '/welcome-to-ghost/')
.expect(200)
.expect('Content-Type', /html/)
.end(doEnd(done));
});

it('expect redirect because of wrong/old permalink prefix', function (done) {
var date = moment().format('YYYY/MM/DD');

request.get('/2016/04/01/welcome-to-ghost/')
.expect('Content-Type', /html/)
.end(function (err, res) {
res.status.should.eql(301);
request.get('/' + date + '/welcome-to-ghost/')
.expect(200)
.expect('Content-Type', /html/)
.end(doEnd(done));
});
});

it('should serve RSS with date permalink', function (done) {
request.get('/rss/')
.expect('Content-Type', 'text/xml; charset=utf-8')
.expect('Cache-Control', testUtils.cacheRules.public)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}

should.not.exist(res.headers['x-cache-invalidate']);
should.not.exist(res.headers['X-CSRF-Token']);
should.not.exist(res.headers['set-cookie']);
should.exist(res.headers.date);

var content = res.text,
todayMoment = moment(),
dd = todayMoment.format('DD'),
mm = todayMoment.format('MM'),
yyyy = todayMoment.format('YYYY'),
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/welcome-to-ghost/';

content.indexOf(postLink).should.be.above(0);
done();
});
});
});

describe('Site Map', function () {
before(testUtils.teardown);

Expand Down
40 changes: 21 additions & 19 deletions core/test/utils/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,29 @@ function findFreePort(port) {
});
}

// Get a copy of current config object from file, to be modified before
// passing to forkGhost() method
function forkConfig() {
// require caches values, and we want to read it fresh from the file
delete require.cache[config.paths.config];
return _.cloneDeep(require(config.paths.config)[process.env.NODE_ENV]);
}

// Creates a new fork of Ghost process with a given config
// Useful for tests that want to verify certain config options
function forkGhost(newConfig, envName) {
envName = envName || 'forked';

return findFreePort(newConfig.server ? newConfig.server.port : undefined)
return findFreePort()
.then(function (port) {
newConfig.server = newConfig.server || {};
newConfig.server.port = port;
newConfig.url = url.format(_.extend({}, url.parse(newConfig.url), {port: port, host: null}));
newConfig.server = _.merge({}, {
port: port
}, (newConfig.server || {}));

if (newConfig.url) {
newConfig.url = url.format(_.extend({}, url.parse(newConfig.url), {port: newConfig.server.port, host: null}));
} else {
newConfig.url = url.format(_.extend({}, url.parse(config.get('url')), {port: newConfig.server.port, host: null}));
}

var newConfigFile = path.join(config.paths.appRoot, 'config.test.' + envName + '.js');
newConfig.logging = false;

var newConfigFile = path.join(config.get('paths').appRoot, 'config.test.' + envName + '.json');

return new Promise(function (resolve, reject) {
fs.writeFile(newConfigFile, 'module.exports = {"' + process.env.NODE_ENV + '": ' + JSON.stringify(newConfig) + '}', function (err) {
fs.writeFile(newConfigFile, JSON.stringify(newConfig), function (err) {
if (err) {
return reject(err);
}
Expand All @@ -80,13 +80,16 @@ function forkGhost(newConfig, envName) {
return false;
};

env.GHOST_CONFIG = newConfigFile;
child = cp.fork(path.join(config.paths.appRoot, 'index.js'), {env: env});
env.NODE_ENV = 'test.' + envName;

child = cp.fork(path.join(config.get('paths').appRoot, 'index.js'), {env: env});

// return the port to make it easier to do requests
child.port = port;
child.port = newConfig.server.port;

// periodic check until forked Ghost is running and is listening on the port
pingCheck = setInterval(function () {
var socket = net.connect(port);
var socket = net.connect(newConfig.server.port);
socket.on('connect', function () {
socket.end();
if (pingStop()) {
Expand Down Expand Up @@ -143,4 +146,3 @@ function forkGhost(newConfig, envName) {
}

module.exports.ghost = forkGhost;
module.exports.config = forkConfig;

0 comments on commit 66dbd5f

Please sign in to comment.