Embed doesn't show comments from ignored users

This commit is contained in:
Benjamin Goering
2017-04-10 14:40:25 -07:00
parent c7d8c40770
commit 873da1cea9
10 changed files with 135 additions and 22 deletions
@@ -29,10 +29,10 @@ export const getCounts = (data) => ({asset_id, limit, sort}) => {
variables: {
asset_id,
limit,
sort
sort,
notIgnoredBy: data.variables.notIgnoredBy,
},
updateQuery: (oldData, {fetchMoreResult:{asset}}) => {
return {
...oldData,
asset: {
@@ -53,7 +53,8 @@ export const loadMore = (data) => ({limit, cursor, parent_id = null, asset_id, s
cursor, // the date of the first/last comment depending on the sort order
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
sort, // CHRONOLOGICAL or REVERSE_CHRONOLOGICAL
notIgnoredBy: data.variables.notIgnoredBy,
},
updateQuery: (oldData, {fetchMoreResult:{new_top_level_comments}}) => {
let updatedAsset;
@@ -122,18 +123,18 @@ export const loadMore = (data) => ({limit, cursor, parent_id = null, asset_id, s
// load the comment stream.
export const queryStream = graphql(STREAM_QUERY, {
options: () => {
options: ({auth} = {}) => {
// where the query string is from the embeded iframe url
let comment_id = getQueryVariable('comment_id');
let has_comment = comment_id != null;
return {
variables: {
asset_id: getQueryVariable('asset_id'),
asset_url: getQueryVariable('asset_url'),
comment_id: has_comment ? comment_id : 'no-comment',
has_comment
has_comment,
notIgnoredBy: (auth && auth.user) ? auth.user.id : undefined,
}
};
},
@@ -1,7 +1,7 @@
#import "../fragments/commentView.graphql"
query LoadMoreComments($limit: Int = 5, $cursor: Date, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER) {
new_top_level_comments: comments(query: {limit: $limit, cursor: $cursor, parent_id: $parent_id, asset_id: $asset_id, sort: $sort}) {
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}) {
...commentView
replyCount
replies(limit: 3) {
@@ -1,6 +1,6 @@
#import "../fragments/commentView.graphql"
query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comment: Boolean!) {
query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comment: Boolean!, $notIgnoredBy: String) {
# 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
@@ -38,10 +38,10 @@ query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comme
}
commentCount
totalCommentCount
comments(limit: 10) {
comments(limit: 10, notIgnoredBy: $notIgnoredBy) {
...commentView
replyCount
replies(limit: 3) {
replies(limit: 3, notIgnoredBy: $notIgnoredBy) {
...commentView
}
}
+15 -1
View File
@@ -6,6 +6,7 @@ const {
const DataLoader = require('dataloader');
const CommentModel = require('../../models/comment');
const UsersService = require('../../services/users');
/**
* Returns the comment count for all comments that are public based on their
@@ -142,7 +143,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 = ({user}, {ids, statuses, asset_id, parent_id, author_id, limit, cursor, sort}) => {
const getCommentsByQuery = async ({user}, {ids, statuses, asset_id, parent_id, author_id, limit, cursor, sort, notIgnoredBy}) => {
let comments = CommentModel.find();
// Only administrators can search for comments with statuses that are not
@@ -184,6 +185,19 @@ const getCommentsByQuery = ({user}, {ids, statuses, asset_id, parent_id, author_
comments = comments.where({parent_id});
}
if (notIgnoredBy) {
if (user.id !== notIgnoredBy) {
throw new Error(`You are not authorized to query for comments notIgnoredBy ${notIgnoredBy}`);
}
// load afresh, as `user` may be from cache and not have recent ignores
const freshUser = await UsersService.findById(user.id);
const ignoredUsers = freshUser.ignoresUsers;
comments = comments.where({
author_id: {$nin: ignoredUsers}
});
}
if (cursor) {
if (sort === 'REVERSE_CHRONOLOGICAL') {
comments = comments.where({
-1
View File
@@ -18,7 +18,6 @@ const ignoreUser = async ({user}, userToIgnore) => {
};
const stopIgnoringUser = async ({user}, userToStopIgnoring) => {
console.log('stopIgnoringUser!!');
return await UsersService.stopIgnoringUsers(user.id, [userToStopIgnoring.id]);
};
+3 -2
View File
@@ -2,12 +2,13 @@ const Asset = {
recentComments({id}, _, {loaders: {Comments}}) {
return Comments.genRecentComments.load(id);
},
comments({id}, {sort, limit}, {loaders: {Comments}}) {
comments({id}, {sort, limit, notIgnoredBy}, {loaders: {Comments}}) {
return Comments.getByQuery({
asset_id: id,
sort,
limit,
parent_id: null
parent_id: null,
notIgnoredBy,
});
},
commentCount({id, commentCount}, _, {loaders: {Comments}}) {
+4 -2
View File
@@ -12,12 +12,14 @@ const Comment = {
recentReplies({id}, _, {loaders: {Comments}}) {
return Comments.genRecentReplies.load(id);
},
replies({id, asset_id}, {sort, limit}, {loaders: {Comments}}) {
replies({id, asset_id}, {sort, limit, notIgnoredBy}, {loaders: {Comments}}) {
console.log('replies notIgnoredBy', notIgnoredBy);
return Comments.getByQuery({
asset_id,
parent_id: id,
sort,
limit
limit,
notIgnoredBy,
});
},
replyCount({id}, _, {loaders: {Comments}}) {
+3 -3
View File
@@ -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}}, {user, loaders: {Comments, Actions}}) {
let query = {statuses, asset_id, parent_id, limit, cursor, sort};
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};
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});
return Comments.getByQuery({ids, statuses, asset_id, parent_id, limit, cursor, sort, notIgnoredBy});
});
}
+5 -2
View File
@@ -140,6 +140,9 @@ input CommentsQuery {
# Sort the results by created_at.
sort: SORT_ORDER = REVERSE_CHRONOLOGICAL
# Exclude comments ignored by this user ID
notIgnoredBy: String
}
# CommentCountQuery allows the ability to query comment counts by specific
@@ -185,7 +188,7 @@ type Comment {
recentReplies: [Comment]
# the replies that were made to the comment.
replies(sort: SORT_ORDER = CHRONOLOGICAL, limit: Int = 3): [Comment]
replies(sort: SORT_ORDER = CHRONOLOGICAL, limit: Int = 3, notIgnoredBy: String): [Comment]
# The count of replies on a comment.
replyCount: Int
@@ -417,7 +420,7 @@ type Asset {
recentComments: [Comment]
# The top level comments that are attached to the asset.
comments(sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, limit: Int = 10): [Comment]
comments(sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, limit: Int = 10, notIgnoredBy: String): [Comment]
# The count of top level comments on the asset.
commentCount: Int
+93
View File
@@ -0,0 +1,93 @@
const expect = require('chai').expect;
const {graphql} = require('graphql');
const schema = require('../../../graph/schema');
const Context = require('../../../graph/context');
const UsersService = require('../../../services/users');
const SettingsService = require('../../../services/settings');
const Asset = require('../../../models/asset');
const CommentsService = require('../../../services/comments');
describe('graph.queries.asset', () => {
beforeEach(async () => {
await SettingsService.init();
});
it('can get comments edge', async () => {
const assetId = 'fakeAssetId';
const assetUrl = 'https://bengo.is';
await Asset.create({id: assetId, url: assetUrl});
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
const context = new Context({user});
await CommentsService.publicCreate([1, 2].map(() => ({
author_id: user.id,
asset_id: assetId,
body: `hello there! ${ String(Math.random()).slice(2)}`,
})));
const assetCommentsQuery = `
query assetCommentsQuery($assetId: ID!, $assetUrl: String!) {
asset(id: $assetId, url: $assetUrl) {
comments(limit: 10) {
id,
body,
}
}
}
`;
const assetCommentsResponse = await graphql(schema, assetCommentsQuery, {}, context, {assetId, assetUrl});
const comments = assetCommentsResponse.data.asset.comments;
expect(comments.length).to.equal(2);
});
it('can query comments edge to exclude comments ignored by user', async () => {
const assetId = 'fakeAssetId1';
const assetUrl = 'https://bengo.is/1';
await Asset.create({id: assetId, url: assetUrl});
const userA = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
const userB = await UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB');
const userC = await UsersService.createLocalUser('usernameC@example.com', 'password', 'usernameC');
const context = new Context({user: userA});
// create 2 comments each for userB, userC
await Promise.all([userB, userC].map(user => CommentsService.publicCreate([1, 2].map(() => ({
author_id: user.id,
asset_id: assetId,
body: `hello there! ${ String(Math.random()).slice(2)}`,
})))));
// ignore userB
const ignoreUserMutation = `
mutation ignoreUser ($id: ID!) {
ignoreUser(id:$id) {
errors {
translation_key
}
}
}
`;
const ignoreUserResponse = await graphql(schema, ignoreUserMutation, {}, context, {id: userB.id});
if (ignoreUserResponse.errors && ignoreUserResponse.errors.length) {
console.error(ignoreUserResponse.errors);
}
expect(ignoreUserResponse.errors).to.be.empty;
const assetCommentsWithoutIgnoredQuery = `
query assetCommentsQuery($assetId: ID!, $assetUrl: String!, $notIgnoredBy: String!) {
asset(id: $assetId, url: $assetUrl) {
comments(limit: 10, notIgnoredBy: $notIgnoredBy) {
id,
body,
}
}
}
`;
const assetCommentsResponse = await graphql(schema, assetCommentsWithoutIgnoredQuery, {}, context, {assetId, assetUrl, notIgnoredBy: userA.id});
const comments = assetCommentsResponse.data.asset.comments;
expect(comments.length).to.equal(2);
});
});