diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index 86bd29c13..a7a0b5740 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -15,7 +15,7 @@ import {NEW_COMMENT_COUNT_POLL_INTERVAL} from 'coral-framework/constants/comment
import {queryStream} from 'coral-framework/graphql/queries';
import {postComment, postFlag, postLike, postDontAgree, deleteAction, addCommentTag, removeCommentTag, ignoreUser} from 'coral-framework/graphql/mutations';
-import {editName, ignoreUserSuccess} from 'coral-framework/actions/user';
+import {editName} from 'coral-framework/actions/user';
import {updateCountCache, viewAllComments} from 'coral-framework/actions/asset';
import {notificationActions, authActions, assetActions, pym} from 'coral-framework';
@@ -117,15 +117,6 @@ class Embed extends Component {
}
}
- ignoreUser = async ({id}) => {
- const {ignoreUser, dispatch} = this.props;
- await ignoreUser({id});
-
- // dispatch ignoreUserSuccess so other reducers can know about the newly
- // ignored user (e.g. to hide coments by that user)
- dispatch(ignoreUserSuccess({id}));
- }
-
render () {
const {activeTab} = this.state;
const {closedAt, countCache = {}} = this.props.asset;
@@ -264,7 +255,7 @@ class Embed extends Component {
postDontAgree={this.props.postDontAgree}
addCommentTag={this.props.addCommentTag}
removeCommentTag={this.props.removeCommentTag}
- ignoreUser={this.ignoreUser}
+ ignoreUser={this.props.ignoreUser}
loadMore={this.props.loadMore}
deleteAction={this.props.deleteAction}
showSignInDialog={this.props.showSignInDialog}
diff --git a/client/coral-framework/actions/user.js b/client/coral-framework/actions/user.js
index dd63cf215..3e80b718c 100644
--- a/client/coral-framework/actions/user.js
+++ b/client/coral-framework/actions/user.js
@@ -1,7 +1,6 @@
import {addNotification} from '../actions/notification';
import coralApi from '../helpers/response';
import * as actions from '../constants/auth';
-import {IGNORE_USER_SUCCESS} from '../constants/user';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from './../translations';
@@ -20,6 +19,3 @@ export const editName = (username) => (dispatch) => {
dispatch(editUsernameFailure(lang.t(`error.${error.translation_key}`)));
});
};
-
-// a user was successfully ignored
-export const ignoreUserSuccess = ({id}) => ({type: IGNORE_USER_SUCCESS, id});
diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js
index 66e58e930..1557a42c9 100644
--- a/client/coral-framework/constants/user.js
+++ b/client/coral-framework/constants/user.js
@@ -7,3 +7,4 @@ export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const UPDATE_USERNAME = 'UPDATE_USERNAME';
export const IGNORE_USER_SUCCESS = 'IGNORE_USER_SUCCESS';
+export const STOP_IGNORING_USER_SUCCESS = 'STOP_IGNORING_USER_SUCCESS';
diff --git a/client/coral-framework/graphql/mutations/index.js b/client/coral-framework/graphql/mutations/index.js
index 114303d2d..64a39d108 100644
--- a/client/coral-framework/graphql/mutations/index.js
+++ b/client/coral-framework/graphql/mutations/index.js
@@ -7,6 +7,9 @@ import DELETE_ACTION from './deleteAction.graphql';
import ADD_COMMENT_TAG from './addCommentTag.graphql';
import REMOVE_COMMENT_TAG from './removeCommentTag.graphql';
import IGNORE_USER from './ignoreUser.graphql';
+import STOP_IGNORING_USER from './stopIgnoringUser.graphql';
+
+import MY_IGNORED_USERS from '../queries/myIgnoredUsers.graphql';
import commentView from '../fragments/commentView.graphql';
@@ -156,7 +159,24 @@ export const ignoreUser = graphql(IGNORE_USER, {
return mutate({
variables: {
id,
- }
+ },
+ refetchQueries: [{
+ query: MY_IGNORED_USERS,
+ }]
+ });
+ }}),
+});
+
+export const stopIgnoringUser = graphql(STOP_IGNORING_USER, {
+ props: ({mutate}) => ({
+ stopIgnoringUser: ({id}) => {
+ return mutate({
+ variables: {
+ id,
+ },
+ refetchQueries: [{
+ query: MY_IGNORED_USERS,
+ }]
});
}}),
});
diff --git a/client/coral-framework/graphql/mutations/stopIgnoringUser.graphql b/client/coral-framework/graphql/mutations/stopIgnoringUser.graphql
new file mode 100644
index 000000000..042452ff5
--- /dev/null
+++ b/client/coral-framework/graphql/mutations/stopIgnoringUser.graphql
@@ -0,0 +1,7 @@
+mutation stopIgnoringUser ($id: ID!) {
+ stopIgnoringUser(id:$id) {
+ errors {
+ translation_key
+ }
+ }
+}
diff --git a/client/coral-framework/reducers/user.js b/client/coral-framework/reducers/user.js
index 0c77b3f69..efa967cf0 100644
--- a/client/coral-framework/reducers/user.js
+++ b/client/coral-framework/reducers/user.js
@@ -39,9 +39,14 @@ export default function user (state = initialState, action) {
return state.set('myAssets', action.assets);
case actions.LOGOUT_SUCCESS:
return initialState;
- case actions.IGNORE_USER_SUCCESS:
- return state.updateIn(['ignoredUsers'], i => i.add(action.id));
- default :
- return state;
+ case 'APOLLO_MUTATION_RESULT':
+ switch (action.operationName) {
+ case 'ignoreUser':
+ return state.updateIn(['ignoredUsers'], i => i.add(action.variables.id));
+ case 'stopIgnoringUser':
+ return state.updateIn(['ignoredUsers'], i => i.delete(action.variables.id));
+ }
+ break;
}
+ return state;
}
diff --git a/client/coral-settings/components/IgnoredUsers.js b/client/coral-settings/components/IgnoredUsers.js
index 5719337d4..4bbf6cc50 100644
--- a/client/coral-settings/components/IgnoredUsers.js
+++ b/client/coral-settings/components/IgnoredUsers.js
@@ -1,10 +1,19 @@
-import React, {Component} from 'react';
+import React, {Component, PropTypes} from 'react';
import styles from './IgnoredUsers.css';
export class IgnoredUsers extends Component {
+ static propTypes = {
+ users: PropTypes.arrayOf(PropTypes.shape({
+ username: PropTypes.string,
+ id: PropTypes.string,
+ })).isRequired,
+
+ // accepts { id }
+ stopIgnoring: PropTypes.func.isRequired,
+ }
render() {
- const {users} = this.props;
+ const {users, stopIgnoring} = this.props;
return (
{
@@ -15,10 +24,12 @@ export class IgnoredUsers extends Component {
{
users.map(({username, id}) => (
-
+
- { username }
-
- Stop ignoring
+ stopIgnoring({id})}
+ className={styles.link}>Stop ignoring
))
diff --git a/client/coral-settings/containers/ProfileContainer.js b/client/coral-settings/containers/ProfileContainer.js
index 480c9e1fe..2d756077d 100644
--- a/client/coral-settings/containers/ProfileContainer.js
+++ b/client/coral-settings/containers/ProfileContainer.js
@@ -4,6 +4,7 @@ import React, {Component} from 'react';
import I18n from 'coral-framework/modules/i18n/i18n';
import {myCommentHistory, myIgnoredUsers} from 'coral-framework/graphql/queries';
+import {stopIgnoringUser} from 'coral-framework/graphql/mutations';
import {link} from 'coral-framework/services/PymConnection';
import NotLoggedIn from '../components/NotLoggedIn';
@@ -31,7 +32,7 @@ class ProfileContainer extends Component {
}
render() {
- const {loggedIn, asset, showSignInDialog, data, myIgnoredUsersData} = this.props;
+ const {loggedIn, asset, showSignInDialog, data, myIgnoredUsersData, stopIgnoringUser} = this.props;
const {me} = this.props.data;
if (!loggedIn || !me) {
@@ -60,6 +61,7 @@ class ProfileContainer extends Component {
Ignored users
)
@@ -100,4 +102,5 @@ export default compose(
connect(mapStateToProps, mapDispatchToProps),
myCommentHistory,
myIgnoredUsers,
+ stopIgnoringUser,
)(ProfileContainer);
diff --git a/graph/mutators/user.js b/graph/mutators/user.js
index 04235c217..fd888a402 100644
--- a/graph/mutators/user.js
+++ b/graph/mutators/user.js
@@ -17,12 +17,18 @@ const ignoreUser = async ({user}, userToIgnore) => {
return await UsersService.ignoreUsers(user.id, [userToIgnore.id]);
};
+const stopIgnoringUser = async ({user}, userToStopIgnoring) => {
+ console.log('stopIgnoringUser!!');
+ return await UsersService.stopIgnoringUsers(user.id, [userToStopIgnoring.id]);
+};
+
module.exports = (context) => {
let mutators = {
User: {
setUserStatus: () => Promise.reject(errors.ErrNotAuthorized),
suspendUser: () => Promise.reject(errors.ErrNotAuthorized),
ignoreUser: (action) => ignoreUser(context, action),
+ stopIgnoringUser: (action) => stopIgnoringUser(context, action),
}
};
diff --git a/graph/resolvers/root_mutation.js b/graph/resolvers/root_mutation.js
index 0e763889f..38183bff6 100644
--- a/graph/resolvers/root_mutation.js
+++ b/graph/resolvers/root_mutation.js
@@ -26,6 +26,9 @@ const RootMutation = {
ignoreUser(_, {id}, {mutators: {User}}) {
return wrapResponse(null)(User.ignoreUser({id}));
},
+ stopIgnoringUser(_, {id}, {mutators: {User}}) {
+ return wrapResponse(null)(User.stopIgnoringUser({id}));
+ },
setCommentStatus(_, {id, status}, {mutators: {Comment}}) {
return wrapResponse(null)(Comment.setCommentStatus({id, status}));
},
diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql
index 86aafbb0e..87926a5da 100644
--- a/graph/typeDefs.graphql
+++ b/graph/typeDefs.graphql
@@ -712,6 +712,11 @@ type IgnoreUserResponse implements Response {
errors: [UserError]
}
+# Response to stopIgnoringUser mutation
+type StopIgnoringUserResponse 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 {
@@ -748,6 +753,9 @@ type RootMutation {
# Ignore comments by another user
ignoreUser(id: ID!): IgnoreUserResponse
+
+ # Stop Ignoring comments by another user
+ stopIgnoringUser(id: ID!): StopIgnoringUserResponse
}
################################################################################
diff --git a/services/users.js b/services/users.js
index 45b113f35..da3b23bc6 100644
--- a/services/users.js
+++ b/services/users.js
@@ -854,4 +854,20 @@ module.exports = class UsersService {
}
});
}
+
+ /**
+ * Stop ignoring other users
+ * @param {String} userId the id of the user that is ignoring another users
+ * @param {String[]} usersToStopIgnoring Array of user IDs to stop ignoring
+ */
+ static async stopIgnoringUsers(userId, usersToStopIgnoring) {
+ assert(Array.isArray(usersToStopIgnoring), 'usersToStopIgnoring is an array');
+ assert(usersToStopIgnoring.every(u => typeof u === 'string'), 'usersToStopIgnoring is an array of string user IDs');
+ await UserModel.update({id: userId}, {
+ $pullAll: {
+ ignoresUsers: usersToStopIgnoring
+ }
+ });
+ console.log('Mongo wrote stopIgnoringUsers', usersToStopIgnoring);
+ }
};
diff --git a/test/graph/mutations/ignoreUser.js b/test/graph/mutations/ignoreUser.js
index 6ede39477..fc6035839 100644
--- a/test/graph/mutations/ignoreUser.js
+++ b/test/graph/mutations/ignoreUser.js
@@ -6,30 +6,30 @@ const Context = require('../../../graph/context');
const UsersService = require('../../../services/users');
const SettingsService = require('../../../services/settings');
+const ignoreUserMutation = `
+ mutation ignoreUser ($id: ID!) {
+ ignoreUser(id:$id) {
+ errors {
+ translation_key
+ }
+ }
+ }
+`;
+
+const getMyIgnoredUsersQuery = `
+ query myIgnoredUsers {
+ myIgnoredUsers {
+ id,
+ username
+ }
+ }
+`;
+
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
- }
- }
- `;
-
// @TODO (bengo) - test a user can't ignore themselves
it('users can ignoreUser', async () => {
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
@@ -54,3 +54,60 @@ describe('graph.mutations.ignoreUser', () => {
});
});
+
+describe('graph.mutations.stopIgnoringUser', () => {
+ beforeEach(async () => {
+ await SettingsService.init();
+ });
+
+ it('users can stop ignoring another user they ignore', async () => {
+
+ // We're going to ignore 2 users,
+ // then stopIgnoring 1 of them
+ // then assert myIgnoredUsers only lists the one remaining
+ const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
+ const usersToIgnore = await Promise.all([
+ UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB'),
+ UsersService.createLocalUser('usernameC@example.com', 'password', 'usernameC'),
+ ]);
+ const context = new Context({user});
+
+ // ignore two users
+ const ignoreUserResponses = await Promise.all(usersToIgnore.map(u => graphql(schema, ignoreUserMutation, {}, context, {id: u.id})));
+ ignoreUserResponses.forEach(response => {
+ if (response.errors && response.errors.length) {
+ console.error(response.errors);
+ }
+ expect(response.errors).to.be.empty;
+ });
+
+ const stopIgnoringUserMutation = `
+ mutation stopIgnoringUser ($id: ID!) {
+ stopIgnoringUser(id:$id) {
+ errors {
+ translation_key
+ }
+ }
+ }
+ `;
+
+ // stop ignoring one user
+ const stopIgnoringUserResponse = await graphql(schema, stopIgnoringUserMutation, {}, context, {id: usersToIgnore[0].id});
+ if (stopIgnoringUserResponse.errors && stopIgnoringUserResponse.errors.length) {
+ console.error(stopIgnoringUserResponse.errors);
+ }
+ expect(stopIgnoringUserResponse.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(usersToIgnore[1].id);
+ expect(myIgnoredUsers[0].username).to.equal(usersToIgnore[1].username);
+ });
+
+});