mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Added default comment relations
refs https://github.com/TryGhost/Team/issues/1664
This commit is contained in:
parent
ef989ed55c
commit
54e7a6cec3
6 changed files with 46 additions and 7 deletions
|
@ -2,7 +2,7 @@ const Promise = require('bluebird');
|
||||||
const tpl = require('@tryghost/tpl');
|
const tpl = require('@tryghost/tpl');
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
const models = require('../../models');
|
const models = require('../../models');
|
||||||
const ALLOWED_INCLUDES = ['post', 'member'];
|
const ALLOWED_INCLUDES = ['post', 'member', 'likes'];
|
||||||
const UNSAFE_ATTRS = ['status'];
|
const UNSAFE_ATTRS = ['status'];
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
|
|
|
@ -26,5 +26,14 @@ module.exports = (model, frame) => {
|
||||||
response.member = null;
|
response.member = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jsonModel.likes) {
|
||||||
|
response.likes_count = jsonModel.likes.length;
|
||||||
|
} else {
|
||||||
|
response.likes_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
response.liked = false;
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,10 @@ const Comment = ghostBookshelf.Model.extend({
|
||||||
return this.belongsTo('Comment', 'parent_id');
|
return this.belongsTo('Comment', 'parent_id');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
likes() {
|
||||||
|
return this.hasMany('CommentLike', 'comment_id');
|
||||||
|
},
|
||||||
|
|
||||||
emitChange: function emitChange(event, options) {
|
emitChange: function emitChange(event, options) {
|
||||||
const eventToTrigger = 'comment' + '.' + event;
|
const eventToTrigger = 'comment' + '.' + event;
|
||||||
ghostBookshelf.Model.prototype.emitChange.bind(this)(this, eventToTrigger, options);
|
ghostBookshelf.Model.prototype.emitChange.bind(this)(this, eventToTrigger, options);
|
||||||
|
@ -100,6 +104,21 @@ const Comment = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasMemberPermission;
|
return hasMemberPermission;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We have to ensure consistency. If you listen on model events (e.g. `member.added`), you can expect that you always
|
||||||
|
* receive all fields including relations. Otherwise you can't rely on a consistent flow. And we want to avoid
|
||||||
|
* that event listeners have to re-fetch a resource. This function is used in the context of inserting
|
||||||
|
* and updating resources. We won't return the relations by default for now.
|
||||||
|
*/
|
||||||
|
defaultRelations: function defaultRelations(methodName, options) {
|
||||||
|
// @todo: the default relations are not working for 'add' when we add it below
|
||||||
|
if (['findAll', 'findPage', 'edit'].indexOf(methodName) !== -1) {
|
||||||
|
options.withRelated = _.union(['member', 'likes'], options.withRelated || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ Object {
|
||||||
"edited_at": null,
|
"edited_at": null,
|
||||||
"html": "<p>First.</p>",
|
"html": "<p>First.</p>",
|
||||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"liked": Any<Boolean>,
|
||||||
|
"likes_count": Any<Number>,
|
||||||
"member": Object {
|
"member": Object {
|
||||||
"avatar_image": null,
|
"avatar_image": null,
|
||||||
"bio": null,
|
"bio": null,
|
||||||
|
@ -21,6 +23,8 @@ Object {
|
||||||
"edited_at": null,
|
"edited_at": null,
|
||||||
"html": "<p>Really original</p>",
|
"html": "<p>Really original</p>",
|
||||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"liked": Any<Boolean>,
|
||||||
|
"likes_count": Any<Number>,
|
||||||
"member": Object {
|
"member": Object {
|
||||||
"avatar_image": null,
|
"avatar_image": null,
|
||||||
"bio": null,
|
"bio": null,
|
||||||
|
@ -34,6 +38,8 @@ Object {
|
||||||
"edited_at": null,
|
"edited_at": null,
|
||||||
"html": "This is a message",
|
"html": "This is a message",
|
||||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"liked": Any<Boolean>,
|
||||||
|
"likes_count": Any<Number>,
|
||||||
"member": Object {
|
"member": Object {
|
||||||
"avatar_image": null,
|
"avatar_image": null,
|
||||||
"bio": null,
|
"bio": null,
|
||||||
|
@ -60,7 +66,7 @@ exports[`Comments API when authenticated Can browse all comments of a post 2: [h
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "*",
|
"access-control-allow-origin": "*",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "782",
|
"content-length": "872",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
"vary": "Accept-Encoding",
|
"vary": "Accept-Encoding",
|
||||||
|
@ -76,6 +82,8 @@ Object {
|
||||||
"edited_at": null,
|
"edited_at": null,
|
||||||
"html": "This is a message",
|
"html": "This is a message",
|
||||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"liked": false,
|
||||||
|
"likes_count": 0,
|
||||||
"member": null,
|
"member": null,
|
||||||
"status": "published",
|
"status": "published",
|
||||||
},
|
},
|
||||||
|
@ -87,7 +95,7 @@ exports[`Comments API when authenticated Can comment on a post 2: [headers] 1`]
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "*",
|
"access-control-allow-origin": "*",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "167",
|
"content-length": "197",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/comments\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/comments\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const {agentProvider, mockManager, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
const {agentProvider, mockManager, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
||||||
const {anyEtag, anyObjectId, anyLocationFor, anyISODateTime, anyUuid} = matchers;
|
const {anyEtag, anyObjectId, anyLocationFor, anyISODateTime, anyUuid, anyNumber, anyBoolean} = matchers;
|
||||||
|
|
||||||
let membersAgent, membersService, postId, commentId;
|
let membersAgent, membersService, postId, commentId;
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ const commentMatcherWithMember = {
|
||||||
created_at: anyISODateTime,
|
created_at: anyISODateTime,
|
||||||
member: {
|
member: {
|
||||||
id: anyObjectId
|
id: anyObjectId
|
||||||
}
|
},
|
||||||
|
likes_count: anyNumber,
|
||||||
|
liked: anyBoolean
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Comments API', function () {
|
describe('Comments API', function () {
|
||||||
|
@ -58,8 +60,8 @@ describe('Comments API', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can browse all comments of a post', async function () {
|
it('Can browse all comments of a post', async function () {
|
||||||
await membersAgent
|
const {body} = await membersAgent
|
||||||
.get(`/api/comments/?filter=post_id:${postId}&include=member`)
|
.get(`/api/comments/?filter=post_id:${postId}`)
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.matchHeaderSnapshot({
|
.matchHeaderSnapshot({
|
||||||
etag: anyEtag
|
etag: anyEtag
|
||||||
|
|
|
@ -313,6 +313,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
matchers: {
|
matchers: {
|
||||||
|
anyBoolean: any(Boolean),
|
||||||
anyString: any(String),
|
anyString: any(String),
|
||||||
anyArray: any(Array),
|
anyArray: any(Array),
|
||||||
anyNumber: any(Number),
|
anyNumber: any(Number),
|
||||||
|
|
Loading…
Reference in a new issue