diff --git a/client/coral-framework/graphql/queries/index.js b/client/coral-framework/graphql/queries/index.js index bcf397d3c..5dbea5822 100644 --- a/client/coral-framework/graphql/queries/index.js +++ b/client/coral-framework/graphql/queries/index.js @@ -30,7 +30,7 @@ export const getCounts = (data) => ({asset_id, limit, sort}) => { asset_id, limit, sort, - notIgnoredBy: data.variables.notIgnoredBy, + excludeIgnored: data.variables.excludeIgnored, }, updateQuery: (oldData, {fetchMoreResult:{asset}}) => { return { @@ -54,7 +54,7 @@ export const loadMore = (data) => ({limit, cursor, parent_id = null, asset_id, s parent_id, // if null, we're loading more top-level comments, if not, we're loading more replies to a comment asset_id, // the id of the asset we're currently on sort, // CHRONOLOGICAL or REVERSE_CHRONOLOGICAL - notIgnoredBy: data.variables.notIgnoredBy, + excludeIgnored: data.variables.excludeIgnored, }, updateQuery: (oldData, {fetchMoreResult:{new_top_level_comments}}) => { let updatedAsset; @@ -131,7 +131,7 @@ export const variablesForStreamQuery = ({auth}) => { asset_url: getQueryVariable('asset_url'), comment_id: has_comment ? comment_id : 'no-comment', has_comment, - notIgnoredBy: (auth && auth.user) ? auth.user.id : undefined, + excludeIgnored: Boolean(auth && auth.user && auth.user.id), }; }; diff --git a/client/coral-framework/graphql/queries/loadMore.graphql b/client/coral-framework/graphql/queries/loadMore.graphql index d4ee818a1..b18f4d84e 100644 --- a/client/coral-framework/graphql/queries/loadMore.graphql +++ b/client/coral-framework/graphql/queries/loadMore.graphql @@ -1,9 +1,9 @@ #import "../fragments/commentView.graphql" -query LoadMoreComments($limit: Int = 5, $cursor: Date, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER, $notIgnoredBy: String) { - new_top_level_comments: comments(query: {limit: $limit, cursor: $cursor, parent_id: $parent_id, asset_id: $asset_id, sort: $sort, notIgnoredBy: $notIgnoredBy}) { +query LoadMoreComments($limit: Int = 5, $cursor: Date, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) { + new_top_level_comments: comments(query: {limit: $limit, cursor: $cursor, parent_id: $parent_id, asset_id: $asset_id, sort: $sort, excludeIgnored: $excludeIgnored}) { ...commentView - replyCount(notIgnoredBy: $notIgnoredBy) + replyCount(excludeIgnored: $excludeIgnored) replies(limit: 3) { ...commentView } diff --git a/client/coral-framework/graphql/queries/streamQuery.graphql b/client/coral-framework/graphql/queries/streamQuery.graphql index a96f7f634..06e36cebd 100644 --- a/client/coral-framework/graphql/queries/streamQuery.graphql +++ b/client/coral-framework/graphql/queries/streamQuery.graphql @@ -1,18 +1,18 @@ #import "../fragments/commentView.graphql" -query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comment: Boolean!, $notIgnoredBy: String) { +query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comment: Boolean!, $excludeIgnored: Boolean) { # the comment here is for loading one comment and it's children, probably after following a permalink # $has_comment is derived from the comment_id query param in the iframe url, # which is in turn pulled from the host page url comment(id: $comment_id) @include(if: $has_comment) { ...commentView - replyCount(notIgnoredBy: $notIgnoredBy) + replyCount(excludeIgnored: $excludeIgnored) replies { ...commentView } parent { ...commentView - replyCount(notIgnoredBy: $notIgnoredBy) + replyCount(excludeIgnored: $excludeIgnored) replies { ...commentView } @@ -36,12 +36,12 @@ query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comme charCount requireEmailConfirmation } - commentCount(notIgnoredBy: $notIgnoredBy) - totalCommentCount(notIgnoredBy: $notIgnoredBy) - comments(limit: 10, notIgnoredBy: $notIgnoredBy) { + commentCount(excludeIgnored: $excludeIgnored) + totalCommentCount(excludeIgnored: $excludeIgnored) + comments(limit: 10, excludeIgnored: $excludeIgnored) { ...commentView - replyCount(notIgnoredBy: $notIgnoredBy) - replies(limit: 3, notIgnoredBy: $notIgnoredBy) { + replyCount(excludeIgnored: $excludeIgnored) + replies(limit: 3, excludeIgnored: $excludeIgnored) { ...commentView } } diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index c9fe1c302..0faa124da 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -44,20 +44,17 @@ const getCountsByAssetID = (context, asset_ids) => { * Returns the count of all public comments on an asset id, also filtering by personalization options. * * @param {Array} id The ID of the asset - * @param {Array} notIgnoredBy Exclude comments ignored by this User ID + * @param {Array} excludeIgnored Exclude comments ignored by the requesting user */ -const getCountsByAssetIDPersonalized = async (context, {assetId, notIgnoredBy}) => { +const getCountsByAssetIDPersonalized = async (context, {assetId, excludeIgnored}) => { const query = { asset_id: assetId, status: { $in: ['NONE', 'ACCEPTED'], }, }; - if (notIgnoredBy) { - const user = context.user; - if (user.id !== notIgnoredBy) { - throw new Error(`You are not authorized to query for comments counts notIgnoredBy ${notIgnoredBy}`); - } + const user = context.user; + if (excludeIgnored && user) { // load afresh, as `user` may be from cache and not have recent ignores const freshUser = await UsersService.findById(user.id); @@ -105,9 +102,9 @@ const getParentCountsByAssetID = (context, asset_ids) => { * Returns the count of top-level comments on an asset id, also filtering by personalization options. * * @param {Array} id The ID of the asset - * @param {Array} notIgnoredBy Exclude comments ignored by this User ID + * @param {Array} excludeIgnored Exclude comments ignored by the requesting user */ -const getParentCountByAssetIDPersonalized = async (context, {assetId, notIgnoredBy}) => { +const getParentCountByAssetIDPersonalized = async (context, {assetId, excludeIgnored}) => { const query = { asset_id: assetId, parent_id: null, @@ -115,11 +112,8 @@ const getParentCountByAssetIDPersonalized = async (context, {assetId, notIgnored $in: ['NONE', 'ACCEPTED'], }, }; - if (notIgnoredBy) { - const user = context.user; - if (user.id !== notIgnoredBy) { - throw new Error(`You are not authorized to query for comments counts notIgnoredBy ${notIgnoredBy}`); - } + const user = context.user; + if (excludeIgnored && user) { // load afresh, as `user` may be from cache and not have recent ignores const freshUser = await UsersService.findById(user.id); @@ -166,9 +160,9 @@ const getCountsByParentID = (context, parent_ids) => { * Returns the count of comments for the provided parent_id, also filtering by personalization options. * * @param {Array} id The ID of the parent comment - * @param {Array} notIgnoredBy Exclude comments ignored by this User ID + * @param {Array} excludeIgnored Exclude comments ignored by context.user */ -const getCountByParentIDPersonalized = async (context, {id, notIgnoredBy}) => { +const getCountByParentIDPersonalized = async (context, {id, excludeIgnored}) => { const query = { parent_id: { $in: [id] @@ -177,11 +171,8 @@ const getCountByParentIDPersonalized = async (context, {id, notIgnoredBy}) => { $in: ['NONE', 'ACCEPTED'] } }; - if (notIgnoredBy) { - const user = context.user; - if (user.id !== notIgnoredBy) { - throw new Error(`You are not authorized to query for comments counts notIgnoredBy ${notIgnoredBy}`); - } + const user = context.user; + if (excludeIgnored && user) { // load afresh, as `user` may be from cache and not have recent ignores const freshUser = await UsersService.findById(user.id); @@ -230,7 +221,7 @@ const getCommentCountByQuery = (context, {ids, statuses, asset_id, parent_id}) = * @param {Object} context graph context * @param {Object} query query terms to apply to the comments query */ -const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, author_id, limit, cursor, sort, notIgnoredBy}) => { +const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, author_id, limit, cursor, sort, excludeIgnored}) => { let comments = CommentModel.find(); // Only administrators can search for comments with statuses that are not @@ -272,10 +263,7 @@ const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, a comments = comments.where({parent_id}); } - if (notIgnoredBy) { - if (user.id !== notIgnoredBy) { - throw new Error(`You are not authorized to query for comments notIgnoredBy ${notIgnoredBy}`); - } + if (excludeIgnored && user) { // load afresh, as `user` may be from cache and not have recent ignores const freshUser = await UsersService.findById(user.id); diff --git a/graph/resolvers/asset.js b/graph/resolvers/asset.js index 811181aa6..96bc8c1bc 100644 --- a/graph/resolvers/asset.js +++ b/graph/resolvers/asset.js @@ -2,27 +2,27 @@ const Asset = { recentComments({id}, _, {loaders: {Comments}}) { return Comments.genRecentComments.load(id); }, - comments({id}, {sort, limit, notIgnoredBy}, {loaders: {Comments}}) { + comments({id}, {sort, limit, excludeIgnored}, {loaders: {Comments}}) { return Comments.getByQuery({ asset_id: id, sort, limit, parent_id: null, - notIgnoredBy, + excludeIgnored, }); }, - commentCount({id, commentCount}, {notIgnoredBy}, {loaders: {Comments}}) { - if (notIgnoredBy) { - return Comments.parentCountByAssetIDPersonalized({assetId: id, notIgnoredBy}); + commentCount({id, commentCount}, {excludeIgnored}, {user, loaders: {Comments}}) { + if (user && excludeIgnored) { + return Comments.parentCountByAssetIDPersonalized({assetId: id, excludeIgnored}); } if (commentCount != null) { return commentCount; } return Comments.parentCountByAssetID.load(id); }, - totalCommentCount({id, totalCommentCount}, {notIgnoredBy}, {loaders: {Comments}}) { - if (notIgnoredBy) { - return Comments.countByAssetIDPersonalized({assetId: id, notIgnoredBy}); + totalCommentCount({id, totalCommentCount}, {excludeIgnored}, {user, loaders: {Comments}}) { + if (user && excludeIgnored) { + return Comments.countByAssetIDPersonalized({assetId: id, excludeIgnored}); } if (totalCommentCount != null) { return totalCommentCount; diff --git a/graph/resolvers/comment.js b/graph/resolvers/comment.js index 1f57cb939..19ea11efe 100644 --- a/graph/resolvers/comment.js +++ b/graph/resolvers/comment.js @@ -12,20 +12,20 @@ const Comment = { recentReplies({id}, _, {loaders: {Comments}}) { return Comments.genRecentReplies.load(id); }, - replies({id, asset_id}, {sort, limit, notIgnoredBy}, {loaders: {Comments}}) { + replies({id, asset_id}, {sort, limit, excludeIgnored}, {loaders: {Comments}}) { return Comments.getByQuery({ asset_id, parent_id: id, sort, limit, - notIgnoredBy, + excludeIgnored, }); }, - replyCount({id}, {notIgnoredBy}, {loaders: {Comments}}) { - if ( ! notIgnoredBy) { - return Comments.countByParentID.load(id); + replyCount({id}, {excludeIgnored}, {user, loaders: {Comments}}) { + if (user && excludeIgnored) { + return Comments.countByParentIDPersonalized({id, excludeIgnored}); } - return Comments.countByParentIDPersonalized({id, notIgnoredBy}); + return Comments.countByParentID.load(id); }, actions({id}, _, {user, loaders: {Actions}}) { diff --git a/graph/resolvers/root_query.js b/graph/resolvers/root_query.js index 530ee74d6..b26ecabca 100644 --- a/graph/resolvers/root_query.js +++ b/graph/resolvers/root_query.js @@ -19,15 +19,15 @@ const RootQuery = { // This endpoint is used for loading moderation queues, so hide it in the // event that we aren't an admin. - comments(_, {query: {action_type, statuses, asset_id, parent_id, limit, cursor, sort, notIgnoredBy}}, {user, loaders: {Comments, Actions}}) { - let query = {statuses, asset_id, parent_id, limit, cursor, sort, notIgnoredBy}; + comments(_, {query: {action_type, statuses, asset_id, parent_id, limit, cursor, sort, excludeIgnored}}, {user, loaders: {Comments, Actions}}) { + let query = {statuses, asset_id, parent_id, limit, cursor, sort, excludeIgnored}; if (user != null && user.hasRoles('ADMIN') && action_type) { return Actions.getByTypes({action_type, item_type: 'COMMENTS'}) .then((ids) => { // Perform the query using the available resolver. - return Comments.getByQuery({ids, statuses, asset_id, parent_id, limit, cursor, sort, notIgnoredBy}); + return Comments.getByQuery({ids, statuses, asset_id, parent_id, limit, cursor, sort, excludeIgnored}); }); } diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 7f988054b..aeae1537c 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -141,8 +141,8 @@ input CommentsQuery { # Sort the results by created_at. sort: SORT_ORDER = REVERSE_CHRONOLOGICAL - # Exclude comments ignored by this user ID - notIgnoredBy: String + # Exclude comments ignored by the requesting user + excludeIgnored: Boolean } # CommentCountQuery allows the ability to query comment counts by specific @@ -188,10 +188,10 @@ type Comment { recentReplies: [Comment] # the replies that were made to the comment. - replies(sort: SORT_ORDER = CHRONOLOGICAL, limit: Int = 3, notIgnoredBy: String): [Comment] + replies(sort: SORT_ORDER = CHRONOLOGICAL, limit: Int = 3, excludeIgnored: Boolean): [Comment] # The count of replies on a comment. - replyCount(notIgnoredBy: String): Int + replyCount(excludeIgnored: Boolean): Int # Actions completed on the parent. Requires the `ADMIN` role. actions: [Action] @@ -420,13 +420,13 @@ type Asset { recentComments: [Comment] # The top level comments that are attached to the asset. - comments(sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, limit: Int = 10, notIgnoredBy: String): [Comment] + comments(sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, limit: Int = 10, excludeIgnored: Boolean): [Comment] # The count of top level comments on the asset. - commentCount(notIgnoredBy: String): Int + commentCount(excludeIgnored: Boolean): Int # The total count of all comments made on the asset. - totalCommentCount(notIgnoredBy: String): Int + totalCommentCount(excludeIgnored: Boolean): Int # The settings (rectified with the global settings) that should be applied to # this asset. diff --git a/test/graph/queries/asset.js b/test/graph/queries/asset.js index 5ee19697a..ba31fe330 100644 --- a/test/graph/queries/asset.js +++ b/test/graph/queries/asset.js @@ -76,16 +76,16 @@ describe('graph.queries.asset', () => { expect(ignoreUserResponse.errors).to.be.empty; const assetCommentsWithoutIgnoredQuery = ` - query assetCommentsQuery($assetId: ID!, $assetUrl: String!, $notIgnoredBy: String!) { + query assetCommentsQuery($assetId: ID!, $assetUrl: String!, $excludeIgnored: Boolean!) { asset(id: $assetId, url: $assetUrl) { - comments(limit: 10, notIgnoredBy: $notIgnoredBy) { + comments(limit: 10, excludeIgnored: $excludeIgnored) { id, body, } } } `; - const assetCommentsResponse = await graphql(schema, assetCommentsWithoutIgnoredQuery, {}, context, {assetId, assetUrl, notIgnoredBy: userA.id}); + const assetCommentsResponse = await graphql(schema, assetCommentsWithoutIgnoredQuery, {}, context, {assetId, assetUrl, excludeIgnored: true}); const comments = assetCommentsResponse.data.asset.comments; expect(comments.length).to.equal(2); });