From 876c1024c96e56b270e2479bec798bbc69d68576 Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Wed, 6 Jul 2022 16:58:12 +0200 Subject: [PATCH] Added liked property to comments refs https://github.com/TryGhost/Team/issues/1664 --- .../serializers/output/mappers/comments.js | 5 +- core/server/models/comment.js | 2 +- .../__snapshots__/comments.test.js.snap | 133 ++++++++++++++++++ .../e2e-api/members-comments/comments.test.js | 45 +++++- 4 files changed, 182 insertions(+), 3 deletions(-) diff --git a/core/server/api/endpoints/utils/serializers/output/mappers/comments.js b/core/server/api/endpoints/utils/serializers/output/mappers/comments.js index 3d859f1e4e..eb5fc94a65 100644 --- a/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +++ b/core/server/api/endpoints/utils/serializers/output/mappers/comments.js @@ -32,8 +32,11 @@ module.exports = (model, frame) => { response.likes_count = 0; } - // todo response.liked = false; + if (jsonModel.likes && frame.original.context.member && frame.original.context.member.id) { + const id = frame.original.context.member.id; + response.liked = !!jsonModel.likes.find(l => l.member_id === id); + } return response; }; diff --git a/core/server/models/comment.js b/core/server/models/comment.js index 338209c76b..b1a4335a9b 100644 --- a/core/server/models/comment.js +++ b/core/server/models/comment.js @@ -114,7 +114,7 @@ const Comment = ghostBookshelf.Model.extend({ */ 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) { + if (['findAll', 'findPage', 'edit', 'findOne'].indexOf(methodName) !== -1) { options.withRelated = _.union(['member', 'likes'], options.withRelated || []); } diff --git a/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap b/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap index 0a5b72ab78..af13f0b50e 100644 --- a/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap +++ b/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap @@ -104,6 +104,28 @@ Object { } `; +exports[`Comments API when authenticated Can like a comment 1: [body] 1`] = ` +Object { + "comments": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "edited_at": null, + "html": "This is a message", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "liked": Any, + "likes_count": Any, + "member": Object { + "avatar_image": null, + "bio": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": null, + }, + "status": "published", + }, + ], +} +`; + exports[`Comments API when authenticated Can like a comment 1: [headers] 1`] = ` Object { "access-control-allow-origin": "*", @@ -113,6 +135,83 @@ Object { } `; +exports[`Comments API when authenticated Can like a comment 2: [body] 1`] = ` +Object { + "comments": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "edited_at": null, + "html": "This is a message", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "liked": Any, + "likes_count": Any, + "member": Object { + "avatar_image": null, + "bio": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": null, + }, + "status": "published", + }, + ], +} +`; + +exports[`Comments API when authenticated Can like a comment 2: [headers] 1`] = ` +Object { + "access-control-allow-origin": "*", + "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", + "content-length": "269", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Comments API when authenticated Can like a comment 3: [headers] 1`] = ` +Object { + "access-control-allow-origin": "*", + "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "x-powered-by": "Express", +} +`; + +exports[`Comments API when authenticated Can like a comment 4: [body] 1`] = ` +Object { + "comments": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "edited_at": null, + "html": "This is a message", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "liked": Any, + "likes_count": Any, + "member": Object { + "avatar_image": null, + "bio": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": null, + }, + "status": "published", + }, + ], +} +`; + +exports[`Comments API when authenticated Can like a comment 5: [headers] 1`] = ` +Object { + "access-control-allow-origin": "*", + "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", + "content-length": "268", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Accept-Encoding", + "x-powered-by": "Express", +} +`; + exports[`Comments API when authenticated Can remove a like 1: [headers] 1`] = ` Object { "access-control-allow-origin": "*", @@ -122,6 +221,40 @@ Object { } `; +exports[`Comments API when authenticated Can remove a like 2: [body] 1`] = ` +Object { + "comments": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "edited_at": null, + "html": "This is a message", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "liked": Any, + "likes_count": Any, + "member": Object { + "avatar_image": null, + "bio": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": null, + }, + "status": "published", + }, + ], +} +`; + +exports[`Comments API when authenticated Can remove a like 3: [headers] 1`] = ` +Object { + "access-control-allow-origin": "*", + "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", + "content-length": "269", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Accept-Encoding", + "x-powered-by": "Express", +} +`; + exports[`Comments API when authenticated Cannot like a comment multiple times 1: [body] 1`] = ` Object { "errors": Array [ diff --git a/test/e2e-api/members-comments/comments.test.js b/test/e2e-api/members-comments/comments.test.js index cd465fc9a8..5dc3dd3bb9 100644 --- a/test/e2e-api/members-comments/comments.test.js +++ b/test/e2e-api/members-comments/comments.test.js @@ -1,5 +1,6 @@ const {agentProvider, mockManager, fixtureManager, matchers} = require('../../utils/e2e-framework'); const {anyEtag, anyObjectId, anyLocationFor, anyISODateTime, anyUuid, anyNumber, anyBoolean} = matchers; +require('should'); let membersAgent, membersService, postId, commentId; @@ -72,6 +73,20 @@ describe('Comments API', function () { }); it('Can like a comment', async function () { + // Check not liked + await membersAgent + .get(`/api/comments/${commentId}/`) + .expectStatus(200) + .matchHeaderSnapshot({ + etag: anyEtag + }) + .matchBodySnapshot({ + comments: new Array(1).fill(commentMatcherWithMember) + }) + .expect(({body}) => { + body.comments[0].liked.should.eql(false); + }); + // Create a temporary comment await membersAgent .post(`/api/comments/${commentId}/like/`) @@ -80,6 +95,20 @@ describe('Comments API', function () { etag: anyEtag }) .expectEmptyBody(); + + // Check liked + await membersAgent + .get(`/api/comments/${commentId}/`) + .expectStatus(200) + .matchHeaderSnapshot({ + etag: anyEtag + }) + .matchBodySnapshot({ + comments: new Array(1).fill(commentMatcherWithMember) + }) + .expect(({body}) => { + body.comments[0].liked.should.eql(true); + }); }); it('Cannot like a comment multiple times', async function () { @@ -99,13 +128,27 @@ describe('Comments API', function () { it('Can remove a like', async function () { // Create a temporary comment - const {body} = await membersAgent + await membersAgent .delete(`/api/comments/${commentId}/like/`) .expectStatus(204) .matchHeaderSnapshot({ etag: anyEtag }) .expectEmptyBody(); + + // Check liked + await membersAgent + .get(`/api/comments/${commentId}/`) + .expectStatus(200) + .matchHeaderSnapshot({ + etag: anyEtag + }) + .matchBodySnapshot({ + comments: new Array(1).fill(commentMatcherWithMember) + }) + .expect(({body}) => { + body.comments[0].liked.should.eql(false); + }); }); }); });