Add ignoreUser mutation and myIgnoredUsers root query

This commit is contained in:
Benjamin Goering
2017-04-11 14:19:32 -07:00
parent d3d7045227
commit 545f176bb8
8 changed files with 132 additions and 2 deletions
+6 -1
View File
@@ -13,11 +13,16 @@ const suspendUser = ({user}, {id, message}) => {
});
};
const ignoreUser = async ({user}, userToIgnore) => {
return await UsersService.ignoreUsers(user.id, [userToIgnore.id]);
};
module.exports = (context) => {
let mutators = {
User: {
setUserStatus: () => Promise.reject(errors.ErrNotAuthorized),
suspendUser: () => Promise.reject(errors.ErrNotAuthorized)
suspendUser: () => Promise.reject(errors.ErrNotAuthorized),
ignoreUser: (action) => ignoreUser(context, action),
}
};
+3
View File
@@ -23,6 +23,9 @@ const RootMutation = {
suspendUser(_, {id, message}, {mutators: {User}}) {
return wrapResponse(null)(User.suspendUser({id, message}));
},
ignoreUser(_, {id}, {mutators: {User}}) {
return wrapResponse(null)(User.ignoreUser({id}));
},
setCommentStatus(_, {id, status}, {mutators: {Comment}}) {
return wrapResponse(null)(Comment.setCommentStatus({id, status}));
},
+10
View File
@@ -83,6 +83,16 @@ const RootQuery = {
return user;
},
myIgnoredUsers: async (_, args, {user, loaders: {Users}}) => {
// get currentUser again since context.user was out of date when running test/graph/mutations/ignoreUser
const currentUser = (await Users.getByQuery({ids: [user.id], limit: 1}))[0];
if ( ! (currentUser && Array.isArray(currentUser.ignoresUsers) && currentUser.ignoresUsers.length)) {
return [];
}
return await Users.getByQuery({ids: currentUser.ignoresUsers});
},
// This endpoint is used for loading the user moderation queues (users whose username has been flagged),
// so hide it in the event that we aren't an admin.
users(_, {query: {action_type, limit, cursor, sort}}, {user, loaders: {Users, Actions}}) {
+13
View File
@@ -537,6 +537,9 @@ type RootQuery {
# role.
me: User
# Users that the currently logged in user ignores
myIgnoredUsers: [User]
# Users returned based on a query.
users(query: UsersQuery): [User]
@@ -703,6 +706,13 @@ type RemoveCommentTagResponse implements Response {
errors: [UserError]
}
# Response to ignoreUser mutation
type IgnoreUserResponse implements Response {
# An array of errors relating to the mutation that occured.
errors: [UserError]
}
# All mutations for the application are defined on this object.
type RootMutation {
@@ -735,6 +745,9 @@ type RootMutation {
# Remove tag from comment.
removeCommentTag(id: ID!, tag: String!): RemoveCommentTagResponse
# Ignore comments by another user
ignoreUser(id: ID!): IgnoreUserResponse
}
################################################################################
+7 -1
View File
@@ -117,7 +117,13 @@ const UserSchema = new mongoose.Schema({
type: String,
default: ''
}
}
},
ignoresUsers: [{
// user id of another user
type: String,
}]
}, {
// This will ensure that we have proper timestamps available on this model.
+20
View File
@@ -1,3 +1,4 @@
const assert = require('assert');
const bcrypt = require('bcrypt');
const url = require('url');
const jwt = require('jsonwebtoken');
@@ -834,4 +835,23 @@ module.exports = class UsersService {
throw err;
});
}
/**
* Ignore another user
* @param {String} userId the id of the user that is ignoring another users
* @param {String[]} usersToIgnore Array of user IDs to ignore
*/
static ignoreUsers(userId, usersToIgnore) {
assert(Array.isArray(usersToIgnore), 'usersToIgnore is an array');
assert(usersToIgnore.every(u => typeof u === 'string'), 'usersToIgnore is an array of string user IDs');
// TODO: For each usersToIgnore, make sure they exist?
return UserModel.update({id: userId}, {
$addToSet: {
ignoresUsers: {
$each: usersToIgnore
}
}
});
}
};
+55
View File
@@ -0,0 +1,55 @@
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');
describe('graph.mutations.ignoreUser', () => {
beforeEach(async () => {
await SettingsService.init();
});
const ignoreUserMutation = `
mutation ignoreUser ($id: ID!) {
ignoreUser(id:$id) {
errors {
translation_key
}
}
}
`;
const getMyIgnoredUsersQuery = `
query myIgnoredUsers {
myIgnoredUsers {
id,
username
}
}
`;
it('users can ignoreUser', async () => {
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
const userToIgnore = await UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB');
const context = new Context({user});
const ignoreUserResponse = await graphql(schema, ignoreUserMutation, {}, context, {id: userToIgnore.id});
if (ignoreUserResponse.errors && ignoreUserResponse.errors.length) {
console.error(ignoreUserResponse.errors);
}
expect(ignoreUserResponse.errors).to.be.empty;
// now check my ignored users
const myIgnoredUsersResponse = await graphql(schema, getMyIgnoredUsersQuery, {}, context, {});
if (myIgnoredUsersResponse.errors && myIgnoredUsersResponse.errors.length) {
console.error(myIgnoredUsersResponse.errors);
}
expect(myIgnoredUsersResponse.errors).to.be.empty;
const myIgnoredUsers = myIgnoredUsersResponse.data.myIgnoredUsers;
expect(myIgnoredUsers.length).to.equal(1);
expect(myIgnoredUsers[0].id).to.equal(userToIgnore.id);
expect(myIgnoredUsers[0].username).to.equal(userToIgnore.username);
});
});
+18
View File
@@ -169,6 +169,24 @@ describe('services.UsersService', () => {
});
});
describe('#ignoreUser', () => {
// @TODO: assert cannot ignore yourself
it('should add user id to ignoredUsers set', async () => {
const user = mockUsers[0];
const usersToIgnore = [mockUsers[1], mockUsers[2]];
await UsersService.ignoreUsers(user.id, usersToIgnore.map(u => u.id));
const userAfterIgnoring = await UsersService.findById(user.id);
expect(userAfterIgnoring.ignoresUsers.length).to.equal(2);
// ignore same user another time, make sure it's not added to the list.
await UsersService.ignoreUsers(user.id, usersToIgnore.slice(0, 1).map(u => u.id));
const userAfterIgnoring2 = await UsersService.findById(user.id);
expect(userAfterIgnoring2.ignoresUsers.length).to.equal(2);
});
});
describe('#ban', () => {
it('should set the status to banned', () => {
return UsersService