mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
Add API tests
closes #1189 - added tests - added request module - added status codes to API calls - fixed return values of API calls - fixed that drafts caused an error when being deleted - fixed X-Invalidate-Cache headers - moved testUtils.js to utils/index.js
This commit is contained in:
parent
dee054e2c3
commit
bb17e1c0e9
@ -156,4 +156,4 @@ db = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.db = db;
|
||||
module.exports = db;
|
||||
|
@ -20,7 +20,7 @@ var Ghost = require('../../ghost'),
|
||||
settingsObject,
|
||||
settingsCollection,
|
||||
settingsFilter,
|
||||
filteredUserAttributes = ['password', 'created_by', 'updated_by'];
|
||||
filteredUserAttributes = ['password', 'created_by', 'updated_by', 'last_login'];
|
||||
|
||||
// ## Posts
|
||||
posts = {
|
||||
@ -28,6 +28,7 @@ posts = {
|
||||
|
||||
// **takes:** filter / pagination parameters
|
||||
browse: function browse(options) {
|
||||
|
||||
// **returns:** a promise for a page of posts in a json object
|
||||
//return dataProvider.Post.findPage(options);
|
||||
return dataProvider.Post.findPage(options).then(function (result) {
|
||||
@ -57,8 +58,8 @@ posts = {
|
||||
omitted.user = _.omit(omitted.user, filteredUserAttributes);
|
||||
return omitted;
|
||||
}
|
||||
return when.reject({errorCode: 404, message: 'Post not found'});
|
||||
|
||||
return null;
|
||||
});
|
||||
},
|
||||
|
||||
@ -68,13 +69,28 @@ posts = {
|
||||
edit: function edit(postData) {
|
||||
// **returns:** a promise for the resulting post in a json object
|
||||
if (!this.user) {
|
||||
return when.reject("You do not have permission to edit this post.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to edit this post.'});
|
||||
}
|
||||
|
||||
return canThis(this.user).edit.post(postData.id).then(function () {
|
||||
return dataProvider.Post.edit(postData);
|
||||
var self = this;
|
||||
return canThis(self.user).edit.post(postData.id).then(function () {
|
||||
return dataProvider.Post.edit(postData).then(function (result) {
|
||||
if (result) {
|
||||
var omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
omitted.user = _.omit(omitted.user, filteredUserAttributes);
|
||||
return omitted;
|
||||
}
|
||||
return when.reject({errorCode: 404, message: 'Post not found'});
|
||||
}).otherwise(function (error) {
|
||||
return dataProvider.Post.findOne({id: postData.id, status: 'all'}).then(function (result) {
|
||||
if (!result) {
|
||||
return when.reject({errorCode: 404, message: 'Post not found'});
|
||||
}
|
||||
return when.reject({message: error.message});
|
||||
});
|
||||
});
|
||||
}, function () {
|
||||
return when.reject("You do not have permission to edit this post.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to edit this post.'});
|
||||
});
|
||||
},
|
||||
|
||||
@ -84,13 +100,13 @@ posts = {
|
||||
add: function add(postData) {
|
||||
// **returns:** a promise for the resulting post in a json object
|
||||
if (!this.user) {
|
||||
return when.reject("You do not have permission to add posts.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to add posts.'});
|
||||
}
|
||||
|
||||
return canThis(this.user).create.post().then(function () {
|
||||
return dataProvider.Post.add(postData);
|
||||
}, function () {
|
||||
return when.reject("You do not have permission to add posts.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to add posts.'});
|
||||
});
|
||||
},
|
||||
|
||||
@ -100,11 +116,11 @@ posts = {
|
||||
destroy: function destroy(args) {
|
||||
// **returns:** a promise for a json response with the id of the deleted post
|
||||
if (!this.user) {
|
||||
return when.reject("You do not have permission to remove posts.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to remove posts.'});
|
||||
}
|
||||
|
||||
return canThis(this.user).remove.post(args.id).then(function () {
|
||||
return when(posts.read({id : args.id})).then(function (result) {
|
||||
return when(posts.read({id : args.id, status: 'all'})).then(function (result) {
|
||||
return dataProvider.Post.destroy(args.id).then(function () {
|
||||
var deletedObj = {};
|
||||
deletedObj.id = result.id;
|
||||
@ -113,7 +129,7 @@ posts = {
|
||||
});
|
||||
});
|
||||
}, function () {
|
||||
return when.reject("You do not have permission to remove posts.");
|
||||
return when.reject({errorCode: 403, message: 'You do not have permission to remove posts.'});
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -157,7 +173,7 @@ users = {
|
||||
return omitted;
|
||||
}
|
||||
|
||||
return null;
|
||||
return when.reject({errorCode: 404, message: 'User not found'});
|
||||
});
|
||||
},
|
||||
|
||||
@ -167,7 +183,13 @@ users = {
|
||||
edit: function edit(userData) {
|
||||
// **returns:** a promise for the resulting user in a json object
|
||||
userData.id = this.user;
|
||||
return dataProvider.User.edit(userData);
|
||||
return dataProvider.User.edit(userData).then(function (result) {
|
||||
if (result) {
|
||||
var omitted = _.omit(result.toJSON(), filteredUserAttributes);
|
||||
return omitted;
|
||||
}
|
||||
return when.reject({errorCode: 404, message: 'User not found'});
|
||||
});
|
||||
},
|
||||
|
||||
// #### Add
|
||||
@ -289,6 +311,7 @@ settings = {
|
||||
// **returns:** a promise for a settings json object
|
||||
if (ghost.settings()) {
|
||||
return when(ghost.settings()).then(function (settings) {
|
||||
//TODO: omit where type==core
|
||||
return settingsObject(settingsFilter(settings, options.type));
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
@ -305,7 +328,7 @@ settings = {
|
||||
if (ghost.settings()) {
|
||||
return when(ghost.settings()[options.key]).then(function (setting) {
|
||||
if (!setting) {
|
||||
return when.reject("Unable to find setting: " + options.key);
|
||||
return when.reject({errorCode: 404, message: 'Unable to find setting: ' + options.key});
|
||||
}
|
||||
var res = {};
|
||||
res.key = options.key;
|
||||
@ -333,11 +356,18 @@ settings = {
|
||||
ghost.updateSettingsCache(settings);
|
||||
return settingsObject(settingsFilter(ghost.settings(), type));
|
||||
});
|
||||
}, errors.logAndThrowError);
|
||||
}).otherwise(function (error) {
|
||||
return dataProvider.Settings.read(key.key).then(function (result) {
|
||||
if (!result) {
|
||||
return when.reject({errorCode: 404, message: 'Unable to find setting: ' + key});
|
||||
}
|
||||
return when.reject({message: error.message});
|
||||
});
|
||||
});
|
||||
}
|
||||
return dataProvider.Settings.read(key).then(function (setting) {
|
||||
if (!setting) {
|
||||
return when.reject("Unable to find setting: " + key);
|
||||
return when.reject({errorCode: 404, message: 'Unable to find setting: ' + key});
|
||||
}
|
||||
if (!_.isString(value)) {
|
||||
value = JSON.stringify(value);
|
||||
@ -356,20 +386,18 @@ settings = {
|
||||
function invalidateCache(req, res, result) {
|
||||
var parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'),
|
||||
method = req.method,
|
||||
endpoint = parsedUrl[3],
|
||||
id = parsedUrl[4],
|
||||
cacheInvalidate;
|
||||
endpoint = parsedUrl[4],
|
||||
id = parsedUrl[5],
|
||||
cacheInvalidate,
|
||||
jsonResult = result.toJSON ? result.toJSON() : result;
|
||||
|
||||
if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
|
||||
if (endpoint === 'settings' || endpoint === 'users') {
|
||||
cacheInvalidate = "/*";
|
||||
} else if (endpoint === 'posts') {
|
||||
cacheInvalidate = "/, /page/*, /rss/, /rss/*";
|
||||
if (id) {
|
||||
if (result.toJSON) {
|
||||
cacheInvalidate += ', /' + result.toJSON().slug + '/';
|
||||
} else {
|
||||
cacheInvalidate += ', /' + result.slug + '/';
|
||||
}
|
||||
if (id && jsonResult.slug) {
|
||||
cacheInvalidate += ', /' + jsonResult.slug + '/';
|
||||
}
|
||||
}
|
||||
if (cacheInvalidate) {
|
||||
@ -394,8 +422,9 @@ requestHandler = function (apiMethod) {
|
||||
invalidateCache(req, res, result);
|
||||
res.json(result || {});
|
||||
}, function (error) {
|
||||
error = {error: _.isString(error) ? error : (_.isObject(error) ? error.message : 'Unknown API Error')};
|
||||
res.json(400, error);
|
||||
var errorCode = error.errorCode || 500,
|
||||
errorMsg = {error: _.isString(error) ? error : (_.isObject(error) ? error.message : 'Unknown API Error')};
|
||||
res.json(errorCode, errorMsg);
|
||||
});
|
||||
};
|
||||
};
|
||||
@ -406,5 +435,5 @@ module.exports.users = users;
|
||||
module.exports.tags = tags;
|
||||
module.exports.notifications = notifications;
|
||||
module.exports.settings = settings;
|
||||
module.exports.db = db.db;
|
||||
module.exports.db = db;
|
||||
module.exports.requestHandler = requestHandler;
|
||||
|
@ -341,9 +341,19 @@ Post = ghostBookshelf.Model.extend({
|
||||
},
|
||||
|
||||
add: function (newPostData, options) {
|
||||
return ghostBookshelf.Model.add.call(this, newPostData, options).tap(function (post) {
|
||||
var self = this;
|
||||
return ghostBookshelf.Model.add.call(this, newPostData, options).then(function (post) {
|
||||
// associated models can't be created until the post has an ID, so run this after
|
||||
return post.updateTags(newPostData.tags);
|
||||
return when(post.updateTags(newPostData.tags)).then(function () {
|
||||
return self.findOne({status: 'all', id: post.id});
|
||||
});
|
||||
});
|
||||
},
|
||||
edit: function (editedPost, options) {
|
||||
var self = this;
|
||||
|
||||
return ghostBookshelf.Model.edit.call(this, editedPost, options).then(function (editedObj) {
|
||||
return self.findOne({status: 'all', id: editedObj.id});
|
||||
});
|
||||
},
|
||||
destroy: function (_identifier, options) {
|
||||
|
@ -28,8 +28,8 @@ User = ghostBookshelf.Model.extend({
|
||||
|
||||
permittedAttributes: [
|
||||
'id', 'uuid', 'name', 'slug', 'password', 'email', 'image', 'cover', 'bio', 'website', 'location',
|
||||
'accessibility', 'status', 'language', 'meta_title', 'meta_description', 'created_at', 'created_by',
|
||||
'updated_at', 'updated_by'
|
||||
'accessibility', 'status', 'language', 'meta_title', 'meta_description', 'last_login', 'created_at',
|
||||
'created_by', 'updated_at', 'updated_by'
|
||||
],
|
||||
|
||||
validate: function () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, it, before, beforeEach, afterEach */
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
should = require('should'),
|
||||
errors = require('../../server/errorHandling'),
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
when = require('when'),
|
||||
@ -310,8 +310,7 @@ describe('Post Model', function () {
|
||||
}).then(function (newPost) {
|
||||
|
||||
should.exist(newPost);
|
||||
|
||||
newPost.get('published_at').should.equal(previousPublishedAtDate);
|
||||
newPost.get('published_at').should.equal(previousPublishedAtDate.getTime());
|
||||
|
||||
done();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, it, before, beforeEach, afterEach */
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
should = require('should'),
|
||||
errors = require('../../server/errorHandling'),
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
should = require('should'),
|
||||
_ = require("underscore"),
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
_ = require("underscore"),
|
||||
when = require('when'),
|
||||
sequence = require('when/sequence'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('../unit/testUtils'),
|
||||
var testUtils = require('../unit/utils'),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
_ = require('underscore'),
|
||||
|
@ -1,12 +1,21 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore');
|
||||
_ = require('underscore'),
|
||||
request = require('request'),
|
||||
expectedPostsProperties = ['posts', 'page', 'limit', 'pages', 'total'],
|
||||
expectedPostProperties = ['id', 'uuid', 'title', 'slug', 'markdown', 'html', 'meta_title', 'meta_description',
|
||||
'featured', 'image', 'status', 'language', 'author_id', 'created_at', 'created_by', 'updated_at', 'updated_by',
|
||||
'published_at', 'published_by', 'page', 'author', 'user', 'tags'];
|
||||
|
||||
|
||||
|
||||
request = request.defaults({jar:true})
|
||||
|
||||
describe('Post API', function () {
|
||||
|
||||
var user = testUtils.DataGenerator.forModel.users[0],
|
||||
authCookie;
|
||||
csrfToken = '';
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData()
|
||||
@ -16,17 +25,22 @@ describe('Post API', function () {
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return testUtils.insertDefaultFixtures();
|
||||
testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
return testUtils.API.login(user.email, user.password);
|
||||
})
|
||||
.then(function (authResponse) {
|
||||
authCookie = authResponse;
|
||||
|
||||
done();
|
||||
// do a get request to get the CSRF token first
|
||||
request.get(testUtils.API.getSigninURL(), function (error, response, body) {
|
||||
var pattern_meta = /<meta.*?name="csrf-param".*?content="(.*?)".*?>/i;
|
||||
pattern_meta.should.exist;
|
||||
csrfToken = body.match(pattern_meta)[1];
|
||||
request.post({uri:testUtils.API.getSigninURL(),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
done();
|
||||
}).form({email: user.email, password: user.password});
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
@ -36,13 +50,170 @@ describe('Post API', function () {
|
||||
}, done);
|
||||
});
|
||||
|
||||
// it('can retrieve a post', function (done) {
|
||||
// testUtils.API.get(testUtils.API.ApiRouteBase + 'posts/?status=all', authCookie).then(function (result) {
|
||||
// should.exist(result);
|
||||
// should.exist(result.response);
|
||||
// result.response.posts.length.should.be.above(1);
|
||||
// done();
|
||||
// }).otherwise(done);
|
||||
// });
|
||||
it('can retrieve all posts', function (done) {
|
||||
request.get(testUtils.API.getApiURL('posts/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, expectedPostsProperties);
|
||||
jsonResponse.posts.should.have.length(5);
|
||||
testUtils.API.checkResponse (jsonResponse.posts[0], expectedPostProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can retrieve a post', function (done) {
|
||||
request.get(testUtils.API.getApiURL('posts/1/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, expectedPostProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can create a new draft, publish post, update post', function (done) {
|
||||
var newTitle = 'My Post',
|
||||
changedTitle = 'My Post changed',
|
||||
publishedState = 'published',
|
||||
newPost = {status:'draft', title:newTitle, markdown:'my post'};
|
||||
|
||||
request.post({uri: testUtils.API.getApiURL('posts/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: newPost}, function (error, response, draftPost) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
draftPost.should.exist;
|
||||
draftPost.title.should.eql(newTitle);
|
||||
draftPost.status = publishedState;
|
||||
testUtils.API.checkResponse (draftPost, expectedPostProperties);
|
||||
request.put({uri: testUtils.API.getApiURL('posts/' + draftPost.id + '/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: draftPost}, function (error, response, publishedPost) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
publishedPost.should.exist;
|
||||
publishedPost.title.should.eql(newTitle);
|
||||
publishedPost.status.should.eql(publishedState);
|
||||
testUtils.API.checkResponse (publishedPost, expectedPostProperties);
|
||||
request.put({uri: testUtils.API.getApiURL('posts/' + publishedPost.id + '/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: publishedPost}, function (error, response, updatedPost) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
updatedPost.should.exist;
|
||||
updatedPost.title.should.eql(newTitle);
|
||||
testUtils.API.checkResponse (updatedPost, expectedPostProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a post', function (done) {
|
||||
var deletePostId = 1;
|
||||
request.del({uri: testUtils.API.getApiURL('posts/' + deletePostId +'/'),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['id', 'slug']);
|
||||
jsonResponse.id.should.eql(deletePostId);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t delete a non existent post', function (done) {
|
||||
request.del({uri: testUtils.API.getApiURL('posts/99/'),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a new draft', function (done) {
|
||||
var newTitle = 'My Post',
|
||||
publishedState = 'draft',
|
||||
newPost = {status: publishedState, title: newTitle, markdown: 'my post'};
|
||||
|
||||
request.post({uri: testUtils.API.getApiURL('posts/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: newPost}, function (error, response, draftPost) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
draftPost.should.exist;
|
||||
draftPost.title.should.eql(newTitle);
|
||||
draftPost.status = publishedState;
|
||||
testUtils.API.checkResponse (draftPost, expectedPostProperties);
|
||||
request.del({uri: testUtils.API.getApiURL('posts/' + draftPost.id + '/'),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['id', 'slug']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('can\'t retrieve non existent post', function (done) {
|
||||
request.get(testUtils.API.getApiURL('posts/99/'), function (error, response, body) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can edit a post', function (done) {
|
||||
request.get(testUtils.API.getApiURL('posts/1/'), function (error, response, body) {
|
||||
var jsonResponse = JSON.parse(body),
|
||||
changedValue = 'My new Title';
|
||||
jsonResponse.should.exist;
|
||||
//jsonResponse.websiteshould.be.empty;
|
||||
jsonResponse.title = changedValue;
|
||||
|
||||
request.put({uri: testUtils.API.getApiURL('posts/1/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: jsonResponse}, function (error, response, putBody) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.title.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse (putBody, expectedPostProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t edit non existent post', function (done) {
|
||||
request.get(testUtils.API.getApiURL('posts/1/'), function (error, response, body) {
|
||||
var jsonResponse = JSON.parse(body),
|
||||
changedValue = 'My new Title';
|
||||
jsonResponse.title.exist;
|
||||
jsonResponse.testvalue = changedValue;
|
||||
jsonResponse.id = 99;
|
||||
request.put({uri: testUtils.API.getApiURL('posts/99/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: jsonResponse}, function (error, response, putBody) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
testUtils.API.checkResponse (putBody, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
123
core/test/unit/api_settings_spec.js
Normal file
123
core/test/unit/api_settings_spec.js
Normal file
@ -0,0 +1,123 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
request = require('request'),
|
||||
// TODO: remove databaseVersion
|
||||
expectedProperties = ['databaseVersion', 'title', 'description', 'email', 'logo', 'cover', 'defaultLang',
|
||||
'postsPerPage', 'forceI18n', 'activeTheme', 'activePlugins', 'installedPlugins', 'availableThemes'];
|
||||
|
||||
request = request.defaults({jar:true})
|
||||
|
||||
describe('Settings API', function () {
|
||||
|
||||
var user = testUtils.DataGenerator.forModel.users[0],
|
||||
csrfToken = '';
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData()
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
// do a get request to get the CSRF token first
|
||||
request.get(testUtils.API.getSigninURL(), function (error, response, body) {
|
||||
var pattern_meta = /<meta.*?name="csrf-param".*?content="(.*?)".*?>/i;
|
||||
pattern_meta.should.exist;
|
||||
csrfToken = body.match(pattern_meta)[1];
|
||||
request.post({uri:testUtils.API.getSigninURL(),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
done();
|
||||
}).form({email: user.email, password: user.password});
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
// TODO: currently includes values of type=core
|
||||
it('can retrieve all settings', function (done) {
|
||||
request.get(testUtils.API.getApiURL('settings/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
|
||||
testUtils.API.checkResponse (jsonResponse, expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('can retrieve a setting', function (done) {
|
||||
request.get(testUtils.API.getApiURL('settings/title/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['key','value']);
|
||||
jsonResponse.key.should.eql('title');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t retrieve non existent setting', function (done) {
|
||||
request.get(testUtils.API.getApiURL('settings/testsetting/'), function (error, response, body) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse (jsonResponse, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can edit settings', function (done) {
|
||||
request.get(testUtils.API.getApiURL('settings'), function (error, response, body) {
|
||||
var jsonResponse = JSON.parse(body),
|
||||
changedValue = 'Ghost changed';
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.title = changedValue;
|
||||
|
||||
request.put({uri: testUtils.API.getApiURL('settings/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: jsonResponse}, function (error, response, putBody) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.title.should.eql(changedValue);
|
||||
testUtils.API.checkResponse (putBody, expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t edit non existent setting', function (done) {
|
||||
request.get(testUtils.API.getApiURL('settings'), function (error, response, body) {
|
||||
var jsonResponse = JSON.parse(body),
|
||||
newValue = 'new value';
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.testvalue = newValue;
|
||||
|
||||
request.put({uri: testUtils.API.getApiURL('settings/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: jsonResponse}, function (error, response, putBody) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
testUtils.API.checkResponse (putBody, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
60
core/test/unit/api_tags_spec.js
Normal file
60
core/test/unit/api_tags_spec.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
request = require('request'),
|
||||
expectedProperties = ['id', 'uuid', 'name', 'slug', 'description', 'parent_id',
|
||||
'meta_title', 'meta_description', 'created_at', 'created_by', 'updated_at', 'updated_by'];
|
||||
|
||||
request = request.defaults({jar:true})
|
||||
|
||||
describe('Tag API', function () {
|
||||
|
||||
var user = testUtils.DataGenerator.forModel.users[0],
|
||||
csrfToken = '';
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData()
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
// do a get request to get the CSRF token first
|
||||
request.get(testUtils.API.getSigninURL(), function (error, response, body) {
|
||||
var pattern_meta = /<meta.*?name="csrf-param".*?content="(.*?)".*?>/i;
|
||||
pattern_meta.should.exist;
|
||||
csrfToken = body.match(pattern_meta)[1];
|
||||
request.post({uri:testUtils.API.getSigninURL(),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
done();
|
||||
}).form({email: user.email, password: user.password});
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can retrieve all tags', function (done) {
|
||||
request.get(testUtils.API.getApiURL('tags/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.should.have.length(5);
|
||||
testUtils.API.checkResponse (jsonResponse[0], expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
106
core/test/unit/api_users_spec.js
Normal file
106
core/test/unit/api_users_spec.js
Normal file
@ -0,0 +1,106 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it */
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
_ = require('underscore'),
|
||||
request = require('request'),
|
||||
expectedProperties = ['id', 'uuid', 'name', 'slug', 'email', 'image', 'cover', 'bio', 'website',
|
||||
'location', 'accessibility', 'status', 'language', 'meta_title', 'meta_description',
|
||||
'created_at', 'updated_at'];
|
||||
|
||||
request = request.defaults({jar:true})
|
||||
|
||||
describe('User API', function () {
|
||||
|
||||
var user = testUtils.DataGenerator.forModel.users[0],
|
||||
csrfToken = '';
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData()
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
this.timeout(5000);
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
testUtils.insertDefaultFixtures();
|
||||
})
|
||||
.then(function () {
|
||||
// do a get request to get the CSRF token first
|
||||
request.get(testUtils.API.getSigninURL(), function (error, response, body) {
|
||||
var pattern_meta = /<meta.*?name="csrf-param".*?content="(.*?)".*?>/i;
|
||||
pattern_meta.should.exist;
|
||||
csrfToken = body.match(pattern_meta)[1];
|
||||
request.post({uri:testUtils.API.getSigninURL(),
|
||||
headers: {'X-CSRF-Token': csrfToken}}, function (error, response, body) {
|
||||
done();
|
||||
}).form({email: user.email, password: user.password});
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can retrieve all users', function (done) {
|
||||
request.get(testUtils.API.getApiURL('users/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse[0].should.exist;
|
||||
|
||||
testUtils.API.checkResponse (jsonResponse[0], expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can retrieve a user', function (done) {
|
||||
request.get(testUtils.API.getApiURL('users/me/'), function (error, response, body) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
|
||||
testUtils.API.checkResponse (jsonResponse, expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t retrieve non existent user', function (done) {
|
||||
request.get(testUtils.API.getApiURL('users/99/'), function (error, response, body) {
|
||||
response.should.have.status(404);
|
||||
response.should.be.json;
|
||||
var jsonResponse = JSON.parse(body);
|
||||
jsonResponse.should.exist;
|
||||
|
||||
testUtils.API.checkResponse (jsonResponse, ['error']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can edit a user', function (done) {
|
||||
request.get(testUtils.API.getApiURL('users/me/'), function (error, response, body) {
|
||||
var jsonResponse = JSON.parse(body),
|
||||
changedValue = 'joe-bloggs.ghost.org';
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.website = changedValue;
|
||||
|
||||
request.put({uri: testUtils.API.getApiURL('users/me/'),
|
||||
headers: {'X-CSRF-Token': csrfToken},
|
||||
json: jsonResponse}, function (error, response, putBody) {
|
||||
response.should.have.status(200);
|
||||
response.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.website.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse (putBody, expectedProperties);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/*globals describe, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
|
||||
// Stuff we are testing
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*globals describe, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
|
||||
// Stuff we are testing
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, beforeEach, afterEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, beforeEach, afterEach, before, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
_ = require("underscore"),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*globals describe, it */
|
||||
var testUtils = require('./testUtils'),
|
||||
var testUtils = require('./utils'),
|
||||
should = require('should'),
|
||||
|
||||
// Stuff we are testing
|
||||
|
@ -1,118 +1,26 @@
|
||||
var _ = require('underscore'),
|
||||
when = require('when'),
|
||||
http = require('http'),
|
||||
HttpMethods,
|
||||
ApiRouteBase = '/ghost/api/v0.1/';
|
||||
url = require('url'),
|
||||
ApiRouteBase = '/ghost/api/v0.1/',
|
||||
host = 'localhost',
|
||||
port = '2369';
|
||||
schema = "http://"
|
||||
|
||||
HttpMethods = {
|
||||
GET: 'GET',
|
||||
POST: 'POST',
|
||||
PUT: 'PUT',
|
||||
DELETE: 'DELETE'
|
||||
};
|
||||
|
||||
function createRequest(httpMethod, overrides) {
|
||||
return _.defaults(overrides, {
|
||||
'host': 'localhost',
|
||||
'port': '2369',
|
||||
'method': httpMethod
|
||||
});
|
||||
function getApiURL (route) {
|
||||
var baseURL = url.resolve(schema + host + ':' + port, ApiRouteBase);
|
||||
return url.resolve(baseURL, route);
|
||||
}
|
||||
function getSigninURL () {
|
||||
return url.resolve(schema + host + ':' + port, 'ghost/signin/');
|
||||
}
|
||||
|
||||
function post(route, data, authCookie) {
|
||||
var jsonData = JSON.stringify(data),
|
||||
options = createRequest(HttpMethods.POST, {
|
||||
path: route,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': jsonData.length
|
||||
}
|
||||
}),
|
||||
req,
|
||||
response = '',
|
||||
deferred = when.defer();
|
||||
|
||||
if (authCookie) {
|
||||
options.headers['Cookie'] = authCookie;
|
||||
// make sure the API only returns expected properties only
|
||||
function checkResponse (jsonResponse, expectedProperties) {
|
||||
Object.keys(jsonResponse).length.should.eql(expectedProperties.length);
|
||||
for(var i=0; i<expectedProperties.length; i = i + 1) {
|
||||
jsonResponse.should.have.property(expectedProperties[i]);
|
||||
}
|
||||
|
||||
req = http.request(options, function (res) {
|
||||
res.setEncoding('utf-8');
|
||||
|
||||
if (res.statusCode === 401) {
|
||||
return deferred.resolver.reject(new Error('401 Unauthorized.'));
|
||||
}
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
deferred.resolver.resolve({
|
||||
headers: res.headers,
|
||||
response: JSON.parse(response)
|
||||
});
|
||||
});
|
||||
}).on('error', deferred.resolver.reject);
|
||||
|
||||
req.write(jsonData);
|
||||
req.end();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function get(route, authCookie) {
|
||||
var options = createRequest(HttpMethods.GET, {
|
||||
path: route,
|
||||
headers: {}
|
||||
}),
|
||||
response = '',
|
||||
deferred = when.defer();
|
||||
|
||||
if (authCookie) {
|
||||
options.headers['Cookie'] = authCookie;
|
||||
}
|
||||
|
||||
http.get(options, function (res) {
|
||||
res.setEncoding('utf-8');
|
||||
|
||||
if (res.statusCode === 401) {
|
||||
return deferred.resolver.reject(new Error('401 Unauthorized.'));
|
||||
}
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
deferred.resolve({
|
||||
headers: res.headers,
|
||||
response: JSON.parse(response)
|
||||
});
|
||||
});
|
||||
}).on('error', deferred.resolver.reject);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function login(email, password) {
|
||||
var data = {
|
||||
email: email,
|
||||
password: password
|
||||
};
|
||||
|
||||
return post('/ghost/signin/', data).then(function (response) {
|
||||
return response.headers['set-cookie'];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HttpMethods: HttpMethods,
|
||||
ApiRouteBase: ApiRouteBase,
|
||||
|
||||
createRequest: createRequest,
|
||||
post: post,
|
||||
get: get,
|
||||
|
||||
login: login
|
||||
};
|
||||
module.exports.getApiURL = getApiURL;
|
||||
module.exports.getSigninURL = getSigninURL;
|
||||
module.exports.checkResponse = checkResponse;
|
||||
|
@ -1,9 +1,9 @@
|
||||
var knex = require('../../server/models/base').knex,
|
||||
var knex = require('../../../server/models/base').knex,
|
||||
when = require('when'),
|
||||
migration = require("../../server/data/migration/"),
|
||||
Settings = require('../../server/models/settings').Settings,
|
||||
DataGenerator = require('./fixtures/data-generator'),
|
||||
API = require('./utils/api');
|
||||
migration = require("../../../server/data/migration/"),
|
||||
Settings = require('../../../server/models/settings').Settings,
|
||||
DataGenerator = require('../fixtures/data-generator'),
|
||||
API = require('./api');
|
||||
|
||||
function initData() {
|
||||
return migration.init();
|
@ -73,6 +73,7 @@
|
||||
"matchdep": "~0.3.0",
|
||||
"mocha": "~1.13.0",
|
||||
"should": "~2.0.2",
|
||||
"sinon": "~1.7.3"
|
||||
"sinon": "~1.7.3",
|
||||
"request": "~2.27.0"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user