mirror of
https://github.com/wassname/talk.git
synced 2026-07-18 12:40:13 +08:00
added message to ban/suspend workflows
This commit is contained in:
@@ -17,15 +17,15 @@ const setUserUsernameStatus = async (ctx, id, status) => {
|
||||
}
|
||||
};
|
||||
|
||||
const setUserBanStatus = async (ctx, id, status) => {
|
||||
const user = await UsersService.setBanStatus(id, status, ctx.user.id);
|
||||
const setUserBanStatus = async (ctx, id, status = false, message = null) => {
|
||||
const user = await UsersService.setBanStatus(id, status, ctx.user.id, message);
|
||||
if (user.banned) {
|
||||
ctx.pubsub.publish('userBanned', user);
|
||||
}
|
||||
};
|
||||
|
||||
const setUserSuspensionStatus = async (ctx, id, until) => {
|
||||
const user = await UsersService.setSuspensionStatus(id, until, ctx.user.id);
|
||||
const setUserSuspensionStatus = async (ctx, id, until = null, message = null) => {
|
||||
const user = await UsersService.setSuspensionStatus(id, until, ctx.user.id, message);
|
||||
if (user.suspended) {
|
||||
ctx.pubsub.publish('userSuspended', user);
|
||||
}
|
||||
@@ -77,11 +77,11 @@ module.exports = (ctx) => {
|
||||
}
|
||||
|
||||
if (ctx.user.can(SET_USER_BAN_STATUS)) {
|
||||
mutators.User.setUserBanStatus = (id, status) => setUserBanStatus(ctx, id, status);
|
||||
mutators.User.setUserBanStatus = (id, status, message) => setUserBanStatus(ctx, id, status, message);
|
||||
}
|
||||
|
||||
if (ctx.user.can(SET_USER_SUSPENSION_STATUS)) {
|
||||
mutators.User.setUserSuspensionStatus = (id, until) => setUserSuspensionStatus(ctx, id, until);
|
||||
mutators.User.setUserSuspensionStatus = (id, until, message) => setUserSuspensionStatus(ctx, id, until, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,17 @@ const RootMutation = {
|
||||
setUsername: async (_, {id, username}, {mutators: {User}}) => {
|
||||
await User.setUsername(id, username);
|
||||
},
|
||||
setUserSuspensionStatus: async (_, {input: {id, until}}, {mutators: {User}}) => {
|
||||
await User.setUserSuspensionStatus(id, until);
|
||||
suspendUser: async (obj, {input: {id, until, message}}, {mutators: {User}}) => {
|
||||
await User.setUserSuspensionStatus(id, until, message);
|
||||
},
|
||||
setUserBanStatus: async (_, {input: {id, status}}, {mutators: {User}}) => {
|
||||
await User.setUserBanStatus(id, status);
|
||||
unSuspendUser: async (obj, {input: {id}}, {mutators: {User}}) => {
|
||||
await User.setUserSuspensionStatus(id);
|
||||
},
|
||||
banUser: async (obj, {input: {id, message}}, {mutators: {User}}) => {
|
||||
await User.setUserBanStatus(id, true, message);
|
||||
},
|
||||
unBanUser: async (obj, {input: {id}}, {mutators: {User}}) => {
|
||||
await User.setUserBanStatus(id, false);
|
||||
},
|
||||
ignoreUser: async (_, {id}, {mutators: {User}}) => {
|
||||
await User.ignoreUser({id});
|
||||
|
||||
+41
-47
@@ -1012,15 +1012,6 @@ enum ACTION_ITEM_TYPE {
|
||||
USERS
|
||||
}
|
||||
|
||||
input CreateLikeInput {
|
||||
|
||||
# The item's id for which we are to create a like.
|
||||
item_id: ID!
|
||||
|
||||
# The type of the item for which we are to create the like.
|
||||
item_type: ACTION_ITEM_TYPE!
|
||||
}
|
||||
|
||||
# CreateCommentInput is the input content used to create a new comment.
|
||||
input CreateCommentInput {
|
||||
|
||||
@@ -1035,7 +1026,6 @@ input CreateCommentInput {
|
||||
|
||||
# Tags
|
||||
tags: [String]
|
||||
|
||||
}
|
||||
|
||||
input CreateFlagInput {
|
||||
@@ -1090,16 +1080,6 @@ input CreateDontAgreeInput {
|
||||
message: String
|
||||
}
|
||||
|
||||
# Input for suspendUser mutation.
|
||||
input SetUserSuspensionStatusInput {
|
||||
|
||||
# id of target user.
|
||||
id: ID!
|
||||
|
||||
# target user will be suspended until this date.
|
||||
until: Date
|
||||
}
|
||||
|
||||
# Configurable settings that can be overridden for the Asset. You must specify
|
||||
# all fields that should be updated.
|
||||
input AssetSettingsInput {
|
||||
@@ -1158,22 +1138,6 @@ type DeleteActionResponse implements Response {
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
# SetUserSuspensionStatusResponse is the response returned with possibly some
|
||||
# errors relating to the suspend action attempt.
|
||||
type SetUserSuspensionStatusResponse implements Response {
|
||||
|
||||
# An array of errors relating to the mutation that occurred.
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
# RejectUsernameResponse is the response returned with possibly some errors
|
||||
# relating to the reject username action attempt.
|
||||
type RejectUsernameResponse implements Response {
|
||||
|
||||
# An array of errors relating to the mutation that occurred.
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
# SetCommentStatusResponse is the response returned with possibly some errors
|
||||
# relating to the delete action attempt.
|
||||
type SetCommentStatusResponse implements Response {
|
||||
@@ -1356,18 +1320,40 @@ type RevokeTokenResponse implements Response {
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
# SetUserBanStatusInput contains the input to change the ban status of a given
|
||||
# user.
|
||||
input SetUserBanStatusInput {
|
||||
|
||||
# id is the user to set the ban status on.
|
||||
input BanUserInput {
|
||||
id: ID!
|
||||
|
||||
# status is the ban status to set on the target user.
|
||||
status: Boolean!
|
||||
message: String!
|
||||
}
|
||||
|
||||
type SetUserBanStatusResponse implements Response {
|
||||
input UnBanUserInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type BanUsersResponse implements Response {
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
type UnBanUserResponse implements Response {
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
input SuspendUserInput {
|
||||
id: ID!
|
||||
message: String!
|
||||
until: Date!
|
||||
}
|
||||
|
||||
type SuspendUserResponse implements Response {
|
||||
errors: [UserError!]
|
||||
}
|
||||
|
||||
input UnSuspendUserInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
# UnSuspendUserResponse is the response returned with possibly some
|
||||
# errors relating to the suspend action attempt.
|
||||
type UnSuspendUserResponse implements Response {
|
||||
|
||||
# An array of errors relating to the mutation that occurred.
|
||||
errors: [UserError!]
|
||||
@@ -1411,11 +1397,19 @@ type RootMutation {
|
||||
|
||||
# Sets the suspension status on a given user. Requires the `MODERATOR` role.
|
||||
# Mutation is restricted.
|
||||
setUserSuspensionStatus(input: SetUserSuspensionStatusInput!): SetUserSuspensionStatusResponse
|
||||
suspendUser(input: SuspendUserInput!): SuspendUserResponse
|
||||
|
||||
# Sets the suspension status on a given user. Requires the `MODERATOR` role.
|
||||
# Mutation is restricted.
|
||||
unSuspendUser(input: UnSuspendUserInput!): UnSuspendUserResponse
|
||||
|
||||
# Sets the ban status on a given user. Requires the `MODERATOR` role.
|
||||
# Mutation is restricted.
|
||||
setUserBanStatus(input: SetUserBanStatusInput!): SetUserBanStatusResponse
|
||||
banUser(input: BanUserInput!): BanUsersResponse
|
||||
|
||||
# Sets the ban status on a given user. Requires the `MODERATOR` role.
|
||||
# Mutation is restricted.
|
||||
unBanUser(input: UnBanUserInput!): UnBanUserResponse
|
||||
|
||||
# Sets the username status on a given user to `APPROVED`. Requires the
|
||||
# `MODERATOR` role. Mutation is restricted.
|
||||
|
||||
@@ -144,6 +144,9 @@ const UserSchema = new Schema({
|
||||
// assigned_by stores the user id of the user who assigned this status.
|
||||
assigned_by: {type: String, default: null},
|
||||
|
||||
// message stores the email content sent to the user.
|
||||
message: {type: String, default: null},
|
||||
|
||||
// created_at stores the date when this status was assigned.
|
||||
created_at: {type: Date, default: Date.now}
|
||||
}],
|
||||
@@ -166,6 +169,9 @@ const UserSchema = new Schema({
|
||||
// assigned_by stores the user id of the user who assigned this status.
|
||||
assigned_by: {type: String, default: null},
|
||||
|
||||
// message stores the email content sent to the user.
|
||||
message: {type: String, default: null},
|
||||
|
||||
// created_at stores the date when this status was assigned.
|
||||
created_at: {type: Date, default: Date.now}
|
||||
}]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const UsersService = require('../../../services/users');
|
||||
const mailer = require('../../../services/mailer');
|
||||
const errors = require('../../../errors');
|
||||
const authorization = require('../../../middleware/authorization');
|
||||
const Limit = require('../../../services/limit');
|
||||
@@ -56,30 +55,6 @@ router.post('/:user_id/role', authorization.needed('ADMIN', 'MODERATOR'), async
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:user_id/email', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
|
||||
try {
|
||||
let user = await UsersService.findById(req.params.user_id);
|
||||
|
||||
let localProfile = user.profiles.find((profile) => profile.provider === 'local');
|
||||
if (!localProfile) {
|
||||
return next(errors.ErrMissingEmail);
|
||||
}
|
||||
|
||||
await mailer.sendSimple({
|
||||
template: 'notification', // needed to know which template to render!
|
||||
locals: { // specifies the template locals.
|
||||
body: req.body.body
|
||||
},
|
||||
subject: req.body.subject,
|
||||
to: localProfile.id // This only works if the user has registered via e-mail.
|
||||
});
|
||||
|
||||
res.status(204).end();
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
});
|
||||
|
||||
// create a local user.
|
||||
router.post('/', async (req, res, next) => {
|
||||
const {email, password, username} = req.body;
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ module.exports = class ActionsService {
|
||||
});
|
||||
|
||||
// Emit that there was a new action created.
|
||||
events.emit(ACTIONS_NEW, foundAction);
|
||||
await events.emitAsync(ACTIONS_NEW, foundAction);
|
||||
|
||||
return foundAction;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ module.exports = class ActionsService {
|
||||
}
|
||||
|
||||
// Emit that the action was deleted.
|
||||
events.emit(ACTIONS_DELETE, action);
|
||||
await events.emitAsync(ACTIONS_DELETE, action);
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ module.exports = class CommentsService {
|
||||
const savedCommentModel = await commentModel.save();
|
||||
|
||||
// Emit that the comment was created!
|
||||
events.emit(COMMENTS_NEW, savedCommentModel);
|
||||
await events.emitAsync(COMMENTS_NEW, savedCommentModel);
|
||||
|
||||
return savedCommentModel;
|
||||
}
|
||||
@@ -193,7 +193,7 @@ module.exports = class CommentsService {
|
||||
}
|
||||
}
|
||||
|
||||
events.emit(COMMENTS_EDIT, originalComment, editedComment);
|
||||
await events.emitAsync(COMMENTS_EDIT, originalComment, editedComment);
|
||||
|
||||
return editedComment;
|
||||
}
|
||||
@@ -305,7 +305,7 @@ module.exports = class CommentsService {
|
||||
|
||||
// Emit that the comment was edited, and pass the original comment and the
|
||||
// edited comment.
|
||||
events.emit(COMMENTS_EDIT, originalComment, editedComment);
|
||||
await events.emitAsync(COMMENTS_EDIT, originalComment, editedComment);
|
||||
|
||||
return editedComment;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<%= body %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= body %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= body.replace(/\n/g, '<br />') %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= body %>
|
||||
+30
-52
@@ -3,7 +3,6 @@ const bcrypt = require('bcryptjs');
|
||||
const errors = require('../errors');
|
||||
const some = require('lodash/some');
|
||||
const merge = require('lodash/merge');
|
||||
const timeago = require('./timeago');
|
||||
|
||||
const {
|
||||
USERS_NEW,
|
||||
@@ -33,7 +32,6 @@ const MailerService = require('./mailer');
|
||||
const i18n = require('./i18n');
|
||||
const Wordlist = require('./wordlist');
|
||||
const DomainList = require('./domain_list');
|
||||
const SettingsService = require('./settings');
|
||||
const {escapeRegExp} = require('./regex');
|
||||
|
||||
const EMAIL_CONFIRM_JWT_SUBJECT = 'email_confirm';
|
||||
@@ -90,7 +88,7 @@ class UsersService {
|
||||
}
|
||||
}
|
||||
|
||||
static async setSuspensionStatus(id, until, assignedBy = null) {
|
||||
static async setSuspensionStatus(id, until, assignedBy = null, message) {
|
||||
let user = await UserModel.findOneAndUpdate({id}, {
|
||||
$set: {
|
||||
'status.suspension.until': until
|
||||
@@ -99,11 +97,13 @@ class UsersService {
|
||||
'status.suspension.history': {
|
||||
until,
|
||||
assigned_by: assignedBy,
|
||||
message,
|
||||
created_at: Date.now()
|
||||
}
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
new: true,
|
||||
runValidators: true
|
||||
});
|
||||
if (user === null) {
|
||||
user = await UserModel.findOne({id});
|
||||
@@ -125,12 +125,12 @@ class UsersService {
|
||||
}
|
||||
|
||||
// Emit that the user username status was changed.
|
||||
await events.emitAsync(USERS_SUSPENSION_CHANGE, user, until);
|
||||
await await events.emitAsync(USERS_SUSPENSION_CHANGE, user, {until, message, assignedBy});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
static async setBanStatus(id, status, assignedBy = null) {
|
||||
static async setBanStatus(id, status, assignedBy = null, message) {
|
||||
let user = await UserModel.findOneAndUpdate({
|
||||
id,
|
||||
status: {
|
||||
@@ -144,6 +144,7 @@ class UsersService {
|
||||
'status.banned.history': {
|
||||
status,
|
||||
assigned_by: assignedBy,
|
||||
message,
|
||||
created_at: Date.now()
|
||||
}
|
||||
}
|
||||
@@ -164,7 +165,7 @@ class UsersService {
|
||||
}
|
||||
|
||||
// Emit that the user ban status was changed.
|
||||
await events.emitAsync(USERS_BAN_CHANGE, user, status);
|
||||
await await events.emitAsync(USERS_BAN_CHANGE, user, {status, assignedBy, message});
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -203,7 +204,7 @@ class UsersService {
|
||||
}
|
||||
|
||||
// Emit that the user username status was changed.
|
||||
await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, status);
|
||||
await await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, {status, assignedBy});
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -252,7 +253,7 @@ class UsersService {
|
||||
}
|
||||
|
||||
// Emit that the user username status was changed.
|
||||
await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, toStatus);
|
||||
await await events.emitAsync(USERS_USERNAME_STATUS_CHANGE, user, toStatus);
|
||||
|
||||
return user;
|
||||
} catch (err) {
|
||||
@@ -385,7 +386,7 @@ class UsersService {
|
||||
await user.save();
|
||||
|
||||
// Emit that the user was created.
|
||||
events.emit(USERS_NEW, user);
|
||||
await events.emitAsync(USERS_NEW, user);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -550,7 +551,7 @@ class UsersService {
|
||||
}
|
||||
|
||||
// Emit that the user was created.
|
||||
events.emit(USERS_NEW, user);
|
||||
await events.emitAsync(USERS_NEW, user);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -903,53 +904,30 @@ class UsersService {
|
||||
|
||||
module.exports = UsersService;
|
||||
|
||||
events.on(USERS_BAN_CHANGE, async (user, status) => {
|
||||
events.on(USERS_BAN_CHANGE, async (user, {status, message}) => {
|
||||
|
||||
// Check to see if the user was banned now and is currently banned.
|
||||
if (user.banned && status) {
|
||||
if (user.banned && status && message && message.length > 0) {
|
||||
await UsersService.sendEmail(user, {
|
||||
template: 'banned',
|
||||
locals: {
|
||||
body: 'In accordance with The Coral Project’s community guidelines, your account has been banned. You are now longer allowed to comment, flag or engage with our community.'
|
||||
},
|
||||
subject: 'Your account has been banned',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
events.on(USERS_SUSPENSION_CHANGE, async (user, until) => {
|
||||
|
||||
// Check to see if the user was suspended now and is currently suspended.
|
||||
if (user.suspended && until !== null && until > Date.now()) {
|
||||
const {organizationName} = await SettingsService.retrieve();
|
||||
|
||||
const message = i18n.t(
|
||||
'suspenduser.email_message_suspend',
|
||||
user.username,
|
||||
organizationName,
|
||||
timeago(until),
|
||||
);
|
||||
|
||||
await UsersService.sendEmail(user, {
|
||||
template: 'suspension',
|
||||
locals: {
|
||||
body: message,
|
||||
},
|
||||
subject: 'Your account has been banned',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
events.on(USERS_USERNAME_STATUS_CHANGE, async (user, status) => {
|
||||
if (status === 'REJECTED') {
|
||||
const message = i18n.t('reject_username.email_message_reject');
|
||||
|
||||
await UsersService.sendEmail(user, {
|
||||
template: 'suspension',
|
||||
template: 'plain',
|
||||
locals: {
|
||||
body: message
|
||||
},
|
||||
subject: 'Username Rejected'
|
||||
subject: 'Your account has been banned',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
events.on(USERS_SUSPENSION_CHANGE, async (user, {until, message}) => {
|
||||
|
||||
// Check to see if the user was suspended now and is currently suspended.
|
||||
if (user.suspended && until !== null && until > Date.now() && message && message.length > 0) {
|
||||
await UsersService.sendEmail(user, {
|
||||
template: 'plain',
|
||||
locals: {
|
||||
body: message,
|
||||
},
|
||||
subject: 'Your account has been suspended',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,10 +5,14 @@ const Context = require('../../../../graph/context');
|
||||
const SettingsService = require('../../../../services/settings');
|
||||
const UserModel = require('../../../../models/user');
|
||||
const UsersService = require('../../../../services/users');
|
||||
const MailerService = require('../../../../services/mailer');
|
||||
|
||||
const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const chai = require('chai');
|
||||
chai.use(require('sinon-chai'));
|
||||
const {expect} = chai;
|
||||
|
||||
describe('graph.mutations.setUserBanStatus', () => {
|
||||
describe('graph.mutations.banUser', () => {
|
||||
let user;
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
@@ -16,11 +20,34 @@ describe('graph.mutations.setUserBanStatus', () => {
|
||||
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
|
||||
});
|
||||
|
||||
const setUserBanStatusMutation = `
|
||||
mutation SetUserBanStatus($user_id: ID!, $status: Boolean!) {
|
||||
setUserBanStatus(input: {
|
||||
let spy;
|
||||
before(() => {
|
||||
spy = sinon.spy(MailerService, 'sendSimple');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
spy.reset();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
spy.restore();
|
||||
});
|
||||
|
||||
const banUserMutation = `
|
||||
mutation BanUser($user_id: ID!, $message: String!) {
|
||||
banUser(input: {
|
||||
id: $user_id,
|
||||
status: $status
|
||||
message: $message
|
||||
}) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutation UnBanUser($user_id: ID!) {
|
||||
unBanUser(input: {
|
||||
id: $user_id
|
||||
}) {
|
||||
errors {
|
||||
translation_key
|
||||
@@ -51,40 +78,42 @@ describe('graph.mutations.setUserBanStatus', () => {
|
||||
|
||||
const ctx = new Context({user: actor});
|
||||
|
||||
const {data, errors} = await graphql(schema, setUserBanStatusMutation, {}, ctx, {
|
||||
const {data, errors} = await graphql(schema, banUserMutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
status: true
|
||||
});
|
||||
message: 'This is a message'
|
||||
}, 'BanUser');
|
||||
|
||||
if (errors && errors.length > 0) {
|
||||
console.error(errors);
|
||||
}
|
||||
expect(errors).to.be.undefined;
|
||||
if (error) {
|
||||
expect(data.setUserBanStatus).to.have.property('errors').not.null;
|
||||
expect(data.setUserBanStatus.errors[0]).to.have.property('translation_key', error);
|
||||
expect(data.banUser).to.have.property('errors').not.null;
|
||||
expect(data.banUser.errors[0]).to.have.property('translation_key', error);
|
||||
} else {
|
||||
expect(data.setUserBanStatus).to.be.null;
|
||||
expect(data.banUser).to.be.null;
|
||||
|
||||
user = await UserModel.findOne({id: user.id});
|
||||
|
||||
expect(user.status.banned.status).to.be.true;
|
||||
expect(user.status.banned.history).to.have.length(1);
|
||||
expect(user.status.banned.history[0]).to.have.property('status', true);
|
||||
expect(user.status.banned.history[0]).to.have.property('message', 'This is a message');
|
||||
expect(user.status.banned.history[0]).to.have.property('assigned_by', actor.id);
|
||||
expect(user.status.banned.history[0]).to.have.property('created_at').not.null;
|
||||
|
||||
expect(user.banned).to.be.true;
|
||||
|
||||
const res = await graphql(schema, setUserBanStatusMutation, {}, ctx, {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
|
||||
const res = await graphql(schema, banUserMutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
status: false
|
||||
});
|
||||
}, 'UnBanUser');
|
||||
if (res.errors && res.errors.length > 0) {
|
||||
console.error(res.errors);
|
||||
}
|
||||
expect(res.errors).to.be.undefined;
|
||||
expect(res.data.setUserBanStatus).to.be.null;
|
||||
expect(res.data.unBanUser).to.be.null;
|
||||
|
||||
user = await UserModel.findOne({id: user.id});
|
||||
|
||||
|
||||
@@ -6,12 +6,15 @@ const Context = require('../../../../graph/context');
|
||||
const SettingsService = require('../../../../services/settings');
|
||||
const UserModel = require('../../../../models/user');
|
||||
const UsersService = require('../../../../services/users');
|
||||
const MailerService = require('../../../../services/mailer');
|
||||
|
||||
const sinon = require('sinon');
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-datetime'));
|
||||
chai.use(require('sinon-chai'));
|
||||
const {expect} = chai;
|
||||
|
||||
describe('graph.mutations.setUserSuspensionStatus', () => {
|
||||
describe('graph.mutations.suspendUser', () => {
|
||||
let user;
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
@@ -19,11 +22,35 @@ describe('graph.mutations.setUserSuspensionStatus', () => {
|
||||
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
|
||||
});
|
||||
|
||||
const setUserSuspensionStatusMutation = `
|
||||
mutation SetUserUsernameStatus($user_id: ID!, $until: Date) {
|
||||
setUserSuspensionStatus(input: {
|
||||
let spy;
|
||||
before(() => {
|
||||
spy = sinon.spy(MailerService, 'sendSimple');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
spy.reset();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
spy.restore();
|
||||
});
|
||||
|
||||
const mutation = `
|
||||
mutation SuspendUser($user_id: ID!, $until: Date!, $message: String!) {
|
||||
suspendUser(input: {
|
||||
id: $user_id,
|
||||
until: $until,
|
||||
message: $message,
|
||||
}) {
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutation UnSuspendUser($user_id: ID!) {
|
||||
unSuspendUser(input: {
|
||||
id: $user_id,
|
||||
until: $until
|
||||
}) {
|
||||
errors {
|
||||
translation_key
|
||||
@@ -57,20 +84,21 @@ describe('graph.mutations.setUserSuspensionStatus', () => {
|
||||
const now = new Date();
|
||||
const oneHourFromNow = new Date(new Date(now).setHours(now.getHours() + 1));
|
||||
|
||||
const {data, errors} = await graphql(schema, setUserSuspensionStatusMutation, {}, ctx, {
|
||||
const {data, errors} = await graphql(schema, mutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
until: oneHourFromNow
|
||||
});
|
||||
until: oneHourFromNow,
|
||||
message: 'This is a message'
|
||||
}, 'SuspendUser');
|
||||
|
||||
if (errors && errors.length > 0) {
|
||||
console.error(errors);
|
||||
}
|
||||
expect(errors).to.be.undefined;
|
||||
if (error) {
|
||||
expect(data.setUserSuspensionStatus).to.have.property('errors').not.null;
|
||||
expect(data.setUserSuspensionStatus.errors[0]).to.have.property('translation_key', error);
|
||||
expect(data.suspendUser).to.have.property('errors').not.null;
|
||||
expect(data.suspendUser.errors[0]).to.have.property('translation_key', error);
|
||||
} else {
|
||||
expect(data.setUserSuspensionStatus).to.be.null;
|
||||
expect(data.suspendUser).to.be.null;
|
||||
|
||||
user = await UserModel.findOne({id: user.id});
|
||||
|
||||
@@ -79,6 +107,7 @@ describe('graph.mutations.setUserSuspensionStatus', () => {
|
||||
expect(user.status.suspension.history).to.have.length(1);
|
||||
expect(user.status.suspension.history[0]).to.have.property('until').to.be.withinTime(new Date(oneHourFromNow.getTime() - 1000), new Date(oneHourFromNow.getTime() + 1000));
|
||||
expect(user.status.suspension.history[0]).to.have.property('assigned_by', actor.id);
|
||||
expect(user.status.suspension.history[0]).to.have.property('message', 'This is a message');
|
||||
expect(user.status.suspension.history[0]).to.have.property('created_at').not.null;
|
||||
|
||||
expect(user.suspended).to.be.true;
|
||||
@@ -86,15 +115,17 @@ describe('graph.mutations.setUserSuspensionStatus', () => {
|
||||
expect(user.suspended).to.be.false;
|
||||
timekeeper.reset();
|
||||
|
||||
const res = await graphql(schema, setUserSuspensionStatusMutation, {}, ctx, {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
|
||||
const res = await graphql(schema, mutation, {}, ctx, {
|
||||
user_id: user.id,
|
||||
until: null
|
||||
});
|
||||
}, 'UnSuspendUser');
|
||||
if (res.errors && res.errors.length > 0) {
|
||||
console.error(res.errors);
|
||||
}
|
||||
expect(res.errors).to.be.undefined;
|
||||
expect(res.data.setUserSuspensionStatus).to.be.null;
|
||||
expect(res.data.unSuspendUser).to.be.null;
|
||||
|
||||
user = await UserModel.findOne({id: user.id});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user