mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-01 23:37:43 +03:00
Add include parameter for posts API
closes #2609 - added include parameter to api.posts.* - changed toJSON to omit objects that are not included - added include parameter to admin - added include parameter to frontend.js - updated tests - removed duplicate code from posts model **Known Issue:** It is not possible to attach a tag using an ID.
This commit is contained in:
parent
d089ddfe87
commit
1e62400465
@ -49,6 +49,7 @@
|
||||
if (method === 'create' || method === 'update') {
|
||||
options.data = JSON.stringify({posts: [this.attributes]});
|
||||
options.contentType = 'application/json';
|
||||
options.url = model.url() + '?include=tags';
|
||||
}
|
||||
|
||||
return Backbone.Model.prototype.sync.apply(this, arguments);
|
||||
|
@ -3,7 +3,7 @@
|
||||
'use strict';
|
||||
|
||||
Ghost.Models.Themes = Backbone.Model.extend({
|
||||
url: Ghost.paths.apiRoot + '/themes'
|
||||
url: Ghost.paths.apiRoot + '/themes/'
|
||||
});
|
||||
|
||||
}());
|
||||
|
@ -36,7 +36,7 @@
|
||||
blog: function () {
|
||||
var posts = new Ghost.Collections.Posts();
|
||||
NProgress.start();
|
||||
posts.fetch({ data: { status: 'all', staticPages: 'all'} }).then(function () {
|
||||
posts.fetch({ data: { status: 'all', staticPages: 'all', include: 'author'} }).then(function () {
|
||||
Ghost.currentView = new Ghost.Views.Blog({ el: '#main', collection: posts });
|
||||
NProgress.done();
|
||||
});
|
||||
@ -63,7 +63,7 @@
|
||||
post.urlRoot = Ghost.paths.apiRoot + '/posts';
|
||||
if (id) {
|
||||
post.id = id;
|
||||
post.fetch({ data: {status: 'all'}}).then(function () {
|
||||
post.fetch({ data: {status: 'all', include: 'tags'}}).then(function () {
|
||||
Ghost.currentView = new Ghost.Views.Editor({ el: '#main', model: post });
|
||||
});
|
||||
} else {
|
||||
|
@ -3,7 +3,9 @@ var when = require('when'),
|
||||
dataProvider = require('../models'),
|
||||
canThis = require('../permissions').canThis,
|
||||
filteredUserAttributes = require('./users').filteredAttributes,
|
||||
posts;
|
||||
|
||||
posts,
|
||||
allowedIncludes = ['created_by', 'updated_by', 'published_by', 'author', 'tags', 'fields'];
|
||||
|
||||
function checkPostData(postData) {
|
||||
if (_.isEmpty(postData) || _.isEmpty(postData.posts) || _.isEmpty(postData.posts[0])) {
|
||||
@ -12,6 +14,19 @@ function checkPostData(postData) {
|
||||
return when.resolve(postData);
|
||||
}
|
||||
|
||||
function prepareInclude(include) {
|
||||
var index;
|
||||
|
||||
include = _.intersection(include.split(","), allowedIncludes);
|
||||
index = include.indexOf('author');
|
||||
|
||||
if (index !== -1) {
|
||||
include[index] = 'author_id';
|
||||
}
|
||||
|
||||
return include;
|
||||
}
|
||||
|
||||
// ## Posts
|
||||
posts = {
|
||||
|
||||
@ -24,13 +39,20 @@ posts = {
|
||||
if (!this.user) {
|
||||
options.status = 'published';
|
||||
}
|
||||
|
||||
if (options.include) {
|
||||
options.include = prepareInclude(options.include);
|
||||
}
|
||||
|
||||
// **returns:** a promise for a page of posts in a json object
|
||||
return dataProvider.Post.findPage(options).then(function (result) {
|
||||
var i = 0,
|
||||
omitted = result;
|
||||
|
||||
for (i = 0; i < omitted.posts.length; i = i + 1) {
|
||||
omitted.posts[i].author = _.omit(omitted.posts[i].author, filteredUserAttributes);
|
||||
if (!_.isNumber(omitted.posts[i].author)) {
|
||||
omitted.posts[i].author = _.omit(omitted.posts[i].author, filteredUserAttributes);
|
||||
}
|
||||
}
|
||||
return omitted;
|
||||
});
|
||||
@ -39,6 +61,7 @@ posts = {
|
||||
// #### Read
|
||||
// **takes:** an identifier (id or slug?)
|
||||
read: function read(options) {
|
||||
var include;
|
||||
options = options || {};
|
||||
|
||||
// only published posts if no user is present
|
||||
@ -46,15 +69,23 @@ posts = {
|
||||
options.status = 'published';
|
||||
}
|
||||
|
||||
if (options.include) {
|
||||
include = prepareInclude(options.include);
|
||||
delete options.include;
|
||||
}
|
||||
|
||||
// **returns:** a promise for a single post in a json object
|
||||
return dataProvider.Post.findOne(options).then(function (result) {
|
||||
return dataProvider.Post.findOne(options, {include: include}).then(function (result) {
|
||||
var omitted;
|
||||
|
||||
if (result) {
|
||||
omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
if (!_.isNumber(omitted.author)) {
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
}
|
||||
return { posts: [ omitted ]};
|
||||
}
|
||||
|
||||
return when.reject({code: 404, message: 'Post not found'});
|
||||
|
||||
});
|
||||
@ -64,21 +95,30 @@ posts = {
|
||||
// **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
|
||||
var self = this;
|
||||
var self = this,
|
||||
include;
|
||||
|
||||
return canThis(self.user).edit.post(postData.id).then(function () {
|
||||
return checkPostData(postData).then(function (checkedPostData) {
|
||||
return dataProvider.Post.edit(checkedPostData.posts[0], {user: self.user});
|
||||
|
||||
if (postData.include) {
|
||||
include = prepareInclude(postData.include);
|
||||
}
|
||||
|
||||
return dataProvider.Post.edit(checkedPostData.posts[0], {user: self.user, include: include});
|
||||
}).then(function (result) {
|
||||
if (result) {
|
||||
var omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
if (!_.isNumber(omitted.author)) {
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
}
|
||||
// If previously was not published and now is, signal the change
|
||||
if (result.updated('status') !== result.get('status')) {
|
||||
omitted.statusChanged = true;
|
||||
}
|
||||
return { posts: [ omitted ]};
|
||||
}
|
||||
|
||||
return when.reject({code: 404, message: 'Post not found'});
|
||||
});
|
||||
}, function () {
|
||||
@ -96,7 +136,9 @@ posts = {
|
||||
return dataProvider.Post.add(checkedPostData.posts[0], {user: self.user});
|
||||
}).then(function (result) {
|
||||
var omitted = result.toJSON();
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
if (!_.isNumber(omitted.author)) {
|
||||
omitted.author = _.omit(omitted.author, filteredUserAttributes);
|
||||
}
|
||||
if (omitted.status === 'published') {
|
||||
// When creating a new post that is published right now, signal the change
|
||||
omitted.statusChanged = true;
|
||||
@ -134,7 +176,6 @@ posts = {
|
||||
},
|
||||
|
||||
// #### Generate slug
|
||||
|
||||
// **takes:** a string to generate the slug from
|
||||
generateSlug: function generateSlug(args) {
|
||||
|
||||
|
@ -28,7 +28,7 @@ function getPostPage(options) {
|
||||
if (!isNaN(postsPerPage) && postsPerPage > 0) {
|
||||
options.limit = postsPerPage;
|
||||
}
|
||||
|
||||
options.include = 'author,tags,fields';
|
||||
return api.posts.browse(options);
|
||||
}).then(function (page) {
|
||||
|
||||
@ -162,6 +162,8 @@ frontendControllers = {
|
||||
|
||||
// Sanitize params we're going to use to lookup the post.
|
||||
var postLookup = _.pick(permalink.params, 'slug', 'id');
|
||||
// Add author, tag and fields
|
||||
postLookup.include = 'author,tags,fields';
|
||||
|
||||
// Query database to find post
|
||||
return api.posts.read(postLookup);
|
||||
@ -270,6 +272,8 @@ frontendControllers = {
|
||||
if (pageParam) { options.page = pageParam; }
|
||||
if (tagParam) { options.tag = tagParam; }
|
||||
|
||||
options.include = 'author,tags,fields';
|
||||
|
||||
return api.posts.browse(options).then(function (page) {
|
||||
|
||||
var title = result[0].value.value,
|
||||
|
@ -1,13 +1,13 @@
|
||||
var Bookshelf = require('bookshelf'),
|
||||
when = require('when'),
|
||||
moment = require('moment'),
|
||||
_ = require('lodash'),
|
||||
uuid = require('node-uuid'),
|
||||
config = require('../config'),
|
||||
unidecode = require('unidecode'),
|
||||
sanitize = require('validator').sanitize,
|
||||
schema = require('../data/schema'),
|
||||
validation = require('../data/validation'),
|
||||
var Bookshelf = require('bookshelf'),
|
||||
when = require('when'),
|
||||
moment = require('moment'),
|
||||
_ = require('lodash'),
|
||||
uuid = require('node-uuid'),
|
||||
config = require('../config'),
|
||||
unidecode = require('unidecode'),
|
||||
sanitize = require('validator').sanitize,
|
||||
schema = require('../data/schema'),
|
||||
validation = require('../data/validation'),
|
||||
|
||||
ghostBookshelf;
|
||||
|
||||
@ -15,7 +15,6 @@ var Bookshelf = require('bookshelf'),
|
||||
ghostBookshelf = Bookshelf.ghost = Bookshelf.initialize(config().database);
|
||||
ghostBookshelf.client = config().database.client;
|
||||
|
||||
|
||||
// The Base Model which other Ghost objects will inherit from,
|
||||
// including some convenience functions as static properties on the model.
|
||||
ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
@ -34,7 +33,14 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
var self = this;
|
||||
var self = this,
|
||||
options = arguments[1] || {};
|
||||
|
||||
// make options include available for toJSON()
|
||||
if (options.include) {
|
||||
this.include = _.clone(options.include);
|
||||
}
|
||||
|
||||
this.on('creating', this.creating, this);
|
||||
this.on('saving', function (model, attributes, options) {
|
||||
return when(self.saving(model, attributes, options)).then(function () {
|
||||
@ -98,15 +104,25 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
|
||||
toJSON: function (options) {
|
||||
var attrs = _.extend({}, this.attributes),
|
||||
relations = this.relations;
|
||||
self = this;
|
||||
|
||||
if (options && options.shallow) {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
_.each(relations, function (relation, key) {
|
||||
if (options && options.idOnly) {
|
||||
return attrs.id;
|
||||
}
|
||||
|
||||
_.each(this.relations, function (relation, key) {
|
||||
if (key.substring(0, 7) !== '_pivot_') {
|
||||
attrs[key] = relation.toJSON ? relation.toJSON() : relation;
|
||||
// if include is set, expand to full object
|
||||
// toMany relationships are included with ids if not expanded
|
||||
if (_.contains(self.include, key)) {
|
||||
attrs[key] = relation.toJSON();
|
||||
} else if (relation.hasOwnProperty('length')) {
|
||||
attrs[key] = relation.toJSON({idOnly: true});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -135,7 +151,14 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
*/
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
return ghostBookshelf.Collection.forge([], {model: this}).fetch(options);
|
||||
return ghostBookshelf.Collection.forge([], {model: this}).fetch(options).then(function (result) {
|
||||
if (options.include) {
|
||||
_.each(result.models, function (item) {
|
||||
item.include = options.include;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
});
|
||||
},
|
||||
|
||||
browse: function () {
|
||||
@ -149,7 +172,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
*/
|
||||
findOne: function (args, options) {
|
||||
options = options || {};
|
||||
return this.forge(args).fetch(options);
|
||||
return this.forge(args, {include: options.include}).fetch(options);
|
||||
},
|
||||
|
||||
read: function () {
|
||||
|
@ -10,7 +10,6 @@ var _ = require('lodash'),
|
||||
Tag = require('./tag').Tag,
|
||||
Tags = require('./tag').Tags,
|
||||
ghostBookshelf = require('./base'),
|
||||
validation = require('../data/validation'),
|
||||
xmlrpc = require('../xmlrpc'),
|
||||
|
||||
Post,
|
||||
@ -29,22 +28,15 @@ Post = ghostBookshelf.Model.extend({
|
||||
|
||||
initialize: function () {
|
||||
var self = this;
|
||||
this.on('creating', this.creating, this);
|
||||
|
||||
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
|
||||
|
||||
this.on('saved', function (model, attributes, options) {
|
||||
if (model.get('status') === 'published') {
|
||||
xmlrpc.ping(model.attributes);
|
||||
}
|
||||
return self.updateTags(model, attributes, options);
|
||||
});
|
||||
this.on('saving', function (model, attributes, options) {
|
||||
return when(self.saving(model, attributes, options)).then(function () {
|
||||
return self.validate(model, attributes, options);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
validation.validateSchema(this.tableName, this.toJSON());
|
||||
},
|
||||
|
||||
saving: function (newPage, attr, options) {
|
||||
@ -57,13 +49,16 @@ Post = ghostBookshelf.Model.extend({
|
||||
// keep tags for 'saved' event and deduplicate upper/lowercase tags
|
||||
tagsToCheck = this.get('tags');
|
||||
this.myTags = [];
|
||||
|
||||
_.each(tagsToCheck, function (item) {
|
||||
for (i = 0; i < self.myTags.length; i = i + 1) {
|
||||
if (self.myTags[i].name.toLocaleLowerCase() === item.name.toLocaleLowerCase()) {
|
||||
return;
|
||||
if (_.isObject(self.myTags)) {
|
||||
for (i = 0; i < self.myTags.length; i = i + 1) {
|
||||
if (self.myTags[i].name.toLocaleLowerCase() === item.name.toLocaleLowerCase()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.myTags.push(item);
|
||||
}
|
||||
self.myTags.push(item);
|
||||
});
|
||||
|
||||
ghostBookshelf.Model.prototype.saving.call(this, newPage, attr, options);
|
||||
@ -201,10 +196,22 @@ Post = ghostBookshelf.Model.extend({
|
||||
},
|
||||
|
||||
// Relations
|
||||
author: function () {
|
||||
author_id: function () {
|
||||
return this.belongsTo(User, 'author_id');
|
||||
},
|
||||
|
||||
created_by: function () {
|
||||
return this.belongsTo(User, 'created_by');
|
||||
},
|
||||
|
||||
updated_by: function () {
|
||||
return this.belongsTo(User, 'updated_by');
|
||||
},
|
||||
|
||||
published_by: function () {
|
||||
return this.belongsTo(User, 'published_by');
|
||||
},
|
||||
|
||||
tags: function () {
|
||||
return this.belongsToMany(Tag);
|
||||
},
|
||||
@ -228,8 +235,7 @@ Post = ghostBookshelf.Model.extend({
|
||||
// Extends base model findAll to eager-fetch author and user relationships.
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
|
||||
options.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
options.withRelated = _.union([ 'tags', 'fields' ], options.include);
|
||||
return ghostBookshelf.Model.findAll.call(this, options);
|
||||
},
|
||||
|
||||
@ -246,7 +252,9 @@ Post = ghostBookshelf.Model.extend({
|
||||
delete args.status;
|
||||
}
|
||||
|
||||
options.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
// Add related objects
|
||||
options.withRelated = _.union([ 'tags', 'fields' ], options.include);
|
||||
|
||||
return ghostBookshelf.Model.findOne.call(this, args, options);
|
||||
},
|
||||
|
||||
@ -273,7 +281,7 @@ Post = ghostBookshelf.Model.extend({
|
||||
findPage: function (opts) {
|
||||
var postCollection = Posts.forge(),
|
||||
tagInstance = opts.tag !== undefined ? Tag.forge({slug: opts.tag}) : false,
|
||||
permittedOptions = ['page', 'limit', 'status', 'staticPages'];
|
||||
permittedOptions = ['page', 'limit', 'status', 'staticPages', 'include'];
|
||||
|
||||
// sanitize opts so we are not automatically passing through any and all
|
||||
// query strings to Bookshelf / Knex. Although the API requires auth, we
|
||||
@ -311,8 +319,8 @@ Post = ghostBookshelf.Model.extend({
|
||||
postCollection.query('where', opts.where);
|
||||
}
|
||||
|
||||
// Fetch related models
|
||||
opts.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
// Add related objects
|
||||
opts.withRelated = _.union([ 'tags', 'fields' ], opts.include);
|
||||
|
||||
// If a query param for a tag is attached
|
||||
// we need to fetch the tag model to find its id
|
||||
@ -338,7 +346,6 @@ Post = ghostBookshelf.Model.extend({
|
||||
.query('join', 'posts_tags', 'posts_tags.post_id', '=', 'posts.id')
|
||||
.query('where', 'posts_tags.tag_id', '=', tagInstance.id);
|
||||
}
|
||||
|
||||
return postCollection
|
||||
.query('limit', opts.limit)
|
||||
.query('offset', opts.limit * (opts.page - 1))
|
||||
@ -384,6 +391,12 @@ Post = ghostBookshelf.Model.extend({
|
||||
pagination['next'] = null;
|
||||
pagination['prev'] = null;
|
||||
|
||||
if (opts.include) {
|
||||
_.each(postCollection.models, function (item) {
|
||||
item.include = opts.include;
|
||||
});
|
||||
}
|
||||
|
||||
data['posts'] = postCollection.toJSON();
|
||||
data['meta'] = meta;
|
||||
meta['pagination'] = pagination;
|
||||
@ -441,7 +454,6 @@ Post = ghostBookshelf.Model.extend({
|
||||
edit: function (editedPost, options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
|
||||
return ghostBookshelf.Model.edit.call(this, editedPost, options).then(function (post) {
|
||||
if (post) {
|
||||
return self.findOne({status: 'all', id: post.id}, options)
|
||||
|
@ -17,7 +17,7 @@ CasperTest.begin("Content screen is correct", 22, function suite(test) {
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
});
|
||||
|
||||
@ -97,7 +97,7 @@ CasperTest.begin('Content list shows correct post status', 8, function testStati
|
||||
test.assert(false, 'publish button did not change to published');
|
||||
});
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
});
|
||||
|
||||
@ -159,7 +159,7 @@ CasperTest.begin('Preview shows correct header for published post', 7, function
|
||||
test.assert(false, 'publish button did not change to published');
|
||||
});
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
});
|
||||
|
||||
@ -196,7 +196,7 @@ CasperTest.begin('Delete post modal', 9, function testDeleteModal(test) {
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
});
|
||||
|
||||
|
@ -33,7 +33,7 @@ CasperTest.begin("Ghost editor is correct", 10, function suite(test) {
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/\/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
var urlRegExp = new RegExp("^" + escapedUrl + "ghost\/editor\/[0-9]*");
|
||||
test.assertUrlMatch(urlRegExp, 'got an id on our URL');
|
||||
test.assertExists('.notification-success', 'got success notification');
|
||||
@ -376,7 +376,7 @@ CasperTest.begin('Publish menu - existing post', 22, function suite(test) {
|
||||
// Create a post in draft status
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
var urlRegExp = new RegExp("^" + escapedUrl + "ghost\/editor\/[0-9]*");
|
||||
test.assertUrlMatch(urlRegExp, 'got an id on our URL');
|
||||
});
|
||||
@ -413,7 +413,7 @@ CasperTest.begin('Publish menu - existing post', 22, function suite(test) {
|
||||
// Publish the post
|
||||
casper.thenClick('.js-publish-button');
|
||||
|
||||
casper.waitForResource(/posts\/$/, function checkPostWasCreated() {
|
||||
casper.waitForResource(/posts\/\?include=tags$/, function checkPostWasCreated() {
|
||||
var urlRegExp = new RegExp("^" + escapedUrl + "ghost\/editor\/[0-9]*");
|
||||
test.assertUrlMatch(urlRegExp, 'got an id on our URL');
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ CasperTest.begin("Ghost edit draft flow works correctly", 8, function suite(test
|
||||
});
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
casper.waitForResource(/posts\/$/);
|
||||
casper.waitForResource(/posts\/\?include=tags$/);
|
||||
|
||||
casper.waitForSelector('.notification-success', function onSuccess() {
|
||||
test.assert(true, 'Got success notification');
|
||||
@ -43,7 +43,7 @@ CasperTest.begin("Ghost edit draft flow works correctly", 8, function suite(test
|
||||
});
|
||||
|
||||
casper.thenClick('.js-publish-button');
|
||||
casper.waitForResource(/posts\/[0-9]+\/$/);
|
||||
casper.waitForResource(/posts\/[0-9]+\/\?include=tags$/);
|
||||
|
||||
casper.waitForSelector('.notification-success', function onSuccess() {
|
||||
test.assert(true, 'Got success notification');
|
||||
|
@ -210,6 +210,33 @@ describe('Post API', function () {
|
||||
jsonResponse.posts[0].page.should.eql(0);
|
||||
_.isBoolean(jsonResponse.posts[0].featured).should.eql(true);
|
||||
_.isBoolean(jsonResponse.posts[0].page).should.eql(true);
|
||||
jsonResponse.posts[0].author.should.be.a.Number;
|
||||
jsonResponse.posts[0].created_by.should.be.a.Number;
|
||||
jsonResponse.posts[0].tags[0].should.be.a.Number;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can retrieve a post with author, created_by, and tags', function (done) {
|
||||
request.get(testUtils.API.getApiQuery('posts/1/?include=author,tags,created_by'))
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
res.should.have.status(200);
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
res.should.be.json;
|
||||
var jsonResponse = res.body;
|
||||
jsonResponse.should.exist;
|
||||
jsonResponse.posts.should.exist;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
||||
jsonResponse.posts[0].page.should.eql(0);
|
||||
|
||||
jsonResponse.posts[0].author.should.be.an.Object;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0].author, 'user');
|
||||
jsonResponse.posts[0].tags[0].should.be.an.Object;
|
||||
testUtils.API.checkResponse(jsonResponse.posts[0].tags[0], 'tag');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -358,7 +385,7 @@ describe('Post API', function () {
|
||||
// ## edit
|
||||
describe('Edit', function () {
|
||||
it('can edit a post', function (done) {
|
||||
request.get(testUtils.API.getApiQuery('posts/1/'))
|
||||
request.get(testUtils.API.getApiQuery('posts/1/?include=tags'))
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
@ -391,7 +418,7 @@ describe('Post API', function () {
|
||||
});
|
||||
|
||||
it('can change a post to a static page', function (done) {
|
||||
request.get(testUtils.API.getApiQuery('posts/1/'))
|
||||
request.get(testUtils.API.getApiQuery('posts/1/?include=tags'))
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
@ -482,7 +509,7 @@ describe('Post API', function () {
|
||||
});
|
||||
|
||||
it('published_at = null', function (done) {
|
||||
request.get(testUtils.API.getApiQuery('posts/1/'))
|
||||
request.get(testUtils.API.getApiQuery('posts/1/?include=tags'))
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
@ -703,7 +730,7 @@ describe('Post API', function () {
|
||||
});
|
||||
|
||||
it('Can edit a post', function (done) {
|
||||
request.get(testUtils.API.getApiQuery('posts/2/'))
|
||||
request.get(testUtils.API.getApiQuery('posts/2/?include=tags'))
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
|
@ -44,7 +44,8 @@ describe('DB API', function () {
|
||||
}).then(function () {
|
||||
TagsAPI.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.equal(0);
|
||||
should.exist(results.tags);
|
||||
results.tags.length.should.equal(0);
|
||||
});
|
||||
}).then(function () {
|
||||
PostAPI.browse().then(function (results) {
|
||||
|
@ -65,10 +65,10 @@ describe('Post Model', function () {
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can findAll, returning author, user and field data', function (done) {
|
||||
it('can findAll, returning author and field data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findAll({}).then(function (results) {
|
||||
PostModel.findAll({include: ['author_id', 'fields']}).then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0].toJSON();
|
||||
@ -83,10 +83,10 @@ describe('Post Model', function () {
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can findOne, returning author, user and field data', function (done) {
|
||||
it('can findOne, returning author and field data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findOne({}).then(function (result) {
|
||||
// TODO: should take author :-/
|
||||
PostModel.findOne({}, {include: ['author_id', 'fields']}).then(function (result) {
|
||||
should.exist(result);
|
||||
firstPost = result.toJSON();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user