replaced eslint:recommended with prettier

This commit is contained in:
Wyatt Johnson
2018-01-11 20:00:34 -07:00
parent d56c19016a
commit 0abc2ca243
649 changed files with 16235 additions and 13008 deletions
+6 -7
View File
@@ -1,10 +1,9 @@
const User = require('../../../models/user');
const Context = require('../../../graph/context');
const errors = require('../../../errors');
const SettingsService = require('../../../services/settings');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.Context', () => {
beforeEach(() => SettingsService.init());
@@ -13,10 +12,10 @@ describe('graph.Context', () => {
let c;
beforeEach(() => {
c = new Context({user: new User({id: '1', role: 'ADMIN'})});
c = new Context({ user: new User({ id: '1', role: 'ADMIN' }) });
});
it('creates a context with a user', (done) => {
it('creates a context with a user', done => {
expect(c).to.have.property('user');
expect(c.user).to.have.property('id', '1');
@@ -36,10 +35,10 @@ describe('graph.Context', () => {
let c;
beforeEach(() => {
c = new Context({user: undefined});
c = new Context({ user: undefined });
});
it('creates a context without a user', (done) => {
it('creates a context without a user', done => {
expect(c).to.not.have.property('user');
done();
@@ -54,7 +53,7 @@ describe('graph.Context', () => {
.then(() => {
throw new Error('should not reach this point');
})
.catch((err) => {
.catch(err => {
expect(err).to.be.equal(errors.ErrNotAuthorized);
});
});
+33 -15
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -7,17 +7,20 @@ const UserModel = require('../../../../models/user');
const SettingsService = require('../../../../services/settings');
const CommentsService = require('../../../../services/comments');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.addTag', () => {
let comment, asset;
beforeEach(async () => {
await SettingsService.init();
asset = new AssetModel({url: 'http://new.test.com/'});
asset = new AssetModel({ url: 'http://new.test.com/' });
await asset.save();
comment = await CommentsService.publicCreate({asset_id: asset.id, body: `hello there! ${String(Math.random()).slice(2)}`});
comment = await CommentsService.publicCreate({
asset_id: asset.id,
body: `hello there! ${String(Math.random()).slice(2)}`,
});
});
const query = `
@@ -31,35 +34,50 @@ describe('graph.mutations.addTag', () => {
`;
it('moderators can add tags to comments', async () => {
const user = new UserModel({role: 'MODERATOR'});
const context = new Context({user});
const res = await graphql(schema, query, {}, context, {id: comment.id, asset_id: asset.id, name: 'BEST'}, 'AddCommentTag');
const user = new UserModel({ role: 'MODERATOR' });
const context = new Context({ user });
const res = await graphql(
schema,
query,
{},
context,
{ id: comment.id, asset_id: asset.id, name: 'BEST' },
'AddCommentTag'
);
if (res.errors && res.errors.length) {
console.error(res.errors);
}
expect(res.errors).to.be.empty;
let {tags} = await CommentsService.findById(comment.id);
let { tags } = await CommentsService.findById(comment.id);
expect(tags).to.have.length(1);
});
describe('users who cant add tags', () => {
Object.entries({
'anonymous': undefined,
anonymous: undefined,
'regular commenter': new UserModel({}),
'banned moderator': new UserModel({role: 'MODERATOR', banned: true})
}).forEach(([ userDescription, user ]) => {
'banned moderator': new UserModel({ role: 'MODERATOR', banned: true }),
}).forEach(([userDescription, user]) => {
it(userDescription, async () => {
const context = new Context({user});
const res = await graphql(schema, query, {}, context, {id: comment.id, asset_id: asset.id, name: 'BEST'}, 'AddCommentTag');
const context = new Context({ user });
const res = await graphql(
schema,
query,
{},
context,
{ id: comment.id, asset_id: asset.id, name: 'BEST' },
'AddCommentTag'
);
if (res.errors && res.errors.length) {
console.error(res.errors);
}
expect(res.errors).to.be.empty;
expect(res.data.addTag.errors).to.deep.equal([{'translation_key':'NOT_AUTHORIZED'}]);
expect(res.data.addTag.errors).to.deep.equal([
{ translation_key: 'NOT_AUTHORIZED' },
]);
});
});
});
});
+41 -20
View File
@@ -1,17 +1,21 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
const SettingsService = require('../../../../services/settings');
const UsersService = require('../../../../services/users');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.changeUsername', () => {
let user;
beforeEach(async () => {
await SettingsService.init();
user = await UsersService.createLocalUser('test@test.com', 'testpassword1!', 'kirk');
user = await UsersService.createLocalUser(
'test@test.com',
'testpassword1!',
'kirk'
);
expect(user).to.have.property('username', 'kirk');
expect(user).to.have.property('lowercaseUsername', 'kirk');
@@ -47,12 +51,12 @@ describe('graph.mutations.changeUsername', () => {
`;
[
{role: 'COMMENTER'},
{role: 'STAFF'},
{role: 'COMMENTER'},
{role: 'MODERATOR'},
{role: 'ADMIN'},
].forEach(({role}) => {
{ role: 'COMMENTER' },
{ role: 'STAFF' },
{ role: 'COMMENTER' },
{ role: 'MODERATOR' },
{ role: 'ADMIN' },
].forEach(({ role }) => {
it(`can change the username with roles ${role}`, async () => {
let username = 'spock';
@@ -60,12 +64,19 @@ describe('graph.mutations.changeUsername', () => {
await UsersService.setRole(user.id, role);
user.role = role;
let ctx = new Context({user});
let ctx = new Context({ user });
let res = await graphql(schema, changeUsernameMutation, {}, ctx, {
user_id: user.id,
username,
}, 'ChangeUsername');
let res = await graphql(
schema,
changeUsernameMutation,
{},
ctx,
{
user_id: user.id,
username,
},
'ChangeUsername'
);
if (res.errors && res.errors.length > 0) {
console.error(res.errors);
@@ -74,19 +85,29 @@ describe('graph.mutations.changeUsername', () => {
expect(res.errors).to.be.undefined;
expect(res.data.changeUsername).to.have.property('errors');
expect(res.data.changeUsername.errors).to.have.length(1);
expect(res.data.changeUsername.errors[0]).to.have.property('translation_key', 'NOT_AUTHORIZED');
expect(res.data.changeUsername.errors[0]).to.have.property(
'translation_key',
'NOT_AUTHORIZED'
);
// Set the user to the desired status.
user = await UsersService.setUsernameStatus(user.id, 'REJECTED');
expect(user.status.username.status, 'REJECTED');
ctx = new Context({user});
ctx = new Context({ user });
res = await graphql(schema, changeUsernameMutation, {}, ctx, {
user_id: user.id,
username,
}, 'ChangeUsername');
res = await graphql(
schema,
changeUsernameMutation,
{},
ctx,
{
user_id: user.id,
username,
},
'ChangeUsername'
);
if (res.errors && res.errors.length > 0) {
console.error(res.errors);
+172 -111
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -10,7 +10,7 @@ const ActionModel = require('../../../../models/action');
const SettingsService = require('../../../../services/settings');
const CommentsService = require('../../../../services/comments');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.createComment', () => {
beforeEach(() => SettingsService.init());
@@ -35,152 +35,213 @@ describe('graph.mutations.createComment', () => {
`;
describe('context with different user properties', () => {
beforeEach(() => AssetModel.create({id: '123'}));
beforeEach(() => AssetModel.create({ id: '123' }));
[
{user: null, error: 'NOT_AUTHORIZED'},
{user: new UserModel({}), error: null}
].forEach(({user, error}) => {
{ user: null, error: 'NOT_AUTHORIZED' },
{ user: new UserModel({}), error: null },
].forEach(({ user, error }) => {
describe(user != null ? 'with user' : 'without user', () => {
it(
error ? 'does not create the comment' : 'creates the comment',
() => {
const context = new Context({ user });
it(error ? 'does not create the comment' : 'creates the comment', () => {
const context = new Context({user});
return graphql(schema, query, {}, context)
.then(({data, errors}) => {
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not.null;
expect(data.createComment.errors[0]).to.have.property('translation_key', error);
} else {
expect(data.createComment).to.have.property('comment').not.null;
expect(data.createComment).to.have.property('errors').null;
return graphql(schema, query, {}, context).then(
({ data, errors }) => {
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not
.null;
expect(data.createComment.errors[0]).to.have.property(
'translation_key',
error
);
} else {
expect(data.createComment).to.have.property('comment').not
.null;
expect(data.createComment).to.have.property('errors').null;
}
}
});
});
);
}
);
});
});
});
describe('users with different statuses', () => {
beforeEach(() => AssetModel.create({id: '123'}));
beforeEach(() => AssetModel.create({ id: '123' }));
[
{user: new UserModel({}), error: null},
{user: new UserModel({banned: true}), error: 'NOT_AUTHORIZED'},
{user: new UserModel({suspended: new Date((new Date()).getTime() - (10 * 86400000))}), error: null},
{user: new UserModel({suspended: new Date((new Date()).getTime() + (10 * 86400000))}), error: 'NOT_AUTHORIZED'},
].forEach(({user, error}) => {
describe(`user.banned=${user.banned} user.suspended=${user.suspended}`, () => {
it(error ? 'does not create the comment' : 'creates the comment', async () => {
const context = new Context({user});
const {data, errors} = await graphql(schema, query, {}, context);
{ user: new UserModel({}), error: null },
{ user: new UserModel({ banned: true }), error: 'NOT_AUTHORIZED' },
{
user: new UserModel({
suspended: new Date(new Date().getTime() - 10 * 86400000),
}),
error: null,
},
{
user: new UserModel({
suspended: new Date(new Date().getTime() + 10 * 86400000),
}),
error: 'NOT_AUTHORIZED',
},
].forEach(({ user, error }) => {
describe(`user.banned=${user.banned} user.suspended=${
user.suspended
}`, () => {
it(
error ? 'does not create the comment' : 'creates the comment',
async () => {
const context = new Context({ user });
const { data, errors } = await graphql(schema, query, {}, context);
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not.null;
expect(data.createComment.errors[0]).to.have.property('translation_key', error);
} else {
if (data.createComment.errors && data.createComment.errors.length > 0) {
console.error(data.createComment.errors);
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not.null;
expect(data.createComment.errors[0]).to.have.property(
'translation_key',
error
);
} else {
if (
data.createComment.errors &&
data.createComment.errors.length > 0
) {
console.error(data.createComment.errors);
}
expect(data.createComment).to.have.property('errors').null;
expect(data.createComment).to.have.property('comment').not.null;
}
expect(data.createComment).to.have.property('errors').null;
expect(data.createComment).to.have.property('comment').not.null;
}
});
);
});
});
});
describe('assets with different statuses', () => {
[
{asset: new AssetModel({id: '123', closedAt: new Date((new Date()).getTime() + (10 * 86400000))}), error: null},
{asset: new AssetModel({id: '123', closedAt: new Date((new Date()).getTime() - (10 * 86400000))}), error: 'COMMENTING_CLOSED'}
].forEach(({asset, error}) => {
{
asset: new AssetModel({
id: '123',
closedAt: new Date(new Date().getTime() + 10 * 86400000),
}),
error: null,
},
{
asset: new AssetModel({
id: '123',
closedAt: new Date(new Date().getTime() - 10 * 86400000),
}),
error: 'COMMENTING_CLOSED',
},
].forEach(({ asset, error }) => {
describe(`asset.isClosed=${asset.isClosed}`, () => {
beforeEach(() => asset.save());
it(error ? 'does not create the comment' : 'creates the comment', () => {
const context = new Context({user: new UserModel({})});
it(
error ? 'does not create the comment' : 'creates the comment',
() => {
const context = new Context({ user: new UserModel({}) });
return graphql(schema, query, {}, context)
.then(({data, errors}) => {
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not.null;
expect(data.createComment.errors[0]).to.have.property('translation_key', error);
} else {
expect(data.createComment).to.have.property('comment').not.null;
expect(data.createComment).to.have.property('errors').null;
return graphql(schema, query, {}, context).then(
({ data, errors }) => {
expect(errors).to.be.undefined;
if (error) {
expect(data.createComment).to.have.property('comment').null;
expect(data.createComment).to.have.property('errors').not
.null;
expect(data.createComment.errors[0]).to.have.property(
'translation_key',
error
);
} else {
expect(data.createComment).to.have.property('comment').not
.null;
expect(data.createComment).to.have.property('errors').null;
}
}
});
});
);
}
);
});
});
});
describe('comments made with different asset moderation settings', () => {
[
{moderation: 'PRE', status: 'PREMOD'},
{moderation: 'POST', status: 'NONE'}
].forEach(({moderation, status}) => {
{ moderation: 'PRE', status: 'PREMOD' },
{ moderation: 'POST', status: 'NONE' },
].forEach(({ moderation, status }) => {
describe(`moderation=${moderation}`, () => {
beforeEach(() => AssetModel.create({id: '123', settings: {moderation}}));
beforeEach(() =>
AssetModel.create({ id: '123', settings: { moderation } })
);
it(`creates comment with status=${status}`, () => {
const context = new Context({user: new UserModel()});
const context = new Context({ user: new UserModel() });
return graphql(schema, query, {}, context)
.then(({data, errors}) => {
return graphql(schema, query, {}, context).then(
({ data, errors }) => {
expect(errors).to.be.undefined;
expect(data.createComment).to.have.property('comment').not.null;
expect(data.createComment).to.have.property('errors').null;
expect(data.createComment.comment).to.have.property('status', status);
});
expect(data.createComment.comment).to.have.property(
'status',
status
);
}
);
});
});
});
});
describe('comments with/without banned words', () => {
beforeEach(() => Promise.all([
AssetModel.create({id: '123'}),
SettingsService.update({wordlist: {banned: ['WORST'], suspect: ['EH']}})
]));
beforeEach(() =>
Promise.all([
AssetModel.create({ id: '123' }),
SettingsService.update({
wordlist: { banned: ['WORST'], suspect: ['EH'] },
}),
])
);
[
{message: 'comment does not contain banned/suspect words', body: 'This is such a nice comment!', status: 'NONE', flagged: false},
{message: 'comment contains banned words', body: 'This is the WORST comment!', status: 'REJECTED', flagged: true},
{message: 'comment contains suspect words', body: 'This is the EH comment!', status: 'NONE', flagged: true}
].forEach(({message, body, status, flagged}) => {
{
message: 'comment does not contain banned/suspect words',
body: 'This is such a nice comment!',
status: 'NONE',
flagged: false,
},
{
message: 'comment contains banned words',
body: 'This is the WORST comment!',
status: 'REJECTED',
flagged: true,
},
{
message: 'comment contains suspect words',
body: 'This is the EH comment!',
status: 'NONE',
flagged: true,
},
].forEach(({ message, body, status, flagged }) => {
describe(message, () => {
it(`should create a comment with status=${status} and it ${
flagged ? 'should' : 'should not'
} be flagged`, async () => {
const context = new Context({ user: new UserModel({}) });
it(`should create a comment with status=${status} and it ${flagged ? 'should' : 'should not'} be flagged`, async () => {
const context = new Context({user: new UserModel({})});
const {data, errors} = await graphql(schema, query, {}, context, {
const { data, errors } = await graphql(schema, query, {}, context, {
input: {
asset_id: '123',
body
}
body,
},
});
expect(errors).to.be.undefined;
@@ -190,7 +251,7 @@ describe('graph.mutations.createComment', () => {
const actions = await ActionModel.find({
item_id: data.createComment.comment.id,
action_type: 'FLAG'
action_type: 'FLAG',
});
if (flagged) {
expect(actions).to.have.length(1);
@@ -198,26 +259,25 @@ describe('graph.mutations.createComment', () => {
expect(actions).to.have.length(0);
}
});
});
});
});
describe('users with different roles', () => {
beforeEach(() => AssetModel.create({id: '123'}));
beforeEach(() => AssetModel.create({ id: '123' }));
[
{role: 'COMMENTER', tag: null},
{role: 'ADMIN', tag: 'STAFF'},
{role: 'MODERATOR', tag: 'STAFF'},
].forEach(({role, tag}) => {
{ role: 'COMMENTER', tag: null },
{ role: 'ADMIN', tag: 'STAFF' },
{ role: 'MODERATOR', tag: 'STAFF' },
].forEach(({ role, tag }) => {
describe(`user.role=${JSON.stringify(role)}`, () => {
it(`creates comment ${
tag ? `with tag=${tag}` : 'without tags'
}`, async () => {
const context = new Context({ user: new UserModel({ role }) });
it(`creates comment ${tag ? `with tag=${tag}` : 'without tags'}`, async () => {
const context = new Context({user: new UserModel({role})});
const {data, errors} = await graphql(schema, query, {}, context);
const { data, errors } = await graphql(schema, query, {}, context);
if (errors) {
console.error(errors);
@@ -226,7 +286,9 @@ describe('graph.mutations.createComment', () => {
expect(data.createComment).to.have.property('comment').not.null;
expect(data.createComment).to.have.property('errors').null;
const {tags} = await CommentsService.findById(data.createComment.comment.id);
const { tags } = await CommentsService.findById(
data.createComment.comment.id
);
if (tag) {
expect(tags).to.have.length(1);
expect(tags[0].tag.name).to.have.equal(tag);
@@ -236,6 +298,5 @@ describe('graph.mutations.createComment', () => {
});
});
});
});
});
+77 -50
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const timekeeper = require('timekeeper');
const schema = require('../../../../graph/schema');
@@ -8,7 +8,7 @@ const AssetModel = require('../../../../models/asset');
const SettingsService = require('../../../../services/settings');
const CommentsService = require('../../../../services/comments');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.editComment', () => {
let asset, user;
@@ -16,7 +16,11 @@ describe('graph.mutations.editComment', () => {
timekeeper.reset();
await SettingsService.init();
asset = await AssetModel.create({});
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
});
const editCommentMutation = `
@@ -30,7 +34,7 @@ describe('graph.mutations.editComment', () => {
`;
it('a user can edit their own comment', async () => {
const context = new Context({user});
const context = new Context({ user });
const testStartedAt = new Date();
const comment = await CommentsService.publicCreate({
asset_id: asset.id,
@@ -50,14 +54,17 @@ describe('graph.mutations.editComment', () => {
id: comment.id,
asset_id: asset.id,
edit: {
body: newBody
}
body: 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) {
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;
@@ -69,11 +76,13 @@ describe('graph.mutations.editComment', () => {
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.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 () => {
it("A user can't edit their comment outside of the edit comment time window", async () => {
const comment = await CommentsService.publicCreate({
asset_id: asset.id,
author_id: user.id,
@@ -85,68 +94,78 @@ describe('graph.mutations.editComment', () => {
timekeeper.travel(oneHourFromNow);
const newBody = 'This body should never be set';
const context = new Context({user});
const context = new Context({ user });
const response = await graphql(schema, editCommentMutation, {}, context, {
id: comment.id,
asset_id: asset.id,
edit: {
body: newBody
}
body: 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');
expect(response.data.editComment.errors[0].translation_key).to.equal(
'EDIT_WINDOW_ENDED'
);
const commentAfterEdit = await CommentsService.findById(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 () => {
it("A user can't edit someone else's comment", async () => {
const comment = await CommentsService.publicCreate({
asset_id: asset.id,
author_id: user.id,
body: `hello there! ${String(Math.random()).slice(2)}`,
});
const userB = await UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB');
const userB = await UsersService.createLocalUser(
'usernameB@example.com',
'password',
'usernameB'
);
const newBody = 'This body should never be set';
const context = new Context({user: userB});
const context = new Context({ user: userB });
const response = await graphql(schema, editCommentMutation, {}, context, {
id: comment.id,
asset_id: asset.id,
edit: {
body: newBody
}
body: 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');
expect(response.data.editComment.errors[0].translation_key).to.equal(
'NOT_AUTHORIZED'
);
const commentAfterEdit = await CommentsService.findById(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 () => {
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 context = new Context({ user });
const response = await graphql(schema, editCommentMutation, {}, context, {
id: fakeCommentId,
asset_id: asset.id,
edit: {
body: newBody
}
body: 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');
expect(response.data.editComment.errors[0].translation_key).to.equal(
'NOT_FOUND'
);
});
const bannedWord = 'BANNED_WORD';
@@ -163,72 +182,77 @@ describe('graph.mutations.editComment', () => {
edit: {
body: 'I have been edited to be less offensive',
},
error: true
error: true,
},
{
description: 'editing an ACCEPTED comment to add a bad word sets status to REJECTED',
description:
'editing an ACCEPTED comment to add a bad word sets status to REJECTED',
settings: {
moderation: 'POST',
wordlist: {
banned: [bannedWord]
}
banned: [bannedWord],
},
},
beforeEdit: {
body: 'I\'m a perfectly acceptable comment',
body: "I'm a perfectly acceptable comment",
status: 'ACCEPTED',
},
edit: {
body: `I have been sneakily edited to add a banned word: ${bannedWord}`
body: `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',
description:
'postmod: editing a REJECTED comment with banned word be rejected',
settings: {
moderation: 'POST',
wordlist: {
banned: [bannedWord]
}
banned: [bannedWord],
},
},
beforeEdit: {
body: `I'm a rejected comment with bad word ${bannedWord}`,
status: 'REJECTED',
},
edit: {
body: 'I have been edited to remove the bad word'
body: 'I have been edited to remove the bad word',
},
error: true
error: true,
},
{
description: 'postmod + premodLinksEnable: editing an ACCEPTED comment to add a link sets status to PREMOD',
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',
body: "I'm a perfectly acceptable comment",
status: 'ACCEPTED',
},
edit: {
body: 'I have been edited to add a link: https://coralproject.net/'
body: 'I have been edited to add a link: https://coralproject.net/',
},
afterEdit: {
status: 'SYSTEM_WITHHELD',
},
},
].forEach(({description, settings, beforeEdit, edit, afterEdit, error}) => {
].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
));
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;
@@ -236,14 +260,17 @@ describe('graph.mutations.editComment', () => {
id: comment.id,
asset_id: asset.id,
edit: {
body: newBody
}
body: newBody,
},
});
if (error) {
expect(response.data.editComment.errors).to.not.be.empty;
} else {
if (response.data.editComment.errors && response.data.editComment.errors.length) {
if (
response.data.editComment.errors &&
response.data.editComment.errors.length
) {
console.error(response.data.editComment.errors);
}
expect(response.data.editComment.errors).to.be.null;
+90 -26
View File
@@ -1,11 +1,11 @@
const {graphql} = require('graphql');
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 {expect} = require('chai');
const { expect } = require('chai');
const ignoreUserMutation = `
mutation ignoreUser ($id: ID!) {
@@ -34,11 +34,25 @@ describe('graph.mutations.ignoreUser', () => {
});
it('users can ignoreUser', async () => {
let currentUser = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
const userToIgnore = await UsersService.createLocalUser('usernameB@example.com', 'password', 'usernameB');
let context = new Context({user: currentUser});
let currentUser = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
const userToIgnore = await UsersService.createLocalUser(
'usernameB@example.com',
'password',
'usernameB'
);
let context = new Context({ user: currentUser });
const ignoreUserResponse = await graphql(schema, ignoreUserMutation, {}, context, {id: userToIgnore.id});
const ignoreUserResponse = await graphql(
schema,
ignoreUserMutation,
{},
context,
{ id: userToIgnore.id }
);
if (ignoreUserResponse.errors && ignoreUserResponse.errors.length) {
console.error(ignoreUserResponse.errors);
}
@@ -47,10 +61,16 @@ describe('graph.mutations.ignoreUser', () => {
// Refresh the user from the database and create the new context for the
// request.
currentUser = await UsersService.findById(currentUser.id);
context = new Context({user: currentUser});
context = new Context({ user: currentUser });
// now check my ignored users
const myIgnoredUsersResponse = await graphql(schema, getMyIgnoredUsersQuery, {}, context, {});
const myIgnoredUsersResponse = await graphql(
schema,
getMyIgnoredUsersQuery,
{},
context,
{}
);
if (myIgnoredUsersResponse.errors && myIgnoredUsersResponse.errors.length) {
console.error(myIgnoredUsersResponse.errors);
}
@@ -63,13 +83,29 @@ describe('graph.mutations.ignoreUser', () => {
});
it('users cannot ignore themselves', async () => {
const user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
const context = new Context({user});
const ignoreUserResponse = await graphql(schema, ignoreUserMutation, {}, context, {id: user.id});
const user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
const context = new Context({ user });
const ignoreUserResponse = await graphql(
schema,
ignoreUserMutation,
{},
context,
{ id: user.id }
);
expect(ignoreUserResponse.errors).to.not.be.empty;
// now check my ignored users
const myIgnoredUsersResponse = await graphql(schema, getMyIgnoredUsersQuery, {}, context, {});
const myIgnoredUsersResponse = await graphql(
schema,
getMyIgnoredUsersQuery,
{},
context,
{}
);
if (myIgnoredUsersResponse.errors && myIgnoredUsersResponse.errors.length) {
console.error(myIgnoredUsersResponse.errors);
}
@@ -77,7 +113,6 @@ describe('graph.mutations.ignoreUser', () => {
const myIgnoredUsers = myIgnoredUsersResponse.data.me.ignoredUsers;
expect(myIgnoredUsers.length).to.equal(0);
});
});
describe('graph.mutations.stopIgnoringUser', () => {
@@ -86,20 +121,35 @@ describe('graph.mutations.stopIgnoringUser', () => {
});
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
let currentUser = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
let currentUser = 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'),
UsersService.createLocalUser(
'usernameB@example.com',
'password',
'usernameB'
),
UsersService.createLocalUser(
'usernameC@example.com',
'password',
'usernameC'
),
]);
let context = new Context({user: currentUser});
let context = new Context({ user: currentUser });
// ignore two users
const ignoreUserResponses = await Promise.all(usersToIgnore.map((u) => graphql(schema, ignoreUserMutation, {}, context, {id: u.id})));
ignoreUserResponses.forEach((response) => {
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);
}
@@ -109,7 +159,7 @@ describe('graph.mutations.stopIgnoringUser', () => {
// Refresh the user from the database and create the new context for the
// request.
currentUser = await UsersService.findById(currentUser.id);
context = new Context({user: currentUser});
context = new Context({ user: currentUser });
const stopIgnoringUserMutation = `
mutation stopIgnoringUser ($id: ID!) {
@@ -122,8 +172,17 @@ describe('graph.mutations.stopIgnoringUser', () => {
`;
// stop ignoring one user
const stopIgnoringUserResponse = await graphql(schema, stopIgnoringUserMutation, {}, context, {id: usersToIgnore[0].id});
if (stopIgnoringUserResponse.errors && stopIgnoringUserResponse.errors.length) {
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;
@@ -131,10 +190,16 @@ describe('graph.mutations.stopIgnoringUser', () => {
// Refresh the user from the database and create the new context for the
// request.
currentUser = await UsersService.findById(currentUser.id);
context = new Context({user: currentUser});
context = new Context({ user: currentUser });
// now check my ignored users
const myIgnoredUsersResponse = await graphql(schema, getMyIgnoredUsersQuery, {}, context, {});
const myIgnoredUsersResponse = await graphql(
schema,
getMyIgnoredUsersQuery,
{},
context,
{}
);
if (myIgnoredUsersResponse.errors && myIgnoredUsersResponse.errors.length) {
console.error(myIgnoredUsersResponse.errors);
}
@@ -144,5 +209,4 @@ describe('graph.mutations.stopIgnoringUser', () => {
expect(myIgnoredUsers[0].id).to.equal(usersToIgnore[1].id);
expect(myIgnoredUsers[0].username).to.equal(usersToIgnore[1].username);
});
});
+50 -24
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -10,17 +10,20 @@ const SettingsService = require('../../../../services/settings');
const CommentsService = require('../../../../services/comments');
const TagsService = require('../../../../services/tags');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.removeTag', () => {
let asset, comment;
beforeEach(async () => {
await SettingsService.init();
asset = new AssetModel({url: 'http://new.test.com/'});
asset = new AssetModel({ url: 'http://new.test.com/' });
await asset.save();
comment = await CommentsService.publicCreate({asset_id: asset.id, body: `hello there! ${String(Math.random()).slice(2)}`});
comment = await CommentsService.publicCreate({
asset_id: asset.id,
body: `hello there! ${String(Math.random()).slice(2)}`,
});
});
const query = `
@@ -34,13 +37,22 @@ describe('graph.mutations.removeTag', () => {
`;
it('moderators can add remove tags from comments', async () => {
const user = new UserModel({role: 'MODERATOR'});
const context = new Context({user});
const user = new UserModel({ role: 'MODERATOR' });
const context = new Context({ user });
// add a tag first
await TagsService.add(comment.id, 'COMMENTS', {tag: {name: 'BEST'}}, false);
await TagsService.add(
comment.id,
'COMMENTS',
{ tag: { name: 'BEST' } },
false
);
const response = await graphql(schema, query, {}, context, {id: comment.id, asset_id: asset.id, name: 'BEST'});
const response = await graphql(schema, query, {}, context, {
id: comment.id,
asset_id: asset.id,
name: 'BEST',
});
if (response.errors && response.errors.length) {
console.error(response.errors);
}
@@ -53,36 +65,50 @@ describe('graph.mutations.removeTag', () => {
});
describe('users who cant remove tags', () => {
before(() => SettingModel.findOneAndUpdate({id: 1}, {
$push: {
tags: {
id: 'BEST',
models: ['COMMENTS']
before(() =>
SettingModel.findOneAndUpdate(
{ id: 1 },
{
$push: {
tags: {
id: 'BEST',
models: ['COMMENTS'],
},
},
}
}
}));
)
);
Object.entries({
'anonymous': undefined,
anonymous: undefined,
'regular commenter': new UserModel({}),
'banned moderator': new UserModel({role: 'MODERATOR', banned: true})
'banned moderator': new UserModel({ role: 'MODERATOR', banned: true }),
}).forEach(([userDescription, user]) => {
it(userDescription, async function () {
const context = new Context({user});
it(userDescription, async function() {
const context = new Context({ user });
// add a tag first
await TagsService.add(comment.id, 'COMMENTS', {tag: {name: 'BEST'}}, false);
await TagsService.add(
comment.id,
'COMMENTS',
{ tag: { name: 'BEST' } },
false
);
const response = await graphql(schema, query, {}, context, {id: comment.id, asset_id: asset.id, name: 'BEST'});
const response = await graphql(schema, query, {}, context, {
id: comment.id,
asset_id: asset.id,
name: 'BEST',
});
if (response.errors && response.errors.length) {
console.error(response.errors);
}
expect(response.errors).to.be.empty;
expect(response.data.removeTag.errors).to.deep.equal([{'translation_key':'NOT_AUTHORIZED'}]);
expect(response.data.removeTag.errors).to.deep.equal([
{ translation_key: 'NOT_AUTHORIZED' },
]);
});
});
});
});
+74 -34
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -10,14 +10,18 @@ const mailer = require('../../../../services/mailer');
const sinon = require('sinon');
const chai = require('chai');
chai.use(require('sinon-chai'));
const {expect} = chai;
const { expect } = chai;
describe('graph.mutations.banUser', () => {
let user;
beforeEach(async () => {
await SettingsService.init();
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
});
let spy;
@@ -57,17 +61,19 @@ describe('graph.mutations.banUser', () => {
`;
[
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{self: true, error: 'NOT_AUTHORIZED', role: 'STAFF'},
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'STAFF'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: false, role: 'MODERATOR'},
{error: false, role: 'ADMIN'},
].forEach(({self, error, role}) => {
it(`${error ? 'can not' : 'can'} ban ${self ? 'themself' : 'another user'} as a user with role=${role}`, async () => {
const actor = new UserModel({role});
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: false, role: 'MODERATOR' },
{ error: false, role: 'ADMIN' },
].forEach(({ self, error, role }) => {
it(`${error ? 'can not' : 'can'} ban ${
self ? 'themself' : 'another user'
} as a user with role=${role}`, async () => {
const actor = new UserModel({ role });
// If we're testing self assign, set the id of the actor to the user
// we're acting on.
@@ -75,12 +81,19 @@ describe('graph.mutations.banUser', () => {
actor.id = user.id;
}
const ctx = new Context({user: actor});
const ctx = new Context({ user: actor });
const {data, errors} = await graphql(schema, banUserMutation, {}, ctx, {
user_id: user.id,
message: 'This is a message'
}, 'BanUser');
const { data, errors } = await graphql(
schema,
banUserMutation,
{},
ctx,
{
user_id: user.id,
message: 'This is a message',
},
'BanUser'
);
if (errors && errors.length > 0) {
console.error(errors);
@@ -88,42 +101,69 @@ describe('graph.mutations.banUser', () => {
expect(errors).to.be.undefined;
if (error) {
expect(data.banUser).to.have.property('errors').not.null;
expect(data.banUser.errors[0]).to.have.property('translation_key', error);
expect(data.banUser.errors[0]).to.have.property(
'translation_key',
error
);
} else {
expect(data.banUser).to.be.null;
user = await UserModel.findOne({id: user.id});
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.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;
expect(spy).to.have.been.calledOnce;
const res = await graphql(schema, banUserMutation, {}, ctx, {
user_id: user.id,
}, 'UnBanUser');
const res = await graphql(
schema,
banUserMutation,
{},
ctx,
{
user_id: user.id,
},
'UnBanUser'
);
if (res.errors && res.errors.length > 0) {
console.error(res.errors);
}
expect(res.errors).to.be.undefined;
expect(res.data.unbanUser).to.be.null;
user = await UserModel.findOne({id: user.id});
user = await UserModel.findOne({ id: user.id });
expect(user.status.banned.status).to.be.false;
expect(user.status.banned.history).to.have.length(2);
expect(user.status.banned.history[0]).to.have.property('status').to.be.true;
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.status.banned.history[1]).to.have.property('status').to.be.false;
expect(user.status.banned.history[1]).to.have.property('assigned_by', actor.id);
expect(user.status.banned.history[1]).to.have.property('created_at').not.null;
expect(user.status.banned.history[0]).to.have.property('status').to.be
.true;
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.status.banned.history[1]).to.have.property('status').to.be
.false;
expect(user.status.banned.history[1]).to.have.property(
'assigned_by',
actor.id
);
expect(user.status.banned.history[1]).to.have.property('created_at').not
.null;
expect(user.banned).to.be.false;
}
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const timekeeper = require('timekeeper');
const schema = require('../../../../graph/schema');
@@ -12,14 +12,18 @@ const sinon = require('sinon');
const chai = require('chai');
chai.use(require('chai-datetime'));
chai.use(require('sinon-chai'));
const {expect} = chai;
const { expect } = chai;
describe('graph.mutations.suspendUser', () => {
let user;
beforeEach(async () => {
await SettingsService.init();
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
});
let spy;
@@ -60,17 +64,19 @@ describe('graph.mutations.suspendUser', () => {
`;
[
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{self: true, error: 'NOT_AUTHORIZED', role: 'STAFF'},
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'STAFF'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: false, role: 'MODERATOR'},
{error: false, role: 'ADMIN'},
].forEach(({self, error, role}) => {
it(`${error ? 'can not' : 'can'} suspend ${self ? 'themself' : 'another user'} as a user with role ${role}`, async () => {
const actor = new UserModel({role});
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: false, role: 'MODERATOR' },
{ error: false, role: 'ADMIN' },
].forEach(({ self, error, role }) => {
it(`${error ? 'can not' : 'can'} suspend ${
self ? 'themself' : 'another user'
} as a user with role ${role}`, async () => {
const actor = new UserModel({ role });
// If we're testing self assign, set the id of the actor to the user
// we're acting on.
@@ -78,16 +84,25 @@ describe('graph.mutations.suspendUser', () => {
actor.id = user.id;
}
const ctx = new Context({user: actor});
const ctx = new Context({ user: actor });
const now = new Date();
const oneHourFromNow = new Date(new Date(now).setHours(now.getHours() + 1));
const oneHourFromNow = new Date(
new Date(now).setHours(now.getHours() + 1)
);
const {data, errors} = await graphql(schema, mutation, {}, ctx, {
user_id: user.id,
until: oneHourFromNow,
message: 'This is a message'
}, 'SuspendUser');
const { data, errors } = await graphql(
schema,
mutation,
{},
ctx,
{
user_id: user.id,
until: oneHourFromNow,
message: 'This is a message',
},
'SuspendUser'
);
if (errors && errors.length > 0) {
console.error(errors);
@@ -95,19 +110,37 @@ describe('graph.mutations.suspendUser', () => {
expect(errors).to.be.undefined;
if (error) {
expect(data.suspendUser).to.have.property('errors').not.null;
expect(data.suspendUser.errors[0]).to.have.property('translation_key', error);
expect(data.suspendUser.errors[0]).to.have.property(
'translation_key',
error
);
} else {
expect(data.suspendUser).to.be.null;
user = await UserModel.findOne({id: user.id});
user = await UserModel.findOne({ id: user.id });
// Mongoose messes with the date, check within a 2 second window.
expect(user.status.suspension.until).to.be.withinTime(new Date(oneHourFromNow.getTime() - 1000), new Date(oneHourFromNow.getTime() + 1000));
expect(user.status.suspension.until).to.be.withinTime(
new Date(oneHourFromNow.getTime() - 1000),
new Date(oneHourFromNow.getTime() + 1000)
);
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.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;
timekeeper.travel(new Date(oneHourFromNow.getTime() + 10000));
@@ -116,27 +149,48 @@ describe('graph.mutations.suspendUser', () => {
expect(spy).to.have.been.calledOnce;
const res = await graphql(schema, mutation, {}, ctx, {
user_id: user.id,
until: null
}, 'UnSuspendUser');
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.unsuspendUser).to.be.null;
user = await UserModel.findOne({id: user.id});
user = await UserModel.findOne({ id: user.id });
// Mongoose messes with the date, check within a 2 second window.
expect(user.status.suspension.until).to.be.null;
expect(user.status.suspension.history).to.have.length(2);
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('created_at').not.null;
expect(user.status.suspension.history[1]).to.have.property('until').to.be.null;
expect(user.status.suspension.history[1]).to.have.property('assigned_by', actor.id);
expect(user.status.suspension.history[1]).to.have.property('created_at').not.null;
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('created_at')
.not.null;
expect(user.status.suspension.history[1]).to.have.property('until').to
.be.null;
expect(user.status.suspension.history[1]).to.have.property(
'assigned_by',
actor.id
);
expect(user.status.suspension.history[1]).to.have.property('created_at')
.not.null;
expect(user.suspended).to.be.false;
}
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -8,18 +8,22 @@ const UsersService = require('../../../../services/users');
const chai = require('chai');
chai.use(require('chai-datetime'));
const {expect} = chai;
const { expect } = chai;
[
{status: 'APPROVED', name: 'approve', mutation: 'approveUsername'},
{status: 'REJECTED', name: 'reject', mutation: 'rejectUsername'}
].forEach(({status, name, mutation}) => {
{ status: 'APPROVED', name: 'approve', mutation: 'approveUsername' },
{ status: 'REJECTED', name: 'reject', mutation: 'rejectUsername' },
].forEach(({ status, name, mutation }) => {
describe(`graph.mutations.${mutation}`, () => {
let user;
beforeEach(async () => {
await SettingsService.init();
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
});
const setUserUsernameStatusMutation = `
@@ -33,17 +37,21 @@ const {expect} = chai;
`;
[
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{self: true, error: 'NOT_AUTHORIZED', role: 'STAFF'},
{self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'STAFF'},
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: false, role: 'MODERATOR'},
{error: false, role: 'ADMIN'},
].forEach(({self, error, role}) => {
it(`${error ? 'can not' : 'can'} ${name} a username with the user role ${role}${self ? ' on themself' : ''}`, async () => {
const actor = new UserModel({role});
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ self: true, error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'STAFF' },
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: false, role: 'MODERATOR' },
{ error: false, role: 'ADMIN' },
].forEach(({ self, error, role }) => {
it(`${
error ? 'can not' : 'can'
} ${name} a username with the user role ${role}${
self ? ' on themself' : ''
}`, async () => {
const actor = new UserModel({ role });
// If we're testing self assign, set the id of the actor to the user
// we're acting on.
@@ -51,11 +59,17 @@ const {expect} = chai;
actor.id = user.id;
}
const ctx = new Context({user: actor});
const ctx = new Context({ user: actor });
const {data, errors} = await graphql(schema, setUserUsernameStatusMutation, {}, ctx, {
user_id: user.id,
});
const { data, errors } = await graphql(
schema,
setUserUsernameStatusMutation,
{},
ctx,
{
user_id: user.id,
}
);
if (errors && errors.length > 0) {
console.error(errors);
@@ -63,22 +77,40 @@ const {expect} = chai;
expect(errors).to.be.undefined;
if (error) {
expect(data[mutation]).to.have.property('errors').not.null;
expect(data[mutation].errors[0]).to.have.property('translation_key', error);
expect(data[mutation].errors[0]).to.have.property(
'translation_key',
error
);
} else {
expect(data[mutation]).to.be.null;
user = await UserModel.findOne({id: user.id});
user = await UserModel.findOne({ id: user.id });
expect(user.status.username.status).to.equal(status);
expect(user.status.username.history).to.have.length(2);
expect(user.status.username.history[0]).to.have.property('status', 'SET');
expect(user.status.username.history[0]).to.have.property('assigned_by').is.null;
expect(user.status.username.history[0]).to.have.property('created_at').not.null;
expect(user.status.username.history[1]).to.have.property('status', status);
expect(user.status.username.history[1]).to.have.property('assigned_by', actor.id);
expect(user.status.username.history[1]).to.have.property('created_at').not.null;
expect(user.status.username.history[0]).to.have.property(
'status',
'SET'
);
expect(user.status.username.history[0]).to.have.property(
'assigned_by'
).is.null;
expect(user.status.username.history[0]).to.have.property('created_at')
.not.null;
expect(user.status.username.history[1]).to.have.property(
'status',
status
);
expect(user.status.username.history[1]).to.have.property(
'assigned_by',
actor.id
);
expect(user.status.username.history[1]).to.have.property('created_at')
.not.null;
expect(user.status.username.history[1].created_at).afterTime(user.status.username.history[0].created_at);
expect(user.status.username.history[1].created_at).afterTime(
user.status.username.history[0].created_at
);
}
});
});
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -6,13 +6,13 @@ const UserModel = require('../../../../models/user');
const SettingsService = require('../../../../services/settings');
const AssetModel = require('../../../../models/asset');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.updateAssetSettings', () => {
let asset;
beforeEach(async () => {
await SettingsService.init();
asset = await AssetModel.create({url: 'http://new.test.com/'});
asset = await AssetModel.create({ url: 'http://new.test.com/' });
});
const QUERY = `
@@ -25,16 +25,15 @@ describe('graph.mutations.updateAssetSettings', () => {
}`;
describe('context with different user roles', () => {
[
{role: 'COMMENTER', error: 'NOT_AUTHORIZED'},
{role: 'STAFF', error: 'NOT_AUTHORIZED'},
{role: 'ADMIN'},
{role: 'MODERATOR'},
].forEach(({role, error}) => {
{ role: 'COMMENTER', error: 'NOT_AUTHORIZED' },
{ role: 'STAFF', error: 'NOT_AUTHORIZED' },
{ role: 'ADMIN' },
{ role: 'MODERATOR' },
].forEach(({ role, error }) => {
it(`role = ${role}`, async () => {
const user = new UserModel({role});
const ctx = new Context({user});
const user = new UserModel({ role });
const ctx = new Context({ user });
const settings = {
premodLinksEnable: false,
@@ -55,16 +54,25 @@ describe('graph.mutations.updateAssetSettings', () => {
if (error) {
expect(res.data.updateAssetSettings.errors).to.not.be.empty;
expect(res.data.updateAssetSettings.errors[0]).to.have.property('translation_key', error);
expect(res.data.updateAssetSettings.errors[0]).to.have.property(
'translation_key',
error
);
} else {
if (res.data.updateAssetSettings && res.data.updateAssetSettings.errors) {
if (
res.data.updateAssetSettings &&
res.data.updateAssetSettings.errors
) {
console.error(res.data.updateAssetSettings.errors);
}
expect(res.data.updateAssetSettings).to.be.null;
const retrievedAsset = await AssetModel.findOne({id: asset.id});
Object.keys(settings).forEach((key) => {
expect(retrievedAsset.settings).to.have.property(key, settings[key]);
const retrievedAsset = await AssetModel.findOne({ id: asset.id });
Object.keys(settings).forEach(key => {
expect(retrievedAsset.settings).to.have.property(
key,
settings[key]
);
});
}
});
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -6,13 +6,13 @@ const UserModel = require('../../../../models/user');
const SettingsService = require('../../../../services/settings');
const AssetModel = require('../../../../models/asset');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.updateAssetStatus', () => {
let asset;
beforeEach(async () => {
await SettingsService.init();
asset = await AssetModel.create({url: 'http://new.test.com/'});
asset = await AssetModel.create({ url: 'http://new.test.com/' });
});
const QUERY = `
@@ -26,17 +26,16 @@ describe('graph.mutations.updateAssetStatus', () => {
`;
describe('context with different user roles', () => {
[
{role: 'COMMENTER', error: 'NOT_AUTHORIZED'},
{role: 'ADMIN'},
{role: 'MODERATOR'},
].forEach(({role, error}) => {
{ role: 'COMMENTER', error: 'NOT_AUTHORIZED' },
{ role: 'ADMIN' },
{ role: 'MODERATOR' },
].forEach(({ role, error }) => {
it(`role = ${role}`, async () => {
const user = new UserModel({role});
const ctx = new Context({user});
const user = new UserModel({ role });
const ctx = new Context({ user });
const closedAt = (new Date()).toISOString();
const closedAt = new Date().toISOString();
const closedMessage = 'my closed message!';
const res = await graphql(schema, QUERY, {}, ctx, {
@@ -53,16 +52,22 @@ describe('graph.mutations.updateAssetStatus', () => {
if (error) {
expect(res.data.updateAssetStatus.errors).to.not.be.empty;
expect(res.data.updateAssetStatus.errors[0]).to.have.property('translation_key', error);
expect(res.data.updateAssetStatus.errors[0]).to.have.property(
'translation_key',
error
);
} else {
if (res.data.updateAssetStatus && res.data.updateAssetStatus.errors) {
console.error(res.data.updateAssetStatus.errors);
}
expect(res.data.updateAssetStatus).to.be.null;
const retrievedAsset = await AssetModel.findOne({id: asset.id});
const retrievedAsset = await AssetModel.findOne({ id: asset.id });
expect(retrievedAsset.closedAt).to.not.be.null;
expect(retrievedAsset).to.have.property('closedMessage', closedMessage);
expect(retrievedAsset).to.have.property(
'closedMessage',
closedMessage
);
}
});
});
+32 -21
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -6,10 +6,9 @@ const UserModel = require('../../../../models/user');
const SettingsService = require('../../../../services/settings');
const isEqual = require('lodash/isEqual');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.mutations.updateSettings', () => {
beforeEach(async () => {
await SettingsService.init();
});
@@ -24,15 +23,14 @@ describe('graph.mutations.updateSettings', () => {
}`;
describe('context with different user roles', () => {
[
{error: 'NOT_AUTHORIZED', role: 'COMMENTER'},
{error: 'NOT_AUTHORIZED', role: 'MODERATOR'},
{role: 'ADMIN'},
].forEach(({role, error}) => {
{ error: 'NOT_AUTHORIZED', role: 'COMMENTER' },
{ error: 'NOT_AUTHORIZED', role: 'MODERATOR' },
{ role: 'ADMIN' },
].forEach(({ role, error }) => {
it(`role = ${role}`, async () => {
const user = new UserModel({role});
const ctx = new Context({user});
const user = new UserModel({ role });
const ctx = new Context({ user });
const newSettings = {
premodLinksEnable: false,
@@ -52,7 +50,10 @@ describe('graph.mutations.updateSettings', () => {
if (error) {
expect(res.data.updateSettings.errors).to.not.be.empty;
expect(res.data.updateSettings.errors[0]).to.have.property('translation_key', error);
expect(res.data.updateSettings.errors[0]).to.have.property(
'translation_key',
error
);
} else {
if (res.data.updateSettings && res.data.updateSettings.errors) {
console.error(res.data.updateSettings.errors);
@@ -60,7 +61,7 @@ describe('graph.mutations.updateSettings', () => {
expect(res.data.updateSettings).to.be.null;
const retrievedSettings = await SettingsService.retrieve();
Object.keys(newSettings).forEach((key) => {
Object.keys(newSettings).forEach(key => {
expect(retrievedSettings).to.have.property(key, newSettings[key]);
});
}
@@ -69,8 +70,8 @@ describe('graph.mutations.updateSettings', () => {
});
describe('nested objects', () => {
const user = new UserModel({role: 'ADMIN'});
const ctx = new Context({user});
const user = new UserModel({ role: 'ADMIN' });
const ctx = new Context({ user });
it('should handle nested objects', async () => {
const initSettings = {
@@ -98,11 +99,16 @@ describe('graph.mutations.updateSettings', () => {
expect(res.data.updateSettings).to.be.null;
let retrievedSettings = await SettingsService.retrieve();
Object.keys(initSettings).forEach((key) => {
Object.keys(initSettings[key]).forEach((nestedKey) => {
Object.keys(initSettings).forEach(key => {
Object.keys(initSettings[key]).forEach(nestedKey => {
expect(retrievedSettings).to.have.property(key);
expect(retrievedSettings[key]).to.have.property(nestedKey);
expect(isEqual(retrievedSettings[key][nestedKey], initSettings[key][nestedKey])).to.be.true;
expect(
isEqual(
retrievedSettings[key][nestedKey],
initSettings[key][nestedKey]
)
).to.be.true;
});
});
@@ -121,7 +127,7 @@ describe('graph.mutations.updateSettings', () => {
},
domains: {
whitelist: change.domains.whitelist,
}
},
});
res = await graphql(schema, QUERY, {}, ctx, {
@@ -140,11 +146,16 @@ describe('graph.mutations.updateSettings', () => {
expect(res.data.updateSettings).to.be.null;
retrievedSettings = await SettingsService.retrieve();
Object.keys(changedSettings).forEach((key) => {
Object.keys(changedSettings[key]).forEach((nestedKey) => {
Object.keys(changedSettings).forEach(key => {
Object.keys(changedSettings[key]).forEach(nestedKey => {
expect(retrievedSettings).to.have.property(key);
expect(retrievedSettings[key]).to.have.property(nestedKey);
expect(isEqual(retrievedSettings[key][nestedKey], changedSettings[key][nestedKey])).to.be.true;
expect(
isEqual(
retrievedSettings[key][nestedKey],
changedSettings[key][nestedKey]
)
).to.be.true;
});
});
});
+43 -25
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -7,42 +7,44 @@ const SettingsService = require('../../../../services/settings');
const Asset = require('../../../../models/asset');
const CommentsService = require('../../../../services/comments');
const {expect} = require('chai');
const { expect } = require('chai');
describe('graph.queries.asset', () => {
let assets, users, comments;
beforeEach(async () => {
await SettingsService.init();
assets = await Asset.create([
{id: '1', url: 'https://example.com/?id=1'},
{id: '2', url: 'https://example.com/?id=2'}
{ id: '1', url: 'https://example.com/?id=1' },
{ id: '2', url: 'https://example.com/?id=2' },
]);
users = await UsersService.createLocalUsers([
{
email: 'usernameA@example.com',
password: 'password',
username: 'usernameA'
username: 'usernameA',
},
{
email: 'usernameB@example.com',
password: 'password',
username: 'usernameB'
username: 'usernameB',
},
{
email: 'usernameC@example.com',
password: 'password',
username: 'usernameC'
}
username: 'usernameC',
},
]);
comments = await CommentsService.publicCreate([0, 0, 1, 1].map((idx) => ({
author_id: users[idx].id,
asset_id: assets[idx].id,
body: `hello there! ${String(Math.random()).slice(2)}`,
})));
comments = await CommentsService.publicCreate(
[0, 0, 1, 1].map(idx => ({
author_id: users[idx].id,
asset_id: assets[idx].id,
body: `hello there! ${String(Math.random()).slice(2)}`,
}))
);
});
it('will not show the same asset stream across multiple assets', async () => {
const context = new Context({user: users[0]});
const context = new Context({ user: users[0] });
const query = `
fragment assetFragment on Asset {
@@ -64,20 +66,30 @@ describe('graph.queries.asset', () => {
}
`;
let res = await graphql(schema, query, {}, context, {id: assets[0].id, otherID: assets[1].id});
let res = await graphql(schema, query, {}, context, {
id: assets[0].id,
otherID: assets[1].id,
});
if (res.errors) {
console.error(res.errors);
}
expect(res.errors).is.empty;
let {asset: {comments: asset}, otherAsset: {comments: otherAsset}} = res.data;
let {
asset: { comments: asset },
otherAsset: { comments: otherAsset },
} = res.data;
expect(asset.nodes).to.have.length(2);
expect(asset.hasNextPage).to.be.false;
expect(asset.nodes.map(({id}) => id)).to.have.members(comments.slice(0, 2).map(({id}) => id));
expect(asset.nodes.map(({ id }) => id)).to.have.members(
comments.slice(0, 2).map(({ id }) => id)
);
expect(otherAsset.nodes).to.have.length(2);
expect(otherAsset.hasNextPage).to.be.false;
expect(otherAsset.nodes.map(({id}) => id)).to.have.members(comments.slice(2, 4).map(({id}) => id));
expect(otherAsset.nodes.map(({ id }) => id)).to.have.members(
comments.slice(2, 4).map(({ id }) => id)
);
for (let node of asset.nodes) {
for (let otherNode of otherAsset.nodes) {
@@ -87,7 +99,7 @@ describe('graph.queries.asset', () => {
});
it('can get comments edge', async () => {
const context = new Context({user: users[0]});
const context = new Context({ user: users[0] });
const assetCommentsQuery = `
query assetCommentsQuery($id: ID!) {
@@ -105,8 +117,15 @@ describe('graph.queries.asset', () => {
}
}
`;
const res = await graphql(schema, assetCommentsQuery, {}, context, {id: assets[0].id});
const {nodes, startCursor, endCursor, hasNextPage} = res.data.asset.comments;
const res = await graphql(schema, assetCommentsQuery, {}, context, {
id: assets[0].id,
});
const {
nodes,
startCursor,
endCursor,
hasNextPage,
} = res.data.asset.comments;
expect(nodes.length).to.equal(2);
expect(startCursor).to.equal(nodes[0].created_at);
expect(endCursor).to.equal(nodes[1].created_at);
@@ -114,7 +133,7 @@ describe('graph.queries.asset', () => {
});
it('can query comments edge to exclude comments ignored by user', async () => {
const context = new Context({user: users[0]});
const context = new Context({ user: users[0] });
// Add the second user to the list of ignored users.
context.user.ignoresUsers.push(users[1].id);
@@ -136,12 +155,11 @@ describe('graph.queries.asset', () => {
const res = await graphql(schema, query, {}, context, {
id: assets[0].id,
url: assets[0].url,
excludeIgnored: true
excludeIgnored: true,
});
expect(res.errors).is.empty;
const {nodes} = res.data.asset.comments;
const { nodes } = res.data.asset.comments;
expect(nodes.length).to.equal(2);
}
});
});
+10 -12
View File
@@ -1,14 +1,14 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
const SettingsService = require('../../../../services/settings');
const UserModel = require('../../../../models/user');
const {expect} = require('chai');
const { expect } = require('chai');
const defaultSettings = {
organizationName: 'The Coral Project'
organizationName: 'The Coral Project',
};
describe('graph.queries.settings', () => {
@@ -47,7 +47,6 @@ describe('graph.queries.settings', () => {
`;
describe('context with different user roles', () => {
const BLACKLISTED_PROPERTIES = [
'premodLinksEnable',
'autoCloseStream',
@@ -56,13 +55,13 @@ describe('graph.queries.settings', () => {
];
[
{bl: true, role: 'COMMENTER'},
{bl: false, role: 'ADMIN'},
{bl: false, role: 'MODERATOR'},
].forEach(({bl, role}) => {
{ bl: true, role: 'COMMENTER' },
{ bl: false, role: 'ADMIN' },
{ bl: false, role: 'MODERATOR' },
].forEach(({ bl, role }) => {
it(`role = ${role}`, async () => {
let user = new UserModel({role});
const ctx = new Context({user});
let user = new UserModel({ role });
const ctx = new Context({ user });
const res = await graphql(schema, QUERY, {}, ctx);
if (res.errors) {
@@ -71,7 +70,7 @@ describe('graph.queries.settings', () => {
expect(res.errors).to.be.empty;
expect(res.data.settings).to.be.object;
Object.keys(res.data.settings).forEach((key) => {
Object.keys(res.data.settings).forEach(key => {
if (bl && BLACKLISTED_PROPERTIES.includes(key)) {
expect(res.data.settings).to.have.property(key, null);
return;
@@ -87,5 +86,4 @@ describe('graph.queries.settings', () => {
});
});
});
});
+17 -14
View File
@@ -1,4 +1,4 @@
const {graphql} = require('graphql');
const { graphql } = require('graphql');
const schema = require('../../../../graph/schema');
const Context = require('../../../../graph/context');
@@ -8,18 +8,21 @@ const UsersService = require('../../../../services/users');
const chai = require('chai');
chai.use(require('chai-datetime'));
const {expect} = chai;
const { expect } = chai;
describe('graph.queries.user', () => {
let user;
beforeEach(async () => {
await SettingsService.init();
user = await UsersService.createLocalUser('usernameA@example.com', 'password', 'usernameA');
user = await UsersService.createLocalUser(
'usernameA@example.com',
'password',
'usernameA'
);
});
describe('state', () => {
const meQuery = `
query Me {
me {
@@ -35,9 +38,9 @@ describe('graph.queries.user', () => {
`;
it('can query me', async () => {
const ctx = new Context({user});
const ctx = new Context({ user });
const {data, errors} = await graphql(schema, meQuery, {}, ctx);
const { data, errors } = await graphql(schema, meQuery, {}, ctx);
expect(errors).to.be.undefined;
expect(data.me).to.not.be.null;
@@ -60,16 +63,16 @@ describe('graph.queries.user', () => {
`;
[
{role: 'COMMENTER', can: false},
{role: 'STAFF', can: false},
{role: 'MODERATOR', can: true},
{role: 'ADMIN', can: true},
].forEach(({role, can}) => {
{ role: 'COMMENTER', can: false },
{ role: 'STAFF', can: false },
{ role: 'MODERATOR', can: true },
{ role: 'ADMIN', can: true },
].forEach(({ role, can }) => {
it(`${can ? 'can' : 'can not'} query with role = ${role}`, async () => {
const actor = new UserModel({role});
const ctx = new Context({user: actor});
const actor = new UserModel({ role });
const ctx = new Context({ user: actor });
const {data, errors} = await graphql(schema, query, {}, ctx, {
const { data, errors } = await graphql(schema, query, {}, ctx, {
user_id: user.id,
});