mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-13 22:41:32 -05:00
Merge pull request #2596 from sebgie/issue#2580-move-obj
Move post API to primary document format
This commit is contained in:
commit
b89727a573
11 changed files with 191 additions and 164 deletions
|
@ -1,4 +1,4 @@
|
|||
/*global Ghost, _, Backbone */
|
||||
/*global Ghost, _, Backbone, JSON */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
@ -11,6 +11,10 @@
|
|||
blacklist: ['published', 'draft'],
|
||||
|
||||
parse: function (resp) {
|
||||
|
||||
if (resp.posts) {
|
||||
resp = resp.posts[0];
|
||||
}
|
||||
if (resp.status) {
|
||||
resp.published = resp.status === 'published';
|
||||
resp.draft = resp.status === 'draft';
|
||||
|
@ -39,6 +43,15 @@
|
|||
return tag.id === tagToRemove.id || tag.name === tagToRemove.name;
|
||||
});
|
||||
this.set('tags', tags);
|
||||
},
|
||||
sync: function (method, model, options) {
|
||||
//wrap post in {posts: [{...}]}
|
||||
if (method === 'create' || method === 'update') {
|
||||
options.data = JSON.stringify({posts: [this.attributes]});
|
||||
options.contentType = 'application/json';
|
||||
}
|
||||
|
||||
return Backbone.Model.prototype.sync.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ function cacheInvalidationHeader(req, result) {
|
|||
cacheInvalidate = '/*';
|
||||
} else if (endpoint === 'posts') {
|
||||
cacheInvalidate = '/, /page/*, /rss/, /rss/*, /tag/*';
|
||||
if (id && jsonResult.slug) {
|
||||
return config.urlForPost(settings, jsonResult).then(function (postUrl) {
|
||||
if (id && jsonResult.posts[0].slug) {
|
||||
return config.urlForPost(settings, jsonResult.posts[0]).then(function (postUrl) {
|
||||
return cacheInvalidate + ', ' + postUrl;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,10 +5,17 @@ var when = require('when'),
|
|||
filteredUserAttributes = require('./users').filteredAttributes,
|
||||
posts;
|
||||
|
||||
function checkPostData(postData) {
|
||||
if (_.isEmpty(postData) || _.isEmpty(postData.posts) || _.isEmpty(postData.posts[0])) {
|
||||
return when.reject({code: 400, message: 'No root key (\'posts\') provided.'});
|
||||
}
|
||||
return when.resolve(postData);
|
||||
}
|
||||
|
||||
// ## Posts
|
||||
posts = {
|
||||
// #### Browse
|
||||
|
||||
// #### Browse
|
||||
// **takes:** filter / pagination parameters
|
||||
browse: function browse(options) {
|
||||
options = options || {};
|
||||
|
@ -21,14 +28,12 @@ posts = {
|
|||
|
||||
for (i = 0; i < omitted.posts.length; i = i + 1) {
|
||||
omitted.posts[i].author = _.omit(omitted.posts[i].author, filteredUserAttributes);
|
||||
omitted.posts[i].user = _.omit(omitted.posts[i].user, filteredUserAttributes);
|
||||
}
|
||||
return omitted;
|
||||
});
|
||||
},
|
||||
|
||||
// #### Read
|
||||
|
||||
// **takes:** an identifier (id or slug?)
|
||||
read: function read(args) {
|
||||
// **returns:** a promise for a single post in a json object
|
||||
|
@ -39,8 +44,7 @@ posts = {
|
|||
if (result) {
|
||||
omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
omitted.user = _.omit(omitted.user, filteredUserAttributes);
|
||||
return omitted;
|
||||
return { posts: [ omitted ]};
|
||||
}
|
||||
return when.reject({code: 404, message: 'Post not found'});
|
||||
|
||||
|
@ -57,7 +61,6 @@ posts = {
|
|||
},
|
||||
|
||||
// #### Edit
|
||||
|
||||
// **takes:** a json object with all the properties which should be updated
|
||||
edit: function edit(postData) {
|
||||
// **returns:** a promise for the resulting post in a json object
|
||||
|
@ -66,21 +69,15 @@ posts = {
|
|||
}
|
||||
var self = this;
|
||||
return canThis(self.user).edit.post(postData.id).then(function () {
|
||||
return dataProvider.Post.edit(postData).then(function (result) {
|
||||
return checkPostData(postData).then(function (checkedPostData) {
|
||||
return dataProvider.Post.edit(checkedPostData.posts[0]);
|
||||
}).then(function (result) {
|
||||
if (result) {
|
||||
var omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
omitted.user = _.omit(omitted.user, filteredUserAttributes);
|
||||
return omitted;
|
||||
return { posts: [ omitted ]};
|
||||
}
|
||||
return when.reject({code: 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({code: 404, message: 'Post not found'});
|
||||
}
|
||||
return when.reject({message: error.message});
|
||||
});
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({code: 403, message: 'You do not have permission to edit this post.'});
|
||||
|
@ -88,7 +85,6 @@ posts = {
|
|||
},
|
||||
|
||||
// #### Add
|
||||
|
||||
// **takes:** a json object representing a post,
|
||||
add: function add(postData) {
|
||||
// **returns:** a promise for the resulting post in a json object
|
||||
|
@ -97,14 +93,19 @@ posts = {
|
|||
}
|
||||
|
||||
return canThis(this.user).create.post().then(function () {
|
||||
return dataProvider.Post.add(postData);
|
||||
return checkPostData(postData).then(function (checkedPostData) {
|
||||
return dataProvider.Post.add(checkedPostData.posts[0]);
|
||||
}).then(function (result) {
|
||||
var omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
return { posts: [ omitted ]};
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({code: 403, message: 'You do not have permission to add posts.'});
|
||||
});
|
||||
},
|
||||
|
||||
// #### Destroy
|
||||
|
||||
// **takes:** an identifier (id or slug?)
|
||||
destroy: function destroy(args) {
|
||||
// **returns:** a promise for a json response with the id of the deleted post
|
||||
|
@ -113,7 +114,7 @@ posts = {
|
|||
}
|
||||
|
||||
return canThis(this.user).remove.post(args.id).then(function () {
|
||||
return when(posts.read({id : args.id, status: 'all'})).then(function (result) {
|
||||
return posts.read({id : args.id, status: 'all'}).then(function (result) {
|
||||
return dataProvider.Post.destroy(args.id).then(function () {
|
||||
var deletedObj = result;
|
||||
return deletedObj;
|
||||
|
|
|
@ -172,7 +172,10 @@ frontendControllers = {
|
|||
|
||||
// Query database to find post
|
||||
return api.posts.read(postLookup);
|
||||
}).then(function (post) {
|
||||
}).then(function (result) {
|
||||
var post = result.posts[0],
|
||||
slugDate = [],
|
||||
slugFormat = [];
|
||||
|
||||
if (!post) {
|
||||
return next();
|
||||
|
@ -208,9 +211,6 @@ frontendControllers = {
|
|||
// we will check it against the post published date
|
||||
// to verify it's correct.
|
||||
if (params.year || params.month || params.day) {
|
||||
var slugDate = [],
|
||||
slugFormat = [];
|
||||
|
||||
if (params.year) {
|
||||
slugDate.push(params.year);
|
||||
slugFormat.push('YYYY');
|
||||
|
|
|
@ -149,7 +149,9 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
|||
edit: function (editedObj, options) {
|
||||
options = options || {};
|
||||
return this.forge({id: editedObj.id}).fetch(options).then(function (foundObj) {
|
||||
return foundObj.save(editedObj, options);
|
||||
if (foundObj) {
|
||||
return foundObj.save(editedObj, options);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -192,10 +192,6 @@ Post = ghostBookshelf.Model.extend({
|
|||
},
|
||||
|
||||
// Relations
|
||||
user: function () {
|
||||
return this.belongsTo(User, 'created_by');
|
||||
},
|
||||
|
||||
author: function () {
|
||||
return this.belongsTo(User, 'author_id');
|
||||
},
|
||||
|
@ -210,7 +206,7 @@ Post = ghostBookshelf.Model.extend({
|
|||
// Extends base model findAll to eager-fetch author and user relationships.
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
options.withRelated = [ 'author', 'user', 'tags' ];
|
||||
options.withRelated = [ 'author', 'tags' ];
|
||||
return ghostBookshelf.Model.findAll.call(this, options);
|
||||
},
|
||||
|
||||
|
@ -227,7 +223,7 @@ Post = ghostBookshelf.Model.extend({
|
|||
delete args.status;
|
||||
}
|
||||
|
||||
options.withRelated = [ 'author', 'user', 'tags' ];
|
||||
options.withRelated = [ 'author', 'tags' ];
|
||||
return ghostBookshelf.Model.findOne.call(this, args, options);
|
||||
},
|
||||
|
||||
|
@ -293,7 +289,7 @@ Post = ghostBookshelf.Model.extend({
|
|||
}
|
||||
|
||||
// Fetch related models
|
||||
opts.withRelated = [ 'author', 'user', 'tags' ];
|
||||
opts.withRelated = [ 'author', 'tags' ];
|
||||
|
||||
// If a query param for a tag is attached
|
||||
// we need to fetch the tag model to find its id
|
||||
|
@ -439,7 +435,9 @@ Post = ghostBookshelf.Model.extend({
|
|||
var self = this;
|
||||
|
||||
return ghostBookshelf.Model.edit.call(this, editedPost, options).then(function (post) {
|
||||
return self.findOne({status: 'all', id: post.id}, options);
|
||||
if (post) {
|
||||
return self.findOne({status: 'all', id: post.id}, options);
|
||||
}
|
||||
});
|
||||
},
|
||||
destroy: function (_identifier, options) {
|
||||
|
|
|
@ -198,8 +198,9 @@ describe('Post API', function () {
|
|||
res.should.be.json;
|
||||
var jsonResponse = res.body;
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse, 'post');
|
||||
jsonResponse.page.should.eql(0);
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
jsonResponse.posts[0].page.should.eql(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -216,8 +217,9 @@ describe('Post API', function () {
|
|||
res.should.be.json;
|
||||
var jsonResponse = res.body;
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse, 'post');
|
||||
jsonResponse.page.should.eql(1);
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
jsonResponse.posts[0].page.should.eql(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -281,7 +283,7 @@ describe('Post API', function () {
|
|||
var newTitle = 'My Post',
|
||||
changedTitle = 'My Post changed',
|
||||
publishedState = 'published',
|
||||
newPost = {status: 'draft', title: newTitle, markdown: 'my post'};
|
||||
newPost = {posts: [{status: 'draft', title: newTitle, markdown: 'my post'}]};
|
||||
|
||||
request.post(testUtils.API.getApiQuery('posts/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
|
@ -294,12 +296,12 @@ describe('Post API', function () {
|
|||
|
||||
res.should.be.json;
|
||||
var draftPost = res.body;
|
||||
draftPost.should.exist;
|
||||
draftPost.title.should.eql(newTitle);
|
||||
draftPost.status = publishedState;
|
||||
testUtils.API.checkResponse(draftPost, 'post');
|
||||
draftPost.posts.should.exist;
|
||||
draftPost.posts[0].title.should.eql(newTitle);
|
||||
draftPost.posts[0].status = publishedState;
|
||||
testUtils.API.checkResponse(draftPost.posts[0], 'post');
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/' + draftPost.id + '/'))
|
||||
request.put(testUtils.API.getApiQuery('posts/' + draftPost.posts[0].id + '/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
.send(draftPost)
|
||||
.expect(200)
|
||||
|
@ -309,15 +311,15 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var publishedPost = res.body;
|
||||
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + publishedPost.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + publishedPost.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
publishedPost.should.exist;
|
||||
publishedPost.title.should.eql(newTitle);
|
||||
publishedPost.status.should.eql(publishedState);
|
||||
testUtils.API.checkResponse(publishedPost, 'post');
|
||||
publishedPost.posts.should.exist;
|
||||
publishedPost.posts[0].title.should.eql(newTitle);
|
||||
publishedPost.posts[0].status.should.eql(publishedState);
|
||||
testUtils.API.checkResponse(publishedPost.posts[0], 'post');
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/' + publishedPost.id + '/'))
|
||||
request.put(testUtils.API.getApiQuery('posts/' + publishedPost.posts[0].id + '/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
.send(publishedPost)
|
||||
.expect(200)
|
||||
|
@ -327,11 +329,12 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var updatedPost = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + updatedPost.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + updatedPost.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
updatedPost.should.exist;
|
||||
updatedPost.title.should.eql(newTitle);
|
||||
testUtils.API.checkResponse(updatedPost, 'post');
|
||||
updatedPost.posts.should.exist;
|
||||
updatedPost.posts[0].title.should.eql(newTitle);
|
||||
testUtils.API.checkResponse(updatedPost.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -352,8 +355,8 @@ describe('Post API', function () {
|
|||
|
||||
var jsonResponse = res.body,
|
||||
changedValue = 'My new Title';
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.title = changedValue;
|
||||
jsonResponse.posts[0].should.exist;
|
||||
jsonResponse.posts[0].title = changedValue;
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/1/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
|
@ -365,12 +368,12 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var putBody = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.title.should.eql(changedValue);
|
||||
putBody.posts[0].title.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse(putBody, 'post');
|
||||
testUtils.API.checkResponse(putBody.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -386,8 +389,8 @@ describe('Post API', function () {
|
|||
var jsonResponse = res.body,
|
||||
changedValue = true;
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.page.should.eql(0);
|
||||
jsonResponse.page = changedValue;
|
||||
jsonResponse.posts[0].page.should.eql(0);
|
||||
jsonResponse.posts[0].page = changedValue;
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/1/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
|
@ -399,12 +402,12 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var putBody = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.page.should.eql(changedValue);
|
||||
putBody.posts[0].page.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse(putBody, 'post');
|
||||
testUtils.API.checkResponse(putBody.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -421,8 +424,8 @@ describe('Post API', function () {
|
|||
var jsonResponse = res.body,
|
||||
changedValue = false;
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.page.should.eql(1);
|
||||
jsonResponse.page = changedValue;
|
||||
jsonResponse.posts[0].page.should.eql(1);
|
||||
jsonResponse.posts[0].page = changedValue;
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/1/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
|
@ -434,12 +437,12 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var putBody = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.page.should.eql(changedValue);
|
||||
putBody.posts[0].page.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse(putBody, 'post');
|
||||
testUtils.API.checkResponse(putBody.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -490,15 +493,16 @@ describe('Post API', function () {
|
|||
}
|
||||
|
||||
var putBody = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.slug + '/');
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + putBody.posts[0].slug + '/');
|
||||
res.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.title.should.eql(changedValue);
|
||||
if (_.isEmpty(putBody.published_at)) {
|
||||
putBody.posts.should.exist;
|
||||
putBody.posts[0].title.should.eql(changedValue);
|
||||
if (_.isEmpty(putBody.posts[0].published_at)) {
|
||||
should.fail('null', 'valid date', 'publish_at should not be empty');
|
||||
done();
|
||||
}
|
||||
testUtils.API.checkResponse(putBody, 'post');
|
||||
testUtils.API.checkResponse(putBody.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -517,9 +521,9 @@ describe('Post API', function () {
|
|||
|
||||
var jsonResponse = res.body,
|
||||
changedValue = 'My new Title';
|
||||
jsonResponse.title.exist;
|
||||
jsonResponse.testvalue = changedValue;
|
||||
jsonResponse.id = 99;
|
||||
jsonResponse.posts[0].title.exist;
|
||||
jsonResponse.posts[0].testvalue = changedValue;
|
||||
jsonResponse.posts[0].id = 99;
|
||||
request.put(testUtils.API.getApiQuery('posts/99/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
.send(jsonResponse)
|
||||
|
@ -551,9 +555,10 @@ describe('Post API', function () {
|
|||
res.should.be.json;
|
||||
var jsonResponse = res.body;
|
||||
jsonResponse.should.exist;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + jsonResponse.slug + '/');
|
||||
testUtils.API.checkResponse(jsonResponse, 'post');
|
||||
jsonResponse.id.should.eql(deletePostId);
|
||||
jsonResponse.posts.should.exist;
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, /' + jsonResponse.posts[0].slug + '/');
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
jsonResponse.posts[0].id.should.eql(deletePostId);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -579,13 +584,15 @@ describe('Post API', function () {
|
|||
it('can delete a new draft', function (done) {
|
||||
var newTitle = 'My Post',
|
||||
publishedState = 'draft',
|
||||
newPost = {status: publishedState, title: newTitle, markdown: 'my post'};
|
||||
newPost = {posts: [{status: publishedState, title: newTitle, markdown: 'my post'}]};
|
||||
|
||||
request.post(testUtils.API.getApiQuery('posts/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
.send(newPost)
|
||||
.expect(200)
|
||||
.end(function (err ,res) {
|
||||
console.log("end");
|
||||
console.log(err);
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
@ -594,11 +601,11 @@ describe('Post API', function () {
|
|||
|
||||
res.should.be.json;
|
||||
draftPost.should.exist;
|
||||
draftPost.title.should.eql(newTitle);
|
||||
draftPost.status = publishedState;
|
||||
testUtils.API.checkResponse(draftPost, 'post');
|
||||
draftPost.posts[0].title.should.eql(newTitle);
|
||||
draftPost.posts[0].status = publishedState;
|
||||
testUtils.API.checkResponse(draftPost.posts[0], 'post');
|
||||
|
||||
request.del(testUtils.API.getApiQuery('posts/' + draftPost.id + '/'))
|
||||
request.del(testUtils.API.getApiQuery('posts/' + draftPost.posts[0].id + '/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
|
@ -609,7 +616,8 @@ describe('Post API', function () {
|
|||
res.should.be.json;
|
||||
var jsonResponse = res.body
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse, 'post');
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -677,9 +685,10 @@ describe('Post API', function () {
|
|||
|
||||
var jsonResponse = res.body;
|
||||
jsonResponse.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse, 'post');
|
||||
jsonResponse.slug.should.not.match(/^\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}/);
|
||||
jsonResponse.page.should.eql(0);
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
jsonResponse.posts[0].slug.should.not.match(/^\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}/);
|
||||
jsonResponse.posts[0].page.should.eql(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -694,7 +703,8 @@ describe('Post API', function () {
|
|||
var jsonResponse = res.body,
|
||||
changedValue = 'My new Title';
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.title = changedValue;
|
||||
jsonResponse.posts.should.exist;
|
||||
jsonResponse.posts[0].title = changedValue;
|
||||
|
||||
request.put(testUtils.API.getApiQuery('posts/2/'))
|
||||
.set('X-CSRF-Token', csrfToken)
|
||||
|
@ -709,14 +719,14 @@ describe('Post API', function () {
|
|||
dd = ("0" + today.getDate()).slice(-2),
|
||||
mm = ("0" + (today.getMonth() + 1)).slice(-2),
|
||||
yyyy = today.getFullYear(),
|
||||
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/' + putBody.slug + '/';
|
||||
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/' + putBody.posts[0].slug + '/';
|
||||
|
||||
res.headers['x-cache-invalidate'].should.eql('/, /page/*, /rss/, /rss/*, /tag/*, ' + postLink);
|
||||
res.should.be.json;
|
||||
putBody.should.exist;
|
||||
putBody.title.should.eql(changedValue);
|
||||
putBody.posts[0].title.should.eql(changedValue);
|
||||
|
||||
testUtils.API.checkResponse(putBody, 'post');
|
||||
testUtils.API.checkResponse(putBody.posts[0], 'post');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ describe('Post API', function () {
|
|||
return PostAPI.read({slug: firstPost.slug});
|
||||
}).then(function (found) {
|
||||
should.exist(found);
|
||||
testUtils.API.checkResponse(found, 'post');
|
||||
testUtils.API.checkResponse(found.posts[0], 'post');
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
|
|
@ -75,9 +75,7 @@ describe('Post Model', function () {
|
|||
firstPost = results.models[0].toJSON();
|
||||
|
||||
firstPost.author.should.be.an.Object;
|
||||
firstPost.user.should.be.an.Object;
|
||||
firstPost.author.name.should.equal(DataGenerator.Content.users[0].name);
|
||||
firstPost.user.name.should.equal(DataGenerator.Content.users[0].name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
|
@ -91,9 +89,7 @@ describe('Post Model', function () {
|
|||
firstPost = result.toJSON();
|
||||
|
||||
firstPost.author.should.be.an.Object;
|
||||
firstPost.user.should.be.an.Object;
|
||||
firstPost.author.name.should.equal(testUtils.DataGenerator.Content.users[0].name);
|
||||
firstPost.user.name.should.equal(testUtils.DataGenerator.Content.users[0].name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
|
|
|
@ -360,29 +360,35 @@ describe('Frontend Controller', function () {
|
|||
|
||||
describe('single', function () {
|
||||
var mockPosts = [{
|
||||
'status': 'published',
|
||||
'id': 1,
|
||||
'title': 'Test static page',
|
||||
'slug': 'test-static-page',
|
||||
'markdown': 'Test static page content',
|
||||
'page': 1,
|
||||
'published_at': new Date('2013/12/30').getTime()
|
||||
'posts': [{
|
||||
'status': 'published',
|
||||
'id': 1,
|
||||
'title': 'Test static page',
|
||||
'slug': 'test-static-page',
|
||||
'markdown': 'Test static page content',
|
||||
'page': 1,
|
||||
'published_at': new Date('2013/12/30').getTime()
|
||||
}]
|
||||
}, {
|
||||
'status': 'published',
|
||||
'id': 2,
|
||||
'title': 'Test normal post',
|
||||
'slug': 'test-normal-post',
|
||||
'markdown': 'The test normal post content',
|
||||
'page': 0,
|
||||
'published_at': new Date('2014/1/2').getTime()
|
||||
'posts': [{
|
||||
'status': 'published',
|
||||
'id': 2,
|
||||
'title': 'Test normal post',
|
||||
'slug': 'test-normal-post',
|
||||
'markdown': 'The test normal post content',
|
||||
'page': 0,
|
||||
'published_at': new Date('2014/1/2').getTime()
|
||||
}]
|
||||
}, {
|
||||
'status': 'published',
|
||||
'id': 3,
|
||||
'title': 'About',
|
||||
'slug': 'about',
|
||||
'markdown': 'This is the about page content',
|
||||
'page': 1,
|
||||
'published_at': new Date('2014/1/30').getTime()
|
||||
'posts': [{
|
||||
'status': 'published',
|
||||
'id': 3,
|
||||
'title': 'About',
|
||||
'slug': 'about',
|
||||
'markdown': 'This is the about page content',
|
||||
'page': 1,
|
||||
'published_at': new Date('2014/1/30').getTime()
|
||||
}]
|
||||
}],
|
||||
// Helper function to prevent unit tests
|
||||
// from failing via timeout when they
|
||||
|
@ -395,7 +401,9 @@ describe('Frontend Controller', function () {
|
|||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(api.posts, 'read', function (args) {
|
||||
return when(_.find(mockPosts, args));
|
||||
return when(_.find(mockPosts, function(mock) {
|
||||
return mock.posts[0].slug === args.slug;
|
||||
}));
|
||||
});
|
||||
|
||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||
|
@ -433,16 +441,15 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('it will render custom page template if it exists', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[2].slug
|
||||
path: '/' + mockPosts[2].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page-' + mockPosts[2].slug);
|
||||
assert.equal(context.post, mockPosts[2]);
|
||||
assert.equal(view, 'page-' + mockPosts[2].posts[0].slug);
|
||||
assert.equal(context.post, mockPosts[2].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
frontend.single(req, res, failTest(done));
|
||||
});
|
||||
});
|
||||
|
@ -456,12 +463,12 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will render static page via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[0].slug
|
||||
path: '/' + mockPosts[0].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockPosts[0]);
|
||||
assert.equal(context.post, mockPosts[0].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -471,7 +478,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT render static page via /YYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[0].slug].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[0].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -485,13 +492,13 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will redirect static page to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPosts[0].slug, 'edit'].join('/')
|
||||
path: '/' + [mockPosts[0].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPosts[0].id + '/');
|
||||
arg.should.eql(adminEditPagePath + mockPosts[0].posts[0].id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -501,7 +508,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[0].slug, 'edit'].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[0].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
|
@ -525,12 +532,12 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will render static page via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[0].slug
|
||||
path: '/' + mockPosts[0].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'page');
|
||||
assert.equal(context.post, mockPosts[0]);
|
||||
assert.equal(context.post, mockPosts[0].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -540,7 +547,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT render static page via /YYYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[0].slug].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[0].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -554,13 +561,13 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will redirect static page to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPosts[0].slug, 'edit'].join('/')
|
||||
path: '/' + [mockPosts[0].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPosts[0].id + '/');
|
||||
arg.should.eql(adminEditPagePath + mockPosts[0].posts[0].id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -570,7 +577,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT redirect static page to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[0].slug, 'edit'].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[0].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
|
@ -596,13 +603,13 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[1].slug
|
||||
path: '/' + mockPosts[1].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPosts[1]);
|
||||
assert.equal(context.post, mockPosts[1].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -612,7 +619,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[1].slug].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -627,13 +634,13 @@ describe('Frontend Controller', function () {
|
|||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + [mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function(arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].id + '/');
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].posts[0].id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -643,7 +650,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT redirect post to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + ['2012/12/30', mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + ['2012/12/30', mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
|
@ -666,15 +673,15 @@ describe('Frontend Controller', function () {
|
|||
});
|
||||
|
||||
it('will render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).format('YYYY/MM/DD'),
|
||||
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPosts[1]);
|
||||
assert.equal(context.post, mockPosts[1].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -685,7 +692,7 @@ describe('Frontend Controller', function () {
|
|||
it('will NOT render post via /YYYY/MM/DD/:slug with non-matching date in url', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).subtract('days', 1).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -699,7 +706,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[1].slug
|
||||
path: '/' + mockPosts[1].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -713,15 +720,15 @@ describe('Frontend Controller', function () {
|
|||
|
||||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /YYYY/MM/DD/:slug/edit', function (done) {
|
||||
var dateFormat = moment(mockPosts[1].published_at).format('YYYY/MM/DD'),
|
||||
var dateFormat = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [dateFormat, mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + [dateFormat, mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].id + '/');
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].posts[0].id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -731,7 +738,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT redirect post to admin edit page via /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + [mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
|
@ -754,15 +761,15 @@ describe('Frontend Controller', function () {
|
|||
});
|
||||
|
||||
it('will render post via /:year/:slug', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).format('YYYY'),
|
||||
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: function (view, context) {
|
||||
assert.equal(view, 'post');
|
||||
assert(context.post, 'Context object has post attribute');
|
||||
assert.equal(context.post, mockPosts[1]);
|
||||
assert.equal(context.post, mockPosts[1].posts[0]);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -771,9 +778,9 @@ describe('Frontend Controller', function () {
|
|||
});
|
||||
|
||||
it('will NOT render post via /YYYY/MM/DD/:slug', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).format('YYYY/MM/DD'),
|
||||
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY/MM/DD'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -786,9 +793,9 @@ describe('Frontend Controller', function () {
|
|||
});
|
||||
|
||||
it('will NOT render post via /:year/slug when year does not match post year', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).subtract('years', 1).format('YYYY'),
|
||||
var date = moment(mockPosts[1].posts[0].published_at).subtract('years', 1).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -802,7 +809,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT render post via /:slug', function (done) {
|
||||
var req = {
|
||||
path: '/' + mockPosts[1].slug
|
||||
path: '/' + mockPosts[1].posts[0].slug
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy()
|
||||
|
@ -816,15 +823,15 @@ describe('Frontend Controller', function () {
|
|||
|
||||
// Handle Edit append
|
||||
it('will redirect post to admin edit page via /:year/:slug/edit', function (done) {
|
||||
var date = moment(mockPosts[1].published_at).format('YYYY'),
|
||||
var date = moment(mockPosts[1].posts[0].published_at).format('YYYY'),
|
||||
req = {
|
||||
path: '/' + [date, mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + [date, mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
redirect: function (arg) {
|
||||
res.render.called.should.be.false;
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].id + '/');
|
||||
arg.should.eql(adminEditPagePath + mockPosts[1].posts[0].id + '/');
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
@ -834,7 +841,7 @@ describe('Frontend Controller', function () {
|
|||
|
||||
it('will NOT redirect post to admin edit page /:slug/edit', function (done) {
|
||||
var req = {
|
||||
path: '/' + [mockPosts[1].slug, 'edit'].join('/')
|
||||
path: '/' + [mockPosts[1].posts[0].slug, 'edit'].join('/')
|
||||
},
|
||||
res = {
|
||||
render: sinon.spy(),
|
||||
|
|
|
@ -8,7 +8,7 @@ var _ = require('lodash'),
|
|||
posts: ['posts', 'page', 'limit', 'pages', 'total'],
|
||||
post: ['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'],
|
||||
'updated_by', 'published_at', 'published_by', 'page', 'author', 'tags'],
|
||||
// TODO: remove databaseVersion, dbHash
|
||||
settings: ['databaseVersion', 'dbHash', 'title', 'description', 'email', 'logo', 'cover', 'defaultLang',
|
||||
"permalinks", 'postsPerPage', 'forceI18n', 'activeTheme', 'activeApps', 'installedApps',
|
||||
|
|
Loading…
Add table
Reference in a new issue