Merge pull request #2835 from jaswilli/fix-tests

Fix up unit tests. Check config url with isURL.
This commit is contained in:
Hannah Wolfe 2014-05-31 16:56:15 +01:00
commit 3e7504faa6
12 changed files with 216 additions and 126 deletions

6
core/bootstrap.js vendored
View File

@ -7,6 +7,7 @@
var fs = require('fs'),
url = require('url'),
when = require('when'),
validator = require('validator'),
errors = require('./server/errors'),
config = require('./server/config'),
@ -73,12 +74,13 @@ function validateConfigEnvironment() {
}
// Check that our url is valid
parsedUrl = url.parse(config.url || 'invalid', false, true);
if (!parsedUrl.host) {
if (!validator.isURL(config.url, { protocols: ['http', 'https'], require_protocol: true })) {
errors.logError(new Error('Your site url in config.js is invalid.'), config.url, 'Please make sure this is a valid url before restarting');
return when.reject(rejectMessage);
}
parsedUrl = url.parse(config.url || 'invalid', false, true);
if (/\/ghost(\/|$)/.test(parsedUrl.pathname)) {
errors.logError(new Error('Your site url in config.js cannot contain a subdirectory called ghost.'), config.url, 'Please rename the subdirectory before restarting');
return when.reject(rejectMessage);

View File

@ -54,9 +54,7 @@ describe('DB API', function () {
results.posts.length.should.equal(0);
done();
});
}).catch(function (error) {
done(error);
});
}).catch(done);
});
it('delete all content is denied', function (done) {
@ -77,7 +75,7 @@ describe('DB API', function () {
}).catch(function (error) {
error.type.should.eql('NoPermissionError');
done();
});
}).catch(done);
});
it('export content is denied', function (done) {
@ -98,7 +96,7 @@ describe('DB API', function () {
}).catch(function (error) {
error.type.should.eql('NoPermissionError');
done();
});
}).catch(done);
});
it('import content is denied', function (done) {
@ -119,6 +117,6 @@ describe('DB API', function () {
}).catch(function (error) {
error.type.should.eql('NoPermissionError');
done();
});
}).catch(done);
});
});

View File

@ -45,6 +45,6 @@ describe('Mail API', function () {
}).catch(function (error) {
error.type.should.eql('EmailError');
done();
});
}).catch(done);
});
});

View File

@ -42,7 +42,7 @@ describe('Notifications API', function () {
results.notifications.length.should.be.above(0);
testUtils.API.checkResponse(results.notifications[0], 'notification');
done();
});
}).catch(done);
});
});
@ -64,7 +64,7 @@ describe('Notifications API', function () {
notification.location.should.equal('bottom');
done();
});
}).catch(done);
});
it('can add, adds id and status', function (done) {
@ -87,7 +87,7 @@ describe('Notifications API', function () {
notification.status.should.equal('persistent')
done();
});
}).catch(done);
});
it('can destroy', function (done) {

View File

@ -125,7 +125,7 @@ describe('Settings API', function () {
should.exist(error);
error.type.should.eql('NoPermissionError');
done();
});
}).catch(done);
});
it('can read core settings if an internal request', function (done) {
@ -172,7 +172,7 @@ describe('Settings API', function () {
err.type.should.eql('NoPermissionError');
done();
});
}).catch(done);
});
it('can edit a core setting with an internal request', function (done) {

View File

@ -60,7 +60,7 @@ describe('Slug API', function () {
}, function (error) {
error.type.should.eql('BadRequestError');
done();
});
}).catch(done);
});
});

View File

@ -19,7 +19,7 @@ describe('Themes API', function () {
before(function (done) {
testUtils.clearData().then(function () {
done();
}, done);
}).catch(done);
});
beforeEach(function (done) {
@ -53,14 +53,14 @@ describe('Themes API', function () {
});
done();
}, done);
}).catch(done);
});
afterEach(function (done) {
testUtils.clearData().then(function () {
sandbox.restore();
done();
}, done);
}).catch(done);
});
it('can browse', function (done) {
@ -77,7 +77,7 @@ describe('Themes API', function () {
done();
}).catch(function (error) {
done(new Error(JSON.stringify(error)));
});
}).catch(done);
});
it('can edit', function (done) {
@ -96,6 +96,6 @@ describe('Themes API', function () {
done();
}).catch(function (error) {
done(new Error(JSON.stringify(error)));
});
}).catch(done);
})
});

View File

@ -18,7 +18,7 @@ describe('Update Check', function () {
return testUtils.clearData();
}).then(function () {
done();
}, done);
}).catch(done);
});
after(function () {
@ -36,13 +36,13 @@ describe('Update Check', function () {
return permissions.init();
}).then(function () {
done();
}, done);
}).catch(done);
});
afterEach(function (done) {
testUtils.clearData().then(function () {
done();
}, done);
}).catch(done);
});
it('should report the correct data', function (done) {

View File

@ -20,9 +20,8 @@ describe('Bootstrap', function () {
bootstrap.__set__("readConfigFile", sandbox.stub().returns(
_.extend({}, defaultConfig, newConfig)
));
};
},
expectedError = new Error('expected bootstrap() to throw error but none thrown');
beforeEach(function () {
sandbox = sinon.sandbox.create();
@ -84,7 +83,7 @@ describe('Bootstrap', function () {
}).catch(done);
});
it('accepts valid urls', function (done) {
it('accepts urls with a valid scheme', function (done) {
// replace the config file with invalid data
overrideConfig({url: 'http://testurl.com'});
@ -109,118 +108,220 @@ describe('Bootstrap', function () {
}).then(function (localConfig) {
localConfig.url.should.equal('http://testurl.com/ghostly/');
// Next test
overrideConfig({url: '//testurl.com'});
return bootstrap();
}).then(function (localConfig) {
localConfig.url.should.equal('//testurl.com');
done();
}).catch(done);
});
it('rejects a fqdn without a scheme', function (done) {
overrideConfig({ url: 'example.com' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('rejects invalid urls', function (done) {
// replace the config file with invalid data
overrideConfig({url: 'notvalid'});
it('rejects a hostname without a scheme', function (done) {
bootstrap().catch(function (error) {
error.should.include(rejectMessage);
overrideConfig({ url: 'example' });
// Next test
overrideConfig({url: 'something.com'});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).then(function () {
should.fail('no error was thrown when it should have been');
done();
});
}).catch(done);
});
it('does not permit subdirectories named ghost', function (done) {
// replace the config file with invalid data
overrideConfig({url: 'http://testurl.com/ghost/'});
it('rejects a hostname with a scheme', function (done) {
bootstrap().catch(function (error) {
error.should.include(rejectMessage);
overrideConfig({ url: 'https://example' });
// Next test
overrideConfig({url: 'http://testurl.com/ghost/blog/'});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
// Next test
overrideConfig({url: 'http://testurl.com/blog/ghost'});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).then(function () {
should.fail('no error was thrown when it should have been');
done();
});
}).catch(done);
});
it('requires a database config', function (done) {
it('rejects a url with an unsupported scheme', function (done) {
overrideConfig({ url: 'ftp://example.com' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('rejects a url with a protocol relative scheme', function (done) {
overrideConfig({ url: '//example.com' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('does not permit the word ghost as a url path', function (done) {
overrideConfig({ url: 'http://example.com/ghost/' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('does not permit the word ghost to be a component in a url path', function (done) {
overrideConfig({ url: 'http://example.com/blog/ghost/' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('does not permit the word ghost to be a component in a url path', function (done) {
overrideConfig({ url: 'http://example.com/ghost/blog/' });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('does not permit database config to be falsy', function (done) {
// replace the config file with invalid data
overrideConfig({database: null});
overrideConfig({ database: false });
bootstrap().catch(function (error) {
error.should.include(rejectMessage);
// Next test
overrideConfig({database: {}});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).then(function () {
should.fail('no error was thrown when it should have been');
}).catch(done);
});
it('does not permit database config to be empty', function (done) {
// replace the config file with invalid data
overrideConfig({ database: {} });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
});
}).catch(done);
});
it('requires a socket or a host and port', function (done) {
// replace the config file with invalid data
overrideConfig({server: {socket: 'test'}});
it('requires server to be present', function (done) {
overrideConfig({ server: false });
bootstrap().then(function (localConfig) {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('allows server to use a socket', function (done) {
overrideConfig({ server: { socket: 'test' } });
bootstrap().then(function (localConfig) {
should.exist(localConfig);
localConfig.server.socket.should.equal('test');
// Next test
overrideConfig({server: null});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
done();
}).catch(done);
});
// Next test
overrideConfig({server: {host: null}});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
it('allows server to have a host and a port', function (done) {
overrideConfig({ server: { host: '127.0.0.1', port: '2368' } });
// Next test
overrideConfig({server: {port: null}});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
// Next test
overrideConfig({server: {host: null, port: null}});
return bootstrap();
}).catch(function (error) {
error.should.include(rejectMessage);
bootstrap().then(function (localConfig) {
should.exist(localConfig);
localConfig.server.host.should.equal('127.0.0.1');
localConfig.server.port.should.equal('2368');
done();
}).then(function () {
should.fail('no error was thrown when it should have been');
}).catch(done);
});
it('rejects server if there is a host but no port', function (done) {
overrideConfig({ server: { host: '127.0.0.1' } });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
});
}).catch(done);
});
it('rejects server if there is a port but no host', function (done) {
overrideConfig({ server: { port: '2368' } });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
it('rejects server if configuration is empty', function (done) {
overrideConfig({ server: {} });
bootstrap().then(function () {
done(expectedError);
}).catch(function (err) {
should.exist(err);
err.should.contain(rejectMessage);
done();
}).catch(done);
});
});

View File

@ -149,7 +149,7 @@ describe("Mail", function () {
}).catch(function (err) {
err.should.be.an.instanceOf(Error);
done();
});
}).catch(done);
});
});
@ -168,13 +168,12 @@ describe("Mail", function () {
}).catch(done);
});
it('should use from address as configured in config.js', function (done) {
it('should use from address as configured in config.js', function () {
overrideConfig({mail:{fromaddress: 'static@example.com'}});
mailer.fromAddress().should.equal('static@example.com');
done();
});
it('should fall back to ghost@[blog.url] as from address', function (done) {
it('should fall back to ghost@[blog.url] as from address', function () {
// Standard domain
overrideConfig({url: 'http://default.com', mail:{fromaddress: null}});
mailer.fromAddress().should.equal('ghost@default.com');
@ -186,7 +185,5 @@ describe("Mail", function () {
// Strip Port
overrideConfig({url: 'http://default.com:2368/', mail:{}});
mailer.fromAddress().should.equal('ghost@default.com');
done();
});
});

View File

@ -73,10 +73,9 @@ describe('Middleware', function () {
};
});
it('should return a json 401 error response', function (done) {
it('should return a json 401 error response', function () {
middleware.authAPI(req, res, null);
assert(res.json.calledWith(401, { error: 'Please sign in' }));
done();
});
it('should call next if a user exists in session', function (done) {
@ -103,12 +102,11 @@ describe('Middleware', function () {
};
});
it('should redirect to dashboard', function (done) {
it('should redirect to dashboard', function () {
req.session.user = {};
middleware.redirectToDashboard(req, res, null);
assert(res.redirect.calledWithMatch('/ghost/'));
done();
});
it('should call next if no user in session', function (done) {

View File

@ -221,7 +221,7 @@ describe('Permissions', function () {
return canThisResult.edit.page(fakePage);
})
.then(function () {
errors.logError(new Error("Allowed edit post without permission"));
done(new Error('was able to edit post without permission'));
}).catch(done);
});
@ -287,9 +287,8 @@ describe('Permissions', function () {
})
.catch(function () {
permissableStub.restore();
errors.logError(new Error("Did not allow testUser"));
done();
done(new Error('did not allow testUser'));
});
});
@ -386,10 +385,7 @@ describe('Permissions', function () {
.post(updatedPost.id)
.then(function () {
done(new Error("Allowed an edit of post 1"));
})
.catch(function () {
done();
});
}).catch(done);
}).catch(done);
});
@ -412,9 +408,7 @@ describe('Permissions', function () {
.then(function () {
done(new Error("Should not allow editing post"));
})
.catch(function () {
done();
});
.catch(done);
});
it('allows \'internal\' to be passed for internal requests', function (done) {