mirror of
https://github.com/wassname/talk.git
synced 2026-06-28 16:14:49 +08:00
1c2ff7d2ae
* Update default plugins * Update plugin docs with missing plugin * Fixed broken link in docs * Update Code of Conduct in docs * Fix mixup that both plugins are moderation-actions * fix: adapt server tests to use the rich text plugin * fix: e2e * fix: sync docs
309 lines
9.6 KiB
JavaScript
309 lines
9.6 KiB
JavaScript
const { graphql } = require('graphql');
|
|
const timekeeper = require('timekeeper');
|
|
|
|
const AssetModel = require('../../../../models/asset');
|
|
const CommentModel = require('../../../../models/comment');
|
|
const CommentsService = require('../../../../services/comments');
|
|
const Context = require('../../../../graph/context');
|
|
const schema = require('../../../../graph/schema');
|
|
const SettingsService = require('../../../../services/settings');
|
|
const UsersService = require('../../../../services/users');
|
|
|
|
const { expect } = require('chai');
|
|
|
|
describe('graph.mutations.editComment', () => {
|
|
let asset, user;
|
|
beforeEach(async () => {
|
|
timekeeper.reset();
|
|
await SettingsService.init();
|
|
const ctx = Context.forSystem();
|
|
asset = await AssetModel.create({});
|
|
user = await UsersService.createLocalUser(
|
|
ctx,
|
|
'usernameA@example.com',
|
|
'password',
|
|
'usernameA'
|
|
);
|
|
});
|
|
|
|
const editCommentMutation = `
|
|
mutation EditComment ($id: ID!, $asset_id: ID!, $edit: EditCommentInput) {
|
|
editComment(id:$id, asset_id:$asset_id, edit:$edit) {
|
|
errors {
|
|
translation_key
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
it('a user can edit their own comment', async () => {
|
|
const context = new Context({ user });
|
|
const testStartedAt = new Date();
|
|
const body = `hello there! ${String(Math.random()).slice(2)}`;
|
|
const comment = await CommentsService.publicCreate({
|
|
asset_id: asset.id,
|
|
author_id: user.id,
|
|
body,
|
|
richTextBody: body,
|
|
});
|
|
|
|
// body_history should be there
|
|
expect(comment.body_history.length).to.equal(1);
|
|
expect(comment.body_history[0].body).to.equal(comment.body);
|
|
expect(comment.body_history[0].created_at).to.be.instanceOf(Date);
|
|
expect(comment.body_history[0].created_at).to.be.at.least(testStartedAt);
|
|
|
|
// now edit
|
|
const newBody = 'I have been edited.';
|
|
const response = await graphql(schema, editCommentMutation, {}, context, {
|
|
id: comment.id,
|
|
asset_id: asset.id,
|
|
edit: {
|
|
body: newBody,
|
|
richTextBody: newBody,
|
|
},
|
|
});
|
|
if (response.errors && response.errors.length) {
|
|
console.error(response.errors);
|
|
}
|
|
expect(response.errors).to.be.empty;
|
|
if (
|
|
response.data.editComment.errors &&
|
|
response.data.editComment.errors.length > 0
|
|
) {
|
|
console.error(response.data.editComment.errors);
|
|
}
|
|
expect(response.data.editComment.errors).to.be.null;
|
|
|
|
// assert body has changed
|
|
const commentAfterEdit = await CommentModel.findOne({ id: comment.id });
|
|
expect(commentAfterEdit.body).to.equal(newBody);
|
|
expect(commentAfterEdit.body_history).to.be.instanceOf(Array);
|
|
expect(commentAfterEdit.body_history.length).to.equal(2);
|
|
expect(commentAfterEdit.body_history[1].body).to.equal(newBody);
|
|
expect(commentAfterEdit.body_history[1].created_at).to.be.instanceOf(Date);
|
|
expect(commentAfterEdit.body_history[1].created_at).to.be.at.least(
|
|
testStartedAt
|
|
);
|
|
expect(commentAfterEdit.status).to.equal('NONE');
|
|
});
|
|
|
|
it("A user can't edit their comment outside of the edit comment time window", async () => {
|
|
const body = `hello there! ${String(Math.random()).slice(2)}`;
|
|
const comment = await CommentsService.publicCreate({
|
|
asset_id: asset.id,
|
|
author_id: user.id,
|
|
body,
|
|
richTextBody: body,
|
|
});
|
|
|
|
const now = new Date();
|
|
const oneHourFromNow = new Date(new Date(now).setHours(now.getHours() + 1));
|
|
timekeeper.travel(oneHourFromNow);
|
|
|
|
const newBody = 'This body should never be set';
|
|
const context = new Context({ user });
|
|
const response = await graphql(schema, editCommentMutation, {}, context, {
|
|
id: comment.id,
|
|
asset_id: asset.id,
|
|
edit: {
|
|
body: newBody,
|
|
richTextBody: newBody,
|
|
},
|
|
});
|
|
if (response.errors && response.errors.length > 0) {
|
|
console.error(response.errors);
|
|
}
|
|
expect(response.errors).to.be.empty;
|
|
expect(response.data.editComment.errors).to.not.be.empty;
|
|
expect(response.data.editComment.errors[0].translation_key).to.equal(
|
|
'EDIT_WINDOW_ENDED'
|
|
);
|
|
const commentAfterEdit = await CommentModel.findOne({ id: comment.id });
|
|
|
|
// it *hasn't* changed from the original
|
|
expect(commentAfterEdit.body).to.equal(comment.body);
|
|
});
|
|
|
|
it("A user can't edit someone else's comment", async () => {
|
|
const body = `hello there! ${String(Math.random()).slice(2)}`;
|
|
const comment = await CommentsService.publicCreate({
|
|
asset_id: asset.id,
|
|
author_id: user.id,
|
|
body,
|
|
richTextBody: body,
|
|
});
|
|
|
|
const ctx = Context.forSystem();
|
|
const userB = await UsersService.createLocalUser(
|
|
ctx,
|
|
'usernameB@example.com',
|
|
'password',
|
|
'usernameB'
|
|
);
|
|
const newBody = 'This body should never be set';
|
|
const context = new Context({ user: userB });
|
|
const response = await graphql(schema, editCommentMutation, {}, context, {
|
|
id: comment.id,
|
|
asset_id: asset.id,
|
|
edit: {
|
|
body: newBody,
|
|
richTextBody: newBody,
|
|
},
|
|
});
|
|
expect(response.errors).to.be.empty;
|
|
expect(response.data.editComment.errors).to.not.be.empty;
|
|
expect(response.data.editComment.errors[0].translation_key).to.equal(
|
|
'NOT_AUTHORIZED'
|
|
);
|
|
const commentAfterEdit = await CommentModel.findOne({ id: comment.id });
|
|
|
|
// it *hasn't* changed from the original
|
|
expect(commentAfterEdit.body).to.equal(comment.body);
|
|
});
|
|
|
|
it("A user Can't edit a comment id that doesn't exist", async () => {
|
|
const fakeCommentId = 'nooooope';
|
|
const newBody = 'This body should never be set';
|
|
const context = new Context({ user });
|
|
const response = await graphql(schema, editCommentMutation, {}, context, {
|
|
id: fakeCommentId,
|
|
asset_id: asset.id,
|
|
edit: {
|
|
body: newBody,
|
|
richTextBody: newBody,
|
|
},
|
|
});
|
|
if (response.errors && response.errors.length > 0) {
|
|
console.error(response.errors);
|
|
}
|
|
expect(response.errors).to.be.empty;
|
|
expect(response.data.editComment.errors[0].translation_key).to.equal(
|
|
'NOT_FOUND'
|
|
);
|
|
});
|
|
|
|
const bannedWord = 'BANNED_WORD';
|
|
[
|
|
{
|
|
description: 'premod: editing a REJECTED comment is rejected',
|
|
settings: {
|
|
moderation: 'PRE',
|
|
},
|
|
beforeEdit: {
|
|
body: 'I was offensive and thus REJECTED',
|
|
richTextBody: 'I was offensive and thus REJECTED',
|
|
status: 'REJECTED',
|
|
},
|
|
edit: {
|
|
body: 'I have been edited to be less offensive',
|
|
richTextBody: 'I have been edited to be less offensive',
|
|
},
|
|
error: true,
|
|
},
|
|
{
|
|
description:
|
|
'editing an ACCEPTED comment to add a bad word sets status to REJECTED',
|
|
settings: {
|
|
moderation: 'POST',
|
|
wordlist: {
|
|
banned: [bannedWord],
|
|
},
|
|
},
|
|
beforeEdit: {
|
|
body: "I'm a perfectly acceptable comment",
|
|
richTextBody: "I'm a perfectly acceptable comment",
|
|
status: 'ACCEPTED',
|
|
},
|
|
edit: {
|
|
body: `I have been sneakily edited to add a banned word: ${bannedWord}`,
|
|
richTextBody: `I have been sneakily edited to add a banned word: ${bannedWord}`,
|
|
},
|
|
afterEdit: {
|
|
status: 'REJECTED',
|
|
},
|
|
},
|
|
{
|
|
description:
|
|
'postmod: editing a REJECTED comment with banned word be rejected',
|
|
settings: {
|
|
moderation: 'POST',
|
|
wordlist: {
|
|
banned: [bannedWord],
|
|
},
|
|
},
|
|
beforeEdit: {
|
|
body: `I'm a rejected comment with bad word ${bannedWord}`,
|
|
richTextBody: `I'm a rejected comment with bad word ${bannedWord}`,
|
|
status: 'REJECTED',
|
|
},
|
|
edit: {
|
|
body: 'I have been edited to remove the bad word',
|
|
richTextBody: 'I have been edited to remove the bad word',
|
|
},
|
|
error: true,
|
|
},
|
|
{
|
|
description:
|
|
'postmod + premodLinksEnable: editing an ACCEPTED comment to add a link sets status to PREMOD',
|
|
settings: {
|
|
moderation: 'POST',
|
|
premodLinksEnable: true,
|
|
},
|
|
beforeEdit: {
|
|
body: "I'm a perfectly acceptable comment",
|
|
richTextBody: "I'm a perfectly acceptable comment",
|
|
status: 'ACCEPTED',
|
|
},
|
|
edit: {
|
|
body: 'I have been edited to add a link: https://coralproject.net/',
|
|
richTextBody:
|
|
'I have been edited to add a link: https://coralproject.net/',
|
|
},
|
|
afterEdit: {
|
|
status: 'SYSTEM_WITHHELD',
|
|
},
|
|
},
|
|
].forEach(({ description, settings, beforeEdit, edit, afterEdit, error }) => {
|
|
it(description, async () => {
|
|
await SettingsService.update(settings);
|
|
const context = new Context({ user });
|
|
const comment = await CommentsService.publicCreate(
|
|
Object.assign(
|
|
{
|
|
asset_id: asset.id,
|
|
author_id: user.id,
|
|
},
|
|
beforeEdit
|
|
)
|
|
);
|
|
|
|
// now edit
|
|
const newBody = edit.body;
|
|
const response = await graphql(schema, editCommentMutation, {}, context, {
|
|
id: comment.id,
|
|
asset_id: asset.id,
|
|
edit: {
|
|
body: newBody,
|
|
richTextBody: newBody,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
expect(response.data.editComment.errors).to.not.be.empty;
|
|
} else {
|
|
if (
|
|
response.data.editComment.errors &&
|
|
response.data.editComment.errors.length
|
|
) {
|
|
console.error(response.data.editComment.errors);
|
|
}
|
|
expect(response.data.editComment.errors).to.be.null;
|
|
const commentAfterEdit = await CommentModel.findOne({ id: comment.id });
|
|
expect(commentAfterEdit.body).to.equal(newBody);
|
|
expect(commentAfterEdit.status).to.equal(afterEdit.status);
|
|
}
|
|
});
|
|
});
|
|
});
|