mirror of
https://github.com/wassname/talk.git
synced 2026-07-24 13:20:47 +08:00
replaced eslint:recommended with prettier
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
|
||||
@@ -6,13 +6,14 @@ const authz = require('../../../middleware/authorization');
|
||||
describe('middleware.authorization', () => {
|
||||
describe('#has', () => {
|
||||
it('allows if no roles are specified', () => {
|
||||
expect(authz.has({role: 'COMMENTER'})).to.be.true;
|
||||
expect(authz.has({ role: 'COMMENTER' })).to.be.true;
|
||||
});
|
||||
it('allows if the correct roles are met', () => {
|
||||
expect(authz.has({role: 'ADMIN'}, 'ADMIN', 'MODERATOR')).to.be.true;
|
||||
expect(authz.has({ role: 'ADMIN' }, 'ADMIN', 'MODERATOR')).to.be.true;
|
||||
});
|
||||
it('disallows if the role required is missing', () => {
|
||||
expect(authz.has({role: 'COMMENTER'}, 'ADMIN', 'MODERATOR')).to.be.false;
|
||||
expect(authz.has({ role: 'COMMENTER' }, 'ADMIN', 'MODERATOR')).to.be
|
||||
.false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,22 +25,22 @@ describe('middleware.authorization', () => {
|
||||
};
|
||||
|
||||
it('allows if no roles are specified', () => {
|
||||
needed()({user: {role: 'COMMENTER'}}, {}, (err) => {
|
||||
needed()({ user: { role: 'COMMENTER' } }, {}, err => {
|
||||
expect(err).to.be.undefined;
|
||||
});
|
||||
});
|
||||
it('allows if the correct roles are met', () => {
|
||||
needed()({user: {role: 'ADMIN'}}, {}, (err) => {
|
||||
needed()({ user: { role: 'ADMIN' } }, {}, err => {
|
||||
expect(err).to.be.undefined;
|
||||
});
|
||||
});
|
||||
it('disallows if the role required is missing', () => {
|
||||
needed('ADMIN', 'MODERATOR')({user: {role: 'COMMENTER'}}, {}, (err) => {
|
||||
needed('ADMIN', 'MODERATOR')({ user: { role: 'COMMENTER' } }, {}, err => {
|
||||
expect(err).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
it('disallows if there is no user on the request', () => {
|
||||
needed('ADMIN', 'MODERATOR')({}, {}, (err) => {
|
||||
needed('ADMIN', 'MODERATOR')({}, {}, err => {
|
||||
expect(err).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ const UserModel = require('../../../models/user');
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-datetime'));
|
||||
const {expect} = chai;
|
||||
const { expect } = chai;
|
||||
|
||||
describe('migration.1510174676_user_status', () => {
|
||||
describe('active user', () => {
|
||||
@@ -13,13 +13,12 @@ describe('migration.1510174676_user_status', () => {
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
canEditName: false
|
||||
canEditName: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('status', 'ACTIVE');
|
||||
expect(user).to.have.property('canEditName', false);
|
||||
@@ -27,7 +26,7 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
@@ -44,13 +43,12 @@ describe('migration.1510174676_user_status', () => {
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
canEditName: true
|
||||
canEditName: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('status', 'ACTIVE');
|
||||
expect(user).to.have.property('canEditName', true);
|
||||
@@ -58,7 +56,7 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
@@ -75,13 +73,12 @@ describe('migration.1510174676_user_status', () => {
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'BANNED',
|
||||
canEditName: true
|
||||
canEditName: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('BANNED');
|
||||
@@ -90,7 +87,7 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
@@ -108,13 +105,12 @@ describe('migration.1510174676_user_status', () => {
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'APPROVED',
|
||||
canEditName: false
|
||||
canEditName: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('APPROVED');
|
||||
@@ -123,7 +119,7 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
@@ -142,14 +138,13 @@ describe('migration.1510174676_user_status', () => {
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
suspension: {
|
||||
until: new Date()
|
||||
}
|
||||
until: new Date(),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('suspension');
|
||||
expect(user.suspension).to.have.property('until');
|
||||
@@ -160,14 +155,17 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('suspension');
|
||||
expect(user.status.suspension).to.have.property('until');
|
||||
expect(user.status.suspension.until).to.not.be.null;
|
||||
expect(user.status.suspension.until).to.be.withinTime(new Date(until.getTime() - 1000), new Date(until.getTime() + 1000));
|
||||
expect(user.status.suspension.until).to.be.withinTime(
|
||||
new Date(until.getTime() - 1000),
|
||||
new Date(until.getTime() + 1000)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -178,13 +176,12 @@ describe('migration.1510174676_user_status', () => {
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'BANNED',
|
||||
canEditName: false
|
||||
canEditName: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
let user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('BANNED');
|
||||
@@ -192,7 +189,7 @@ describe('migration.1510174676_user_status', () => {
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
user = await UserModel.collection.findOne({ id: '123' });
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
|
||||
@@ -2,13 +2,14 @@ const authorization = require('../../middleware/authorization');
|
||||
|
||||
// Add the passport middleware here before it's setup.
|
||||
authorization.middleware.push((req, res, next) => {
|
||||
req.user = JSON.parse(new Buffer(req.get('X-Mock-Authorization'), 'base64').toString('ascii'));
|
||||
req.user = JSON.parse(
|
||||
new Buffer(req.get('X-Mock-Authorization'), 'base64').toString('ascii')
|
||||
);
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
const MockStrategy = {
|
||||
|
||||
/**
|
||||
* Injects the new user into the request header for the mock middleware to
|
||||
* interpret.
|
||||
@@ -17,9 +18,11 @@ const MockStrategy = {
|
||||
*/
|
||||
inject(user) {
|
||||
return {
|
||||
'X-Mock-Authorization': new Buffer(JSON.stringify(user)).toString('base64')
|
||||
'X-Mock-Authorization': new Buffer(JSON.stringify(user)).toString(
|
||||
'base64'
|
||||
),
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = MockStrategy;
|
||||
|
||||
@@ -12,9 +12,12 @@ const AssetsService = require('../../../../../services/assets');
|
||||
const SettingsService = require('../../../../../services/settings');
|
||||
|
||||
describe('/api/v1/assets', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
const settings = {id: '1', moderation: 'PRE', domains: {whitelist: ['test.com']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
domains: { whitelist: ['test.com'] },
|
||||
};
|
||||
|
||||
await SettingsService.init(settings);
|
||||
|
||||
@@ -23,24 +26,24 @@ describe('/api/v1/assets', () => {
|
||||
url: 'https://coralproject.net/news/asset1',
|
||||
title: 'Asset 1',
|
||||
description: 'term1',
|
||||
closedAt: Date.now()
|
||||
closedAt: Date.now(),
|
||||
},
|
||||
{
|
||||
url: 'https://coralproject.net/news/asset2',
|
||||
title: 'Asset 2',
|
||||
description: 'term2',
|
||||
closedAt: null
|
||||
}
|
||||
closedAt: null,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('#get', () => {
|
||||
|
||||
it('should return all assets without a search query', async () => {
|
||||
for (const role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/assets')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
|
||||
const body = res.body;
|
||||
|
||||
@@ -55,9 +58,10 @@ describe('/api/v1/assets', () => {
|
||||
|
||||
it('should return assets that we search for', async () => {
|
||||
for (const role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/assets?value=term2')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
|
||||
const body = res.body;
|
||||
|
||||
@@ -70,16 +74,20 @@ describe('/api/v1/assets', () => {
|
||||
|
||||
const asset = assets[0];
|
||||
|
||||
expect(asset).to.have.property('url', 'https://coralproject.net/news/asset2');
|
||||
expect(asset).to.have.property(
|
||||
'url',
|
||||
'https://coralproject.net/news/asset2'
|
||||
);
|
||||
expect(asset).to.have.property('title', 'Asset 2');
|
||||
}
|
||||
});
|
||||
|
||||
it('should not return assets that we do not search for', async () => {
|
||||
for (const role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/assets?value=term3')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
const body = res.body;
|
||||
|
||||
expect(body).to.have.property('count', 0);
|
||||
@@ -91,9 +99,10 @@ describe('/api/v1/assets', () => {
|
||||
|
||||
it('should return only closed assets', async () => {
|
||||
for (const role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/assets?filter=closed')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
const body = res.body;
|
||||
|
||||
expect(body).to.have.property('count', 1);
|
||||
@@ -107,9 +116,10 @@ describe('/api/v1/assets', () => {
|
||||
|
||||
it('should return only opened assets', async () => {
|
||||
for (const role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/assets?filter=open')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
const body = res.body;
|
||||
|
||||
expect(body).to.have.property('count', 1);
|
||||
@@ -120,28 +130,29 @@ describe('/api/v1/assets', () => {
|
||||
expect(assets[0]).to.have.property('title', 'Asset 2');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#put', () => {
|
||||
it('should close the asset', async () => {
|
||||
|
||||
const today = Date.now();
|
||||
|
||||
const asset = await AssetsService.findOrCreateByUrl('http://test.com');
|
||||
expect(asset).to.have.property('isClosed', false);
|
||||
expect(asset).to.have.property('closedAt', null);
|
||||
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.put(`/api/v1/assets/${asset.id}/status`)
|
||||
.set(passport.inject({role: 'ADMIN'}))
|
||||
.send({closedAt: today});
|
||||
.set(passport.inject({ role: 'ADMIN' }))
|
||||
.send({ closedAt: today });
|
||||
|
||||
expect(res).to.have.status(204);
|
||||
|
||||
const closedAsset = await AssetsService.findByUrl('http://test.com');
|
||||
expect(closedAsset).to.have.property('isClosed', true);
|
||||
expect(closedAsset).to.have.property('closedAt').and.to.not.equal(null);
|
||||
expect(closedAsset)
|
||||
.to.have.property('closedAt')
|
||||
.and.to.not.equal(null);
|
||||
});
|
||||
|
||||
it('should require ADMIN role', async () => {
|
||||
@@ -151,12 +162,12 @@ describe('/api/v1/assets', () => {
|
||||
expect(asset).to.have.property('isClosed', false);
|
||||
expect(asset).to.have.property('closedAt', null);
|
||||
|
||||
const promise = chai.request(app)
|
||||
const promise = chai
|
||||
.request(app)
|
||||
.put(`/api/v1/assets/${asset.id}/status`)
|
||||
.set(passport.inject({role: 'MODERATOR'}))
|
||||
.send({closedAt: today});
|
||||
.set(passport.inject({ role: 'MODERATOR' }))
|
||||
.send({ closedAt: today });
|
||||
await expect(promise).to.eventually.be.rejected;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -10,9 +10,10 @@ const UsersService = require('../../../../../services/users');
|
||||
describe('/api/v1/auth', () => {
|
||||
describe('#get', () => {
|
||||
it('should return nothing when no user is logged in', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.get('/api/v1/auth')
|
||||
.then((res) => {
|
||||
.then(res => {
|
||||
expect(res.status).to.be.equal(204);
|
||||
expect(res).to.not.have.a.body;
|
||||
});
|
||||
@@ -23,23 +24,29 @@ describe('/api/v1/auth', () => {
|
||||
const SettingsService = require('../../../../../services/settings');
|
||||
|
||||
describe('/api/v1/auth/local', () => {
|
||||
|
||||
let mockUser;
|
||||
beforeEach(async () => {
|
||||
const settings = {requireEmailConfirmation: false, wordlist: {banned: ['bad'], suspect: ['naughty']}};
|
||||
const settings = {
|
||||
requireEmailConfirmation: false,
|
||||
wordlist: { banned: ['bad'], suspect: ['naughty'] },
|
||||
};
|
||||
await SettingsService.init(settings);
|
||||
|
||||
mockUser = await UsersService.createLocalUser('maria@gmail.com', 'password!', 'Maria');
|
||||
mockUser = await UsersService.createLocalUser(
|
||||
'maria@gmail.com',
|
||||
'password!',
|
||||
'Maria'
|
||||
);
|
||||
});
|
||||
|
||||
describe('email confirmation disabled', () => {
|
||||
|
||||
describe('#post', () => {
|
||||
it('should send back the user on a successful login', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post('/api/v1/auth/local')
|
||||
.send({email: 'maria@gmail.com', password: 'password!'})
|
||||
.then((res2) => {
|
||||
.send({ email: 'maria@gmail.com', password: 'password!' })
|
||||
.then(res2 => {
|
||||
expect(res2).to.have.status(200);
|
||||
expect(res2).to.be.json;
|
||||
expect(res2.body).to.have.property('user');
|
||||
@@ -48,42 +55,50 @@ describe('/api/v1/auth/local', () => {
|
||||
});
|
||||
|
||||
it('should not send back the user on a unsuccessful login', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post('/api/v1/auth/local')
|
||||
.send({email: 'maria@gmail.com', password: 'password!3'})
|
||||
.catch((err) => {
|
||||
.send({ email: 'maria@gmail.com', password: 'password!3' })
|
||||
.catch(err => {
|
||||
expect(err).to.not.be.null;
|
||||
expect(err.response).to.have.status(401);
|
||||
expect(err.response.body).to.have.property('message', 'You are not authorized to perform this action.');
|
||||
expect(err.response.body).to.have.property(
|
||||
'message',
|
||||
'You are not authorized to perform this action.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('email confirmation enabled', () => {
|
||||
|
||||
beforeEach(() => SettingsService.update({requireEmailConfirmation: true}));
|
||||
beforeEach(() =>
|
||||
SettingsService.update({ requireEmailConfirmation: true })
|
||||
);
|
||||
|
||||
describe('#post', () => {
|
||||
it('should not allow a login from a user that is not confirmed', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post('/api/v1/auth/local')
|
||||
.send({email: 'maria@gmail.com', password: 'password!'})
|
||||
.catch((err) => {
|
||||
.send({ email: 'maria@gmail.com', password: 'password!' })
|
||||
.catch(err => {
|
||||
expect(err).to.have.status(401);
|
||||
err.response.body.should.have.property('error');
|
||||
|
||||
return UsersService.createEmailConfirmToken(mockUser, mockUser.profiles[0].id);
|
||||
return UsersService.createEmailConfirmToken(
|
||||
mockUser,
|
||||
mockUser.profiles[0].id
|
||||
);
|
||||
})
|
||||
.then(UsersService.verifyEmailConfirmation)
|
||||
.then(() => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post('/api/v1/auth/local')
|
||||
.send({email: 'maria@gmail.com', password: 'password!'});
|
||||
.send({ email: 'maria@gmail.com', password: 'password!' });
|
||||
})
|
||||
.then((res) => {
|
||||
.then(res => {
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.be.json;
|
||||
expect(res.body).to.have.property('user');
|
||||
|
||||
@@ -8,19 +8,18 @@ chai.use(require('chai-http'));
|
||||
const expect = chai.expect;
|
||||
|
||||
const SettingsService = require('../../../../../services/settings');
|
||||
const defaults = {id: '1', moderation: 'PRE'};
|
||||
const defaults = { id: '1', moderation: 'PRE' };
|
||||
|
||||
describe('/api/v1/settings', () => {
|
||||
|
||||
beforeEach(() => SettingsService.init(defaults));
|
||||
|
||||
describe('#get', () => {
|
||||
|
||||
it('should return a settings object', async () => {
|
||||
for (let role of ['ADMIN', 'MODERATOR']) {
|
||||
const res = await chai.request(app)
|
||||
const res = await chai
|
||||
.request(app)
|
||||
.get('/api/v1/settings')
|
||||
.set(passport.inject({role}));
|
||||
.set(passport.inject({ role }));
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.be.json;
|
||||
expect(res.body).to.have.property('moderation', 'PRE');
|
||||
@@ -29,29 +28,29 @@ describe('/api/v1/settings', () => {
|
||||
});
|
||||
|
||||
describe('#put', () => {
|
||||
|
||||
it('should update the settings', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.put('/api/v1/settings')
|
||||
.set(passport.inject({role: 'ADMIN'}))
|
||||
.send({moderation: 'POST'})
|
||||
.then((res) => {
|
||||
.set(passport.inject({ role: 'ADMIN' }))
|
||||
.send({ moderation: 'POST' })
|
||||
.then(res => {
|
||||
expect(res).to.have.status(204);
|
||||
|
||||
return SettingsService.retrieve();
|
||||
})
|
||||
.then((settings) => {
|
||||
.then(settings => {
|
||||
expect(settings).to.have.property('moderation', 'POST');
|
||||
});
|
||||
});
|
||||
|
||||
it('should require ADMIN role', () => {
|
||||
const promise = chai.request(app)
|
||||
const promise = chai
|
||||
.request(app)
|
||||
.put('/api/v1/settings')
|
||||
.set(passport.inject({role: 'MODERATOR'}))
|
||||
.send({moderation: 'POST'});
|
||||
.set(passport.inject({ role: 'MODERATOR' }))
|
||||
.send({ moderation: 'POST' });
|
||||
return expect(promise).to.eventually.be.rejected;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -4,7 +4,11 @@ const app = require('../../../../../app');
|
||||
const mailer = require('../../../../../services/mailer');
|
||||
|
||||
const SettingsService = require('../../../../../services/settings');
|
||||
const settings = {id: '1', moderation: 'PRE', wordlist: {banned: ['bad words'], suspect: ['suspect words']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
wordlist: { banned: ['bad words'], suspect: ['suspect words'] },
|
||||
};
|
||||
|
||||
const chai = require('chai');
|
||||
chai.should();
|
||||
@@ -14,34 +18,42 @@ const expect = chai.expect;
|
||||
const UsersService = require('../../../../../services/users');
|
||||
|
||||
describe('/api/v1/users/:user_id/email/confirm', () => {
|
||||
|
||||
let mockUser;
|
||||
|
||||
beforeEach(() => SettingsService.init(settings).then(() => {
|
||||
return UsersService.createLocalUser('ana@gmail.com', '123321123', 'Ana');
|
||||
})
|
||||
.then((user) => {
|
||||
mockUser = user;
|
||||
}));
|
||||
beforeEach(() =>
|
||||
SettingsService.init(settings)
|
||||
.then(() => {
|
||||
return UsersService.createLocalUser(
|
||||
'ana@gmail.com',
|
||||
'123321123',
|
||||
'Ana'
|
||||
);
|
||||
})
|
||||
.then(user => {
|
||||
mockUser = user;
|
||||
})
|
||||
);
|
||||
|
||||
describe('#post', () => {
|
||||
it('should send an email when we hit the endpoint', () => {
|
||||
expect(mailer.task.tasks).to.have.length(0);
|
||||
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post(`/api/v1/users/${mockUser.id}/email/confirm`)
|
||||
.set(passport.inject({role: 'ADMIN'}))
|
||||
.then((res) => {
|
||||
.set(passport.inject({ role: 'ADMIN' }))
|
||||
.then(res => {
|
||||
expect(res).to.have.status(204);
|
||||
expect(mailer.task.tasks).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should send a 404 on not matching a user', () => {
|
||||
return chai.request(app)
|
||||
return chai
|
||||
.request(app)
|
||||
.post(`/api/v1/users/${mockUser.id}/email/confirm`)
|
||||
.set(passport.inject({role: 'ADMIN'}))
|
||||
.then((res) => {
|
||||
.set(passport.inject({ role: 'ADMIN' }))
|
||||
.then(res => {
|
||||
expect(res).to.have.status(204);
|
||||
expect(mailer.task.tasks).to.have.length(1);
|
||||
});
|
||||
|
||||
@@ -7,7 +7,10 @@ chai.use(require('chai-as-promised'));
|
||||
const expect = chai.expect;
|
||||
|
||||
const events = require('../../../services/events');
|
||||
const {ACTIONS_NEW, ACTIONS_DELETE} = require('../../../services/events/constants');
|
||||
const {
|
||||
ACTIONS_NEW,
|
||||
ACTIONS_DELETE,
|
||||
} = require('../../../services/events/constants');
|
||||
|
||||
const sinon = require('sinon');
|
||||
|
||||
@@ -22,7 +25,7 @@ describe('services.ActionsService', () => {
|
||||
status_history: [],
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '1'
|
||||
id: '1',
|
||||
});
|
||||
|
||||
mockActions = await ActionModel.create([
|
||||
@@ -30,31 +33,30 @@ describe('services.ActionsService', () => {
|
||||
action_type: 'FLAG',
|
||||
item_id: comment.id,
|
||||
item_type: 'COMMENTS',
|
||||
user_id: 'flagginguserid'
|
||||
user_id: 'flagginguserid',
|
||||
},
|
||||
{
|
||||
action_type: 'FLAG',
|
||||
item_id: '456',
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '1'
|
||||
user_id: '1',
|
||||
},
|
||||
{
|
||||
action_type: 'FLAG',
|
||||
item_id: comment.id,
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '2'
|
||||
user_id: '2',
|
||||
},
|
||||
{
|
||||
action_type: 'LIKE',
|
||||
item_id: comment.id,
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '3'
|
||||
}
|
||||
user_id: '3',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('#create', () => {
|
||||
|
||||
it('creates an action', async () => {
|
||||
const srcAction = {
|
||||
action_type: 'LIKE',
|
||||
@@ -68,7 +70,9 @@ describe('services.ActionsService', () => {
|
||||
expect(createdAction).has.property('id');
|
||||
expect(createdAction).has.property('item_id', comment.id);
|
||||
|
||||
const retrievedAction = await ActionModel.findOne({id: createdAction.id});
|
||||
const retrievedAction = await ActionModel.findOne({
|
||||
id: createdAction.id,
|
||||
});
|
||||
|
||||
expect(retrievedAction).is.not.null;
|
||||
expect(retrievedAction).has.property('id', createdAction.id);
|
||||
@@ -93,22 +97,22 @@ describe('services.ActionsService', () => {
|
||||
|
||||
expect(spy).to.have.been.calledWith(createdAction);
|
||||
|
||||
const retrievedComment = await CommentModel.findOne({id: comment.id});
|
||||
const retrievedComment = await CommentModel.findOne({ id: comment.id });
|
||||
|
||||
expect(retrievedComment).to.have.property('action_counts');
|
||||
expect(retrievedComment.action_counts).to.have.property('like', 1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#delete', () => {
|
||||
|
||||
it('deletes an action', async () => {
|
||||
const deletedAction = await ActionsService.delete(mockActions[0]);
|
||||
|
||||
expect(deletedAction).has.property('id', mockActions[0].id);
|
||||
|
||||
const retrievedAction = await ActionModel.findOne({id: deletedAction.id});
|
||||
const retrievedAction = await ActionModel.findOne({
|
||||
id: deletedAction.id,
|
||||
});
|
||||
|
||||
expect(retrievedAction).is.null;
|
||||
});
|
||||
@@ -122,17 +126,16 @@ describe('services.ActionsService', () => {
|
||||
expect(deletedAction).has.property('id', mockActions[0].id);
|
||||
expect(spy).to.have.been.calledWith(deletedAction);
|
||||
|
||||
const retrievedComment = await CommentModel.findOne({id: comment.id});
|
||||
const retrievedComment = await CommentModel.findOne({ id: comment.id });
|
||||
|
||||
expect(retrievedComment).to.have.property('action_counts');
|
||||
expect(retrievedComment.action_counts).to.have.property('flag', -1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#findById()', () => {
|
||||
it('should find an action by id', () => {
|
||||
return ActionsService.findById(mockActions[0].id).then((result) => {
|
||||
return ActionsService.findById(mockActions[0].id).then(result => {
|
||||
expect(result).to.not.be.null;
|
||||
expect(result).to.have.property('action_type', 'FLAG');
|
||||
});
|
||||
@@ -141,17 +144,18 @@ describe('services.ActionsService', () => {
|
||||
|
||||
describe('#findByItemIdArray()', () => {
|
||||
it('should find an array of actions from an array of item_ids', () => {
|
||||
return ActionsService.findByItemIdArray([comment.id, '456']).then((result) => {
|
||||
expect(result).to.have.length(4);
|
||||
});
|
||||
return ActionsService.findByItemIdArray([comment.id, '456']).then(
|
||||
result => {
|
||||
expect(result).to.have.length(4);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getActionSummaries()', () => {
|
||||
it('should return properly formatted summaries from an array of item_ids', () => {
|
||||
return ActionsService
|
||||
.getActionSummaries([comment.id, '789'])
|
||||
.then((summaries) => {
|
||||
return ActionsService.getActionSummaries([comment.id, '789']).then(
|
||||
summaries => {
|
||||
expect(summaries).to.have.length(2);
|
||||
|
||||
expect(summaries).to.deep.include({
|
||||
@@ -159,7 +163,7 @@ describe('services.ActionsService', () => {
|
||||
count: 1,
|
||||
item_id: comment.id,
|
||||
item_type: 'COMMENTS',
|
||||
current_user: null
|
||||
current_user: null,
|
||||
});
|
||||
|
||||
expect(summaries).to.deep.include({
|
||||
@@ -167,39 +171,47 @@ describe('services.ActionsService', () => {
|
||||
count: 2,
|
||||
item_id: comment.id,
|
||||
item_type: 'COMMENTS',
|
||||
current_user: null
|
||||
current_user: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should include a current user when one is passed', () => {
|
||||
return ActionsService
|
||||
.getActionSummaries([comment.id], 'flagginguserid')
|
||||
.then((summaries) => {
|
||||
expect(summaries).to.have.length(2);
|
||||
return ActionsService.getActionSummaries(
|
||||
[comment.id],
|
||||
'flagginguserid'
|
||||
).then(summaries => {
|
||||
expect(summaries).to.have.length(2);
|
||||
|
||||
let summary = summaries.find((s) => s.item_id === comment.id && s.action_type === 'FLAG');
|
||||
let summary = summaries.find(
|
||||
s => s.item_id === comment.id && s.action_type === 'FLAG'
|
||||
);
|
||||
|
||||
expect(summary).to.not.be.undefined;
|
||||
expect(summary.current_user).to.not.be.null;
|
||||
expect(summary.current_user).to.have.property('item_id', comment.id);
|
||||
expect(summary.current_user).to.have.property('item_type', 'COMMENTS');
|
||||
expect(summary.current_user).to.have.property('user_id', 'flagginguserid');
|
||||
expect(summary.current_user).to.have.property('action_type', 'FLAG');
|
||||
});
|
||||
expect(summary).to.not.be.undefined;
|
||||
expect(summary.current_user).to.not.be.null;
|
||||
expect(summary.current_user).to.have.property('item_id', comment.id);
|
||||
expect(summary.current_user).to.have.property('item_type', 'COMMENTS');
|
||||
expect(summary.current_user).to.have.property(
|
||||
'user_id',
|
||||
'flagginguserid'
|
||||
);
|
||||
expect(summary.current_user).to.have.property('action_type', 'FLAG');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not include a current user when one is passed for a user that doesn\'t have an action', () => {
|
||||
return ActionsService
|
||||
.getActionSummaries([comment.id], 'flagginguserid2')
|
||||
.then((summaries) => {
|
||||
expect(summaries).to.have.length(2);
|
||||
it("should not include a current user when one is passed for a user that doesn't have an action", () => {
|
||||
return ActionsService.getActionSummaries(
|
||||
[comment.id],
|
||||
'flagginguserid2'
|
||||
).then(summaries => {
|
||||
expect(summaries).to.have.length(2);
|
||||
|
||||
summaries.forEach((summary) => {
|
||||
expect(summary).to.not.be.undefined;
|
||||
expect(summary).to.have.property('current_user', null);
|
||||
});
|
||||
summaries.forEach(summary => {
|
||||
expect(summary).to.not.be.undefined;
|
||||
expect(summary).to.have.property('current_user', null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,74 +12,76 @@ chai.should();
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
const settings = {id: '1', moderation: 'PRE', domains: {whitelist: ['new.test.com', 'test.com', 'override.test.com']}};
|
||||
const defaults = {url:'http://test.com'};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
domains: { whitelist: ['new.test.com', 'test.com', 'override.test.com'] },
|
||||
};
|
||||
const defaults = { url: 'http://test.com' };
|
||||
|
||||
describe('services.AssetsService', () => {
|
||||
|
||||
let asset;
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init(settings);
|
||||
|
||||
asset = await AssetModel.findOneAndUpdate({id: '1'}, {$setOnInsert: defaults}, {upsert: true, new: true});
|
||||
asset = await AssetModel.findOneAndUpdate(
|
||||
{ id: '1' },
|
||||
{ $setOnInsert: defaults },
|
||||
{ upsert: true, new: true }
|
||||
);
|
||||
});
|
||||
|
||||
describe('#findById', ()=> {
|
||||
describe('#findById', () => {
|
||||
it('should find an asset by the id', () => {
|
||||
return AssetsService.findById(1)
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
return AssetsService.findById(1).then(asset => {
|
||||
expect(asset)
|
||||
.to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#findByUrl', ()=> {
|
||||
describe('#findByUrl', () => {
|
||||
beforeEach(() => AssetsService.findOrCreateByUrl('http://test.com'));
|
||||
|
||||
it('should find an asset by a url', () => {
|
||||
return AssetsService
|
||||
.findByUrl('http://test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('url', 'http://test.com');
|
||||
});
|
||||
return AssetsService.findByUrl('http://test.com').then(asset => {
|
||||
expect(asset).to.have.property('url', 'http://test.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null when a url does not exist', () => {
|
||||
return AssetsService
|
||||
.findByUrl('http://new.test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.be.null;
|
||||
});
|
||||
return AssetsService.findByUrl('http://new.test.com').then(asset => {
|
||||
expect(asset).to.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#findOrCreateByUrl', ()=> {
|
||||
describe('#findOrCreateByUrl', () => {
|
||||
it('should find an asset by a url', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('http://test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
return AssetsService.findOrCreateByUrl('http://test.com').then(asset => {
|
||||
expect(asset)
|
||||
.to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a new asset when the url does not exist and its domain is whitelisted', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('http://new.test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('id')
|
||||
return AssetsService.findOrCreateByUrl('http://new.test.com').then(
|
||||
asset => {
|
||||
expect(asset)
|
||||
.to.have.property('id')
|
||||
.and.to.not.equal(1);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should return an error when the url does not exist and its domain is not whitelisted', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('http://bad.test.com')
|
||||
.then((asset) => {
|
||||
return AssetsService.findOrCreateByUrl('http://bad.test.com')
|
||||
.then(asset => {
|
||||
expect(asset).to.be.null;
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch(error => {
|
||||
expect(error).to.not.be.null;
|
||||
});
|
||||
});
|
||||
@@ -87,18 +89,21 @@ describe('services.AssetsService', () => {
|
||||
|
||||
describe('#overrideSettings', () => {
|
||||
it('should update the settings', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('https://override.test.com/asset')
|
||||
.then((asset) => {
|
||||
return AssetsService.findOrCreateByUrl('https://override.test.com/asset')
|
||||
.then(asset => {
|
||||
expect(asset).to.have.property('settings');
|
||||
expect(asset.settings).to.be.empty;
|
||||
|
||||
return AssetsService.overrideSettings(asset.id, {moderation: 'PRE'});
|
||||
return AssetsService.overrideSettings(asset.id, {
|
||||
moderation: 'PRE',
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return AssetsService.findOrCreateByUrl('https://override.test.com/asset');
|
||||
return AssetsService.findOrCreateByUrl(
|
||||
'https://override.test.com/asset'
|
||||
);
|
||||
})
|
||||
.then((asset) => {
|
||||
.then(asset => {
|
||||
expect(asset).to.have.property('settings');
|
||||
expect(asset.settings).is.an('object');
|
||||
expect(asset.settings).to.have.property('moderation', 'PRE');
|
||||
@@ -106,28 +111,27 @@ describe('services.AssetsService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#findOrCreateByUrl', ()=> {
|
||||
describe('#findOrCreateByUrl', () => {
|
||||
it('should find an asset by a url', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('http://test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
return AssetsService.findOrCreateByUrl('http://test.com').then(asset => {
|
||||
expect(asset)
|
||||
.to.have.property('url')
|
||||
.and.to.equal('http://test.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a new asset when the url does not exist', () => {
|
||||
return AssetsService
|
||||
.findOrCreateByUrl('http://new.test.com')
|
||||
.then((asset) => {
|
||||
expect(asset).to.have.property('id')
|
||||
return AssetsService.findOrCreateByUrl('http://new.test.com').then(
|
||||
asset => {
|
||||
expect(asset)
|
||||
.to.have.property('id')
|
||||
.and.to.not.equal(1);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateURL', () => {
|
||||
|
||||
it('should change the url if the asset was found, and there was no conflict', async () => {
|
||||
let newURL = url.resolve(asset.url, '/new-url');
|
||||
|
||||
@@ -135,7 +139,7 @@ describe('services.AssetsService', () => {
|
||||
await AssetsService.updateURL(asset.id, newURL);
|
||||
|
||||
// Check that the url was updated.
|
||||
let {url: databaseURL} = await AssetsService.findById(asset.id);
|
||||
let { url: databaseURL } = await AssetsService.findById(asset.id);
|
||||
|
||||
expect(databaseURL).to.equal(newURL);
|
||||
});
|
||||
@@ -144,47 +148,55 @@ describe('services.AssetsService', () => {
|
||||
let newURL = url.resolve(asset.url, '/new-url');
|
||||
|
||||
// Create a new asset with our new URL.
|
||||
await AssetModel.findOneAndUpdate({id: '2'}, {$setOnInsert: {url: newURL}}, {upsert: true, new: true});
|
||||
await AssetModel.findOneAndUpdate(
|
||||
{ id: '2' },
|
||||
{ $setOnInsert: { url: newURL } },
|
||||
{ upsert: true, new: true }
|
||||
);
|
||||
|
||||
return AssetsService.updateURL(asset.id, newURL).should.eventually.be.rejected;
|
||||
return AssetsService.updateURL(asset.id, newURL).should.eventually.be
|
||||
.rejected;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#merge', () => {
|
||||
|
||||
it('should error if either the src or the dst is missing', () => {
|
||||
return AssetsService.merge('not-found', asset.id).should.eventually.be.rejected;
|
||||
return AssetsService.merge('not-found', asset.id).should.eventually.be
|
||||
.rejected;
|
||||
});
|
||||
|
||||
it('should merge the assets', async () => {
|
||||
let newURL = url.resolve(asset.url, '/new-url');
|
||||
|
||||
// Create a new asset with our new URL.
|
||||
await AssetModel.findOneAndUpdate({id: '2'}, {$setOnInsert: {url: newURL}}, {upsert: true, new: true});
|
||||
await AssetModel.findOneAndUpdate(
|
||||
{ id: '2' },
|
||||
{ $setOnInsert: { url: newURL } },
|
||||
{ upsert: true, new: true }
|
||||
);
|
||||
|
||||
// Create some comments on both assets.
|
||||
await CommentsService.publicCreate([
|
||||
{
|
||||
asset_id: '1',
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
status: 'ACCEPTED',
|
||||
},
|
||||
{
|
||||
asset_id: '1',
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
status: 'ACCEPTED',
|
||||
},
|
||||
{
|
||||
asset_id: '2',
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
status: 'ACCEPTED',
|
||||
},
|
||||
{
|
||||
asset_id: '2',
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
}
|
||||
status: 'ACCEPTED',
|
||||
},
|
||||
]);
|
||||
|
||||
// Merge all the comments from asset 1 into asset 2, followed by deleting
|
||||
@@ -192,12 +204,11 @@ describe('services.AssetsService', () => {
|
||||
await AssetsService.merge('1', '2');
|
||||
|
||||
// Check to see if the comments are moved.
|
||||
expect(await CommentModel.find({asset_id: '1'}).count()).to.equal(0);
|
||||
expect(await CommentModel.find({asset_id: '2'}).count()).to.equal(4);
|
||||
expect(await CommentModel.find({ asset_id: '1' }).count()).to.equal(0);
|
||||
expect(await CommentModel.find({ asset_id: '2' }).count()).to.equal(4);
|
||||
|
||||
// Check to see if the asset was removed.
|
||||
expect(await AssetModel.findOne({id: '1'})).to.equal(null);
|
||||
expect(await AssetModel.findOne({ id: '1' })).to.equal(null);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
+135
-103
@@ -2,12 +2,16 @@ const CommentModel = require('../../../models/comment');
|
||||
const ActionModel = require('../../../models/action');
|
||||
|
||||
const events = require('../../../services/events');
|
||||
const {COMMENTS_EDIT} = require('../../../services/events/constants');
|
||||
const { COMMENTS_EDIT } = require('../../../services/events/constants');
|
||||
const UsersService = require('../../../services/users');
|
||||
const SettingsService = require('../../../services/settings');
|
||||
const CommentsService = require('../../../services/comments');
|
||||
|
||||
const settings = {id: '1', moderation: 'PRE', wordlist: {banned: ['bad words'], suspect: ['suspect words']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
wordlist: { banned: ['bad words'], suspect: ['suspect words'] },
|
||||
};
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('sinon-chai'));
|
||||
@@ -16,84 +20,105 @@ const expect = chai.expect;
|
||||
const sinon = require('sinon');
|
||||
|
||||
describe('services.CommentsService', () => {
|
||||
const comments = [{
|
||||
body: 'comment 10',
|
||||
asset_id: '123',
|
||||
status_history: [],
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '1'
|
||||
}, {
|
||||
body: 'comment 20',
|
||||
asset_id: '123',
|
||||
status_history: [{
|
||||
type: 'ACCEPTED'
|
||||
}],
|
||||
status: 'ACCEPTED',
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '2'
|
||||
}, {
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status_history: [],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '3'
|
||||
}, {
|
||||
body: 'comment 40',
|
||||
asset_id: '123',
|
||||
status_history: [{
|
||||
type: 'REJECTED'
|
||||
}],
|
||||
status: 'REJECTED',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '4'
|
||||
}, {
|
||||
body: 'comment 50',
|
||||
asset_id: '1234',
|
||||
status_history: [{
|
||||
type: 'PREMOD'
|
||||
}],
|
||||
status: 'PREMOD',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '5'
|
||||
}, {
|
||||
body: 'comment 60',
|
||||
asset_id: '1234',
|
||||
status_history: [{
|
||||
type: 'PREMOD'
|
||||
}],
|
||||
status: 'PREMOD',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '6'
|
||||
}];
|
||||
const comments = [
|
||||
{
|
||||
body: 'comment 10',
|
||||
asset_id: '123',
|
||||
status_history: [],
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '1',
|
||||
},
|
||||
{
|
||||
body: 'comment 20',
|
||||
asset_id: '123',
|
||||
status_history: [
|
||||
{
|
||||
type: 'ACCEPTED',
|
||||
},
|
||||
],
|
||||
status: 'ACCEPTED',
|
||||
parent_id: '',
|
||||
author_id: '123',
|
||||
id: '2',
|
||||
},
|
||||
{
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status_history: [],
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '3',
|
||||
},
|
||||
{
|
||||
body: 'comment 40',
|
||||
asset_id: '123',
|
||||
status_history: [
|
||||
{
|
||||
type: 'REJECTED',
|
||||
},
|
||||
],
|
||||
status: 'REJECTED',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '4',
|
||||
},
|
||||
{
|
||||
body: 'comment 50',
|
||||
asset_id: '1234',
|
||||
status_history: [
|
||||
{
|
||||
type: 'PREMOD',
|
||||
},
|
||||
],
|
||||
status: 'PREMOD',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '5',
|
||||
},
|
||||
{
|
||||
body: 'comment 60',
|
||||
asset_id: '1234',
|
||||
status_history: [
|
||||
{
|
||||
type: 'PREMOD',
|
||||
},
|
||||
],
|
||||
status: 'PREMOD',
|
||||
parent_id: '',
|
||||
author_id: '456',
|
||||
id: '6',
|
||||
},
|
||||
];
|
||||
|
||||
const users = [{
|
||||
id: 'u1',
|
||||
email: 'stampi@gmail.com',
|
||||
username: 'Stampi',
|
||||
password: '1Coral!!'
|
||||
}, {
|
||||
email: 'sockmonster@gmail.com',
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!!'
|
||||
}];
|
||||
const users = [
|
||||
{
|
||||
id: 'u1',
|
||||
email: 'stampi@gmail.com',
|
||||
username: 'Stampi',
|
||||
password: '1Coral!!',
|
||||
},
|
||||
{
|
||||
email: 'sockmonster@gmail.com',
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!!',
|
||||
},
|
||||
];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'FLAG',
|
||||
item_id: '3',
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '123'
|
||||
}, {
|
||||
action_type: 'LIKE',
|
||||
item_id: '1',
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '456'
|
||||
}];
|
||||
const actions = [
|
||||
{
|
||||
action_type: 'FLAG',
|
||||
item_id: '3',
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '123',
|
||||
},
|
||||
{
|
||||
action_type: 'LIKE',
|
||||
item_id: '1',
|
||||
item_type: 'COMMENTS',
|
||||
user_id: '456',
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init(settings);
|
||||
@@ -101,16 +126,15 @@ describe('services.CommentsService', () => {
|
||||
await Promise.all([
|
||||
CommentModel.create(comments),
|
||||
UsersService.createLocalUsers(users),
|
||||
ActionModel.create(actions)
|
||||
ActionModel.create(actions),
|
||||
]);
|
||||
});
|
||||
|
||||
describe('#publicCreate()', () => {
|
||||
|
||||
it('creates a new comment', async () => {
|
||||
const c = await CommentsService.publicCreate({
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
status: 'ACCEPTED',
|
||||
});
|
||||
|
||||
expect(c).to.not.be.null;
|
||||
@@ -120,19 +144,19 @@ describe('services.CommentsService', () => {
|
||||
});
|
||||
|
||||
it('creates many new comments', async () => {
|
||||
const [
|
||||
c1,
|
||||
c2,
|
||||
c3,
|
||||
] = await CommentsService.publicCreate([{
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED'
|
||||
}, {
|
||||
body: 'This is another comment!'
|
||||
}, {
|
||||
body: 'This is a rejected comment!',
|
||||
status: 'REJECTED'
|
||||
}]);
|
||||
const [c1, c2, c3] = await CommentsService.publicCreate([
|
||||
{
|
||||
body: 'This is a comment!',
|
||||
status: 'ACCEPTED',
|
||||
},
|
||||
{
|
||||
body: 'This is another comment!',
|
||||
},
|
||||
{
|
||||
body: 'This is a rejected comment!',
|
||||
status: 'REJECTED',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(c1).to.not.be.null;
|
||||
expect(c1.status).to.be.equal('ACCEPTED');
|
||||
@@ -161,7 +185,10 @@ describe('services.CommentsService', () => {
|
||||
|
||||
expect(retrivedComment).to.have.property('status', 'ACCEPTED');
|
||||
expect(retrivedComment.status_history).to.have.length(2);
|
||||
expect(retrivedComment.status_history[1]).to.have.property('type', 'ACCEPTED');
|
||||
expect(retrivedComment.status_history[1]).to.have.property(
|
||||
'type',
|
||||
'ACCEPTED'
|
||||
);
|
||||
|
||||
const editedComment = await CommentsService.edit({
|
||||
id: originalComment.id,
|
||||
@@ -172,34 +199,40 @@ describe('services.CommentsService', () => {
|
||||
|
||||
expect(editedComment).to.have.property('status', 'PREMOD');
|
||||
expect(editedComment.status_history).to.have.length(4);
|
||||
expect(editedComment.status_history[3]).to.have.property('type', 'PREMOD');
|
||||
expect(editedComment.status_history[3]).to.have.property(
|
||||
'type',
|
||||
'PREMOD'
|
||||
);
|
||||
|
||||
retrivedComment = await CommentsService.findById(originalComment.id);
|
||||
|
||||
expect(retrivedComment).to.have.property('status', 'PREMOD');
|
||||
expect(retrivedComment.status_history).to.have.length(4);
|
||||
expect(retrivedComment.status_history[3]).to.have.property('type', 'PREMOD');
|
||||
expect(retrivedComment.status_history[3]).to.have.property(
|
||||
'type',
|
||||
'PREMOD'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#findById()', () => {
|
||||
|
||||
it('should find a comment by id', async () => {
|
||||
const comment = await CommentsService.findById('1');
|
||||
expect(comment).to.not.be.null;
|
||||
expect(comment).to.have.property('body', 'comment 10');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#findByAssetId()', () => {
|
||||
|
||||
it('should find an array of all comments by asset id', async () => {
|
||||
const comments = await CommentsService.findByAssetId('123');
|
||||
expect(comments).to.have.length(3);
|
||||
comments.sort((a, b) => {
|
||||
if (a.body < b.body) {return -1;}
|
||||
else {return 1;}
|
||||
if (a.body < b.body) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
expect(comments[0]).to.have.property('body', 'comment 10');
|
||||
expect(comments[1]).to.have.property('body', 'comment 20');
|
||||
@@ -208,7 +241,6 @@ describe('services.CommentsService', () => {
|
||||
});
|
||||
|
||||
describe('#changeStatus', () => {
|
||||
|
||||
it('should change the status of a comment from no status', async () => {
|
||||
let comment_id = comments[0].id;
|
||||
|
||||
|
||||
@@ -3,27 +3,25 @@ const DomainList = require('../../../services/domain_list');
|
||||
const SettingsService = require('../../../services/settings');
|
||||
|
||||
describe('services.DomainList', () => {
|
||||
|
||||
const domainLists = {
|
||||
whitelist: [
|
||||
'nytimes.com',
|
||||
'wapo.com'
|
||||
]
|
||||
whitelist: ['nytimes.com', 'wapo.com'],
|
||||
};
|
||||
|
||||
let domainList = new DomainList();
|
||||
const settings = {id: '1', moderation: 'PRE', domainlist: {whitelist: ['nytimes.com', 'wapo.com']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
domainlist: { whitelist: ['nytimes.com', 'wapo.com'] },
|
||||
};
|
||||
|
||||
beforeEach(() => SettingsService.init(settings));
|
||||
|
||||
describe('#init', () => {
|
||||
|
||||
before(() => domainList.upsert(domainLists));
|
||||
|
||||
it('has entries', () => {
|
||||
expect(domainList.lists.whitelist).to.not.be.empty;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#parseURL', () => {
|
||||
@@ -92,30 +90,25 @@ describe('services.DomainList', () => {
|
||||
['google.Ca:80', 'google.ca'],
|
||||
['google.Ca:443', 'google.ca'],
|
||||
].forEach(([domain, hostname]) => {
|
||||
expect(DomainList.parseURL(domain), `domain ${domain} should be parsed as ${hostname}`).to.equal(hostname);
|
||||
expect(
|
||||
DomainList.parseURL(domain),
|
||||
`domain ${domain} should be parsed as ${hostname}`
|
||||
).to.equal(hostname);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#match', () => {
|
||||
|
||||
const whiteList = DomainList.parseList(domainLists['whitelist']);
|
||||
|
||||
it('does match on an included domain', () => {
|
||||
[
|
||||
'http://wapo.com',
|
||||
'nytimes.com'
|
||||
].forEach((domain) => {
|
||||
['http://wapo.com', 'nytimes.com'].forEach(domain => {
|
||||
expect(domainList.match(whiteList, domain)).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
it('does not match on a not included domain', () => {
|
||||
[
|
||||
'badsite.com',
|
||||
'www.badsite.com',
|
||||
'otherexample.com'
|
||||
].forEach((domain) => {
|
||||
['badsite.com', 'www.badsite.com', 'otherexample.com'].forEach(domain => {
|
||||
expect(domainList.match(whiteList, domain)).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,37 +3,54 @@ const chai = require('chai');
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('services.SettingsService', () => {
|
||||
|
||||
beforeEach(() => SettingsService.init({moderation: 'PRE', wordlist: ['donut']}));
|
||||
beforeEach(() =>
|
||||
SettingsService.init({ moderation: 'PRE', wordlist: ['donut'] })
|
||||
);
|
||||
|
||||
describe('#retrieve()', () => {
|
||||
it('should have a moderation field defined', () => {
|
||||
return SettingsService.retrieve().then((settings) => {
|
||||
expect(settings).to.have.property('moderation').and.to.equal('PRE');
|
||||
return SettingsService.retrieve().then(settings => {
|
||||
expect(settings)
|
||||
.to.have.property('moderation')
|
||||
.and.to.equal('PRE');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have two infoBox fields defined', () => {
|
||||
return SettingsService.retrieve().then((settings) => {
|
||||
expect(settings).to.have.property('infoBoxEnable').and.to.equal(false);
|
||||
expect(settings).to.have.property('infoBoxContent').and.to.equal('');
|
||||
return SettingsService.retrieve().then(settings => {
|
||||
expect(settings)
|
||||
.to.have.property('infoBoxEnable')
|
||||
.and.to.equal(false);
|
||||
expect(settings)
|
||||
.to.have.property('infoBoxContent')
|
||||
.and.to.equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#update()', () => {
|
||||
it('should update the settings with a passed object', () => {
|
||||
const mockSettings = {moderation: 'POST', infoBoxEnable: true, infoBoxContent: 'yeah'};
|
||||
return SettingsService.update(mockSettings).then((updatedSettings) => {
|
||||
const mockSettings = {
|
||||
moderation: 'POST',
|
||||
infoBoxEnable: true,
|
||||
infoBoxContent: 'yeah',
|
||||
};
|
||||
return SettingsService.update(mockSettings).then(updatedSettings => {
|
||||
expect(updatedSettings).to.be.an('object');
|
||||
expect(updatedSettings).to.have.property('moderation').and.to.equal('POST');
|
||||
expect(updatedSettings)
|
||||
.to.have.property('moderation')
|
||||
.and.to.equal('POST');
|
||||
expect(updatedSettings).to.have.property('infoBoxEnable', true);
|
||||
expect(updatedSettings).to.have.property('infoBoxContent', 'yeah');
|
||||
});
|
||||
});
|
||||
|
||||
it('should be ok when receiving an object based off of a mongoose model', async () => {
|
||||
const mockSettings = {moderation: 'POST', infoBoxEnable: true, infoBoxContent: 'yeah'};
|
||||
const mockSettings = {
|
||||
moderation: 'POST',
|
||||
infoBoxEnable: true,
|
||||
infoBoxContent: 'yeah',
|
||||
};
|
||||
await SettingsService.update(mockSettings);
|
||||
|
||||
const settings = await SettingsService.retrieve();
|
||||
@@ -45,7 +62,7 @@ describe('services.SettingsService', () => {
|
||||
|
||||
describe('#get', () => {
|
||||
it('should return the moderation settings', () => {
|
||||
return SettingsService.retrieve().then(({moderation}) => {
|
||||
return SettingsService.retrieve().then(({ moderation }) => {
|
||||
expect(moderation).not.to.be.null;
|
||||
});
|
||||
});
|
||||
@@ -53,15 +70,13 @@ describe('services.SettingsService', () => {
|
||||
|
||||
describe('#merge', () => {
|
||||
it('should merge a settings object and its overrides', () => {
|
||||
return SettingsService
|
||||
.retrieve()
|
||||
.then((settings) => {
|
||||
let ovrSett = {moderation: 'POST'};
|
||||
return SettingsService.retrieve().then(settings => {
|
||||
let ovrSett = { moderation: 'POST' };
|
||||
|
||||
settings.merge(ovrSett);
|
||||
settings.merge(ovrSett);
|
||||
|
||||
expect(settings).to.have.property('moderation', 'POST');
|
||||
});
|
||||
expect(settings).to.have.property('moderation', 'POST');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,14 +12,18 @@ describe('services.TagsService', () => {
|
||||
let comment, user;
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
user = await UsersService.createLocalUser('stampi@gmail.com', '1Coral!!', 'Stampi');
|
||||
user = await UsersService.createLocalUser(
|
||||
'stampi@gmail.com',
|
||||
'1Coral!!',
|
||||
'Stampi'
|
||||
);
|
||||
comment = await CommentModel.create({
|
||||
id: '1',
|
||||
body: 'comment 10',
|
||||
asset_id: '123',
|
||||
status_history: [],
|
||||
parent_id: null,
|
||||
author_id: user.id
|
||||
author_id: user.id,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,43 +35,43 @@ describe('services.TagsService', () => {
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
const {tags} = await CommentsService.findById(id);
|
||||
const { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(1);
|
||||
expect(tags[0].tag.name).to.equal(name);
|
||||
expect(tags[0].assigned_by).to.equal(assigned_by);
|
||||
});
|
||||
|
||||
it('can\'t add same tag.id twice', async () => {
|
||||
it("can't add same tag.id twice", async () => {
|
||||
const id = comment.id;
|
||||
const name = 'BEST';
|
||||
const assigned_by = user.id;
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
let {tags} = await CommentsService.findById(id);
|
||||
let { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(1);
|
||||
}
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
let {tags} = await CommentsService.findById(id);
|
||||
let { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(1);
|
||||
}
|
||||
});
|
||||
@@ -81,26 +85,26 @@ describe('services.TagsService', () => {
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
const {tags} = await CommentsService.findById(id);
|
||||
const { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(1);
|
||||
}
|
||||
|
||||
// ok now to remove it
|
||||
await TagsService.remove(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
const {tags} = await CommentsService.findById(id);
|
||||
const { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(0);
|
||||
}
|
||||
});
|
||||
@@ -111,33 +115,33 @@ describe('services.TagsService', () => {
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name: 'ANOTHER'
|
||||
name: 'ANOTHER',
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
await TagsService.add(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
const {tags} = await CommentsService.findById(id);
|
||||
const { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(2);
|
||||
}
|
||||
|
||||
// ok now to remove it
|
||||
await TagsService.remove(id, 'COMMENTS', {
|
||||
tag: {
|
||||
name
|
||||
name,
|
||||
},
|
||||
assigned_by
|
||||
assigned_by,
|
||||
});
|
||||
|
||||
{
|
||||
const {tags} = await CommentsService.findById(id);
|
||||
const { tags } = await CommentsService.findById(id);
|
||||
expect(tags.length).to.equal(1);
|
||||
expect(tags[0].tag.name).to.equal('ANOTHER');
|
||||
}
|
||||
|
||||
@@ -7,15 +7,17 @@ chai.use(require('chai-as-promised'));
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('services.TokensService', () => {
|
||||
|
||||
let user;
|
||||
beforeEach(async () => {
|
||||
await SettingsService.init();
|
||||
user = await UsersService.createLocalUser('sockmonster@gmail.com', '2Coral!!', 'Sockmonster');
|
||||
user = await UsersService.createLocalUser(
|
||||
'sockmonster@gmail.com',
|
||||
'2Coral!!',
|
||||
'Sockmonster'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#create', () => {
|
||||
|
||||
it('can create the token without error', async () => {
|
||||
let token = await TokensService.create(user.id, 'Github Token');
|
||||
expect(token).to.be.an.object;
|
||||
@@ -29,13 +31,11 @@ describe('services.TokensService', () => {
|
||||
expect(tokens[0]).to.have.property('id', pat.id);
|
||||
expect(tokens[0]).to.have.property('name', pat.name);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#revoke', () => {
|
||||
|
||||
it('can revoke a token', async () => {
|
||||
let {pat: {id}} = await TokensService.create(user.id, 'Github Token');
|
||||
let { pat: { id } } = await TokensService.create(user.id, 'Github Token');
|
||||
|
||||
let tokens = await TokensService.list(user.id);
|
||||
expect(tokens).to.have.length(1);
|
||||
@@ -49,24 +49,20 @@ describe('services.TokensService', () => {
|
||||
expect(tokens[0]).to.have.property('id', id);
|
||||
expect(tokens[0]).to.have.property('active', false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#validate', () => {
|
||||
|
||||
it('will allow a valid token', async () => {
|
||||
|
||||
// Create a token.
|
||||
let {pat: {id}} = await TokensService.create(user.id, 'Github Token');
|
||||
let { pat: { id } } = await TokensService.create(user.id, 'Github Token');
|
||||
|
||||
// Validate it.
|
||||
await TokensService.validate(user.id, id);
|
||||
});
|
||||
|
||||
it('will not allow an invalid token', async () => {
|
||||
|
||||
// Create a token.
|
||||
let {pat: {id}} = await TokensService.create(user.id, 'Github Token');
|
||||
let { pat: { id } } = await TokensService.create(user.id, 'Github Token');
|
||||
|
||||
// Revoke it.
|
||||
await TokensService.revoke(user.id, id);
|
||||
@@ -74,23 +70,19 @@ describe('services.TokensService', () => {
|
||||
// Validate it.
|
||||
return TokensService.validate(user.id, id).should.eventually.be.rejected;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#list', () => {
|
||||
|
||||
it('lists the tokens for a user', async () => {
|
||||
|
||||
let tokens = await TokensService.list(user.id);
|
||||
expect(tokens).to.have.length(0);
|
||||
|
||||
// Create a token.
|
||||
let {pat: {id}} = await TokensService.create(user.id, 'Github Token');
|
||||
let { pat: { id } } = await TokensService.create(user.id, 'Github Token');
|
||||
|
||||
tokens = await TokensService.list(user.id);
|
||||
expect(tokens).to.have.length(1);
|
||||
expect(tokens[0]).to.have.property('id', id);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
+111
-70
@@ -9,25 +9,32 @@ chai.use(require('sinon-chai'));
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('services.UsersService', () => {
|
||||
|
||||
let mockUsers;
|
||||
beforeEach(async () => {
|
||||
const settings = {id: '1', moderation: 'PRE', wordlist: {banned: ['bad words'], suspect: ['suspect words']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
wordlist: { banned: ['bad words'], suspect: ['suspect words'] },
|
||||
};
|
||||
|
||||
await SettingsService.init(settings);
|
||||
mockUsers = await UsersService.createLocalUsers([{
|
||||
email: 'stampi@gmail.com',
|
||||
username: 'Stampi',
|
||||
password: '1Coral!-',
|
||||
}, {
|
||||
email: 'sockmonster@gmail.com',
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!2'
|
||||
}, {
|
||||
email: 'marvel@gmail.com',
|
||||
username: 'Marvel',
|
||||
password: '3Coral!3'
|
||||
}]);
|
||||
mockUsers = await UsersService.createLocalUsers([
|
||||
{
|
||||
email: 'stampi@gmail.com',
|
||||
username: 'Stampi',
|
||||
password: '1Coral!-',
|
||||
},
|
||||
{
|
||||
email: 'sockmonster@gmail.com',
|
||||
username: 'Sockmonster',
|
||||
password: '2Coral!2',
|
||||
},
|
||||
{
|
||||
email: 'marvel@gmail.com',
|
||||
username: 'Marvel',
|
||||
password: '3Coral!3',
|
||||
},
|
||||
]);
|
||||
|
||||
sinon.spy(mailer, 'send');
|
||||
});
|
||||
@@ -45,7 +52,7 @@ describe('services.UsersService', () => {
|
||||
|
||||
describe('#findByIdArray()', () => {
|
||||
it('should find an array of users from an array of ids', async () => {
|
||||
const ids = mockUsers.map((user) => user.id);
|
||||
const ids = mockUsers.map(user => user.id);
|
||||
const users = await UsersService.findByIdArray(ids);
|
||||
expect(users).to.have.length(3);
|
||||
});
|
||||
@@ -53,13 +60,17 @@ describe('services.UsersService', () => {
|
||||
|
||||
describe('#findPublicByIdArray()', () => {
|
||||
it('should find an array of users from an array of ids', async () => {
|
||||
const ids = mockUsers.map((user) => user.id);
|
||||
const ids = mockUsers.map(user => user.id);
|
||||
const users = await UsersService.findPublicByIdArray(ids);
|
||||
expect(users).to.have.length(3);
|
||||
|
||||
const sorted = users.sort((a, b) => {
|
||||
if(a.username < b.username) {return -1;}
|
||||
if(a.username > b.username) {return 1;}
|
||||
const sorted = users.sort((a, b) => {
|
||||
if (a.username < b.username) {
|
||||
return -1;
|
||||
}
|
||||
if (a.username > b.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
expect(sorted[0]).to.have.property('username', 'Marvel');
|
||||
@@ -67,74 +78,83 @@ describe('services.UsersService', () => {
|
||||
});
|
||||
|
||||
describe('#findLocalUser', () => {
|
||||
|
||||
it('should find a user', () => {
|
||||
return UsersService
|
||||
.findLocalUser(mockUsers[0].profiles[0].id)
|
||||
.then((user) => {
|
||||
return UsersService.findLocalUser(mockUsers[0].profiles[0].id).then(
|
||||
user => {
|
||||
expect(user).to.have.property('username', mockUsers[0].username);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#createLocalUser', () => {
|
||||
it('should not create a user with duplicate username', () => {
|
||||
return UsersService.createLocalUsers([{
|
||||
email: 'otrostampi@gmail.com',
|
||||
username: 'StampiTheSecond',
|
||||
password: '1Coralito!'
|
||||
}])
|
||||
.then((user) => {
|
||||
return UsersService.createLocalUsers([
|
||||
{
|
||||
email: 'otrostampi@gmail.com',
|
||||
username: 'StampiTheSecond',
|
||||
password: '1Coralito!',
|
||||
},
|
||||
])
|
||||
.then(user => {
|
||||
expect(user).to.be.null;
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch(error => {
|
||||
expect(error).to.not.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#createEmailConfirmToken', () => {
|
||||
|
||||
it('should create a token for a valid user', async () => {
|
||||
const token = await UsersService.createEmailConfirmToken(mockUsers[0], mockUsers[0].profiles[0].id);
|
||||
const token = await UsersService.createEmailConfirmToken(
|
||||
mockUsers[0],
|
||||
mockUsers[0].profiles[0].id
|
||||
);
|
||||
expect(token).to.not.be.null;
|
||||
});
|
||||
|
||||
it('should not create a token for a user already verified', async () => {
|
||||
const token = await UsersService.createEmailConfirmToken(mockUsers[0], mockUsers[0].profiles[0].id);
|
||||
const token = await UsersService.createEmailConfirmToken(
|
||||
mockUsers[0],
|
||||
mockUsers[0].profiles[0].id
|
||||
);
|
||||
expect(token).to.not.be.null;
|
||||
|
||||
await UsersService.verifyEmailConfirmation(token);
|
||||
|
||||
const user = await UsersService.findById(mockUsers[0].id);
|
||||
|
||||
return expect(UsersService.createEmailConfirmToken(user, mockUsers[0].profiles[0].id)).to.eventually.be.rejected;
|
||||
return expect(
|
||||
UsersService.createEmailConfirmToken(user, mockUsers[0].profiles[0].id)
|
||||
).to.eventually.be.rejected;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#verifyEmailConfirmation', () => {
|
||||
|
||||
it('should correctly validate a valid token', async () => {
|
||||
const token = await UsersService.createEmailConfirmToken(mockUsers[0], mockUsers[0].profiles[0].id);
|
||||
const token = await UsersService.createEmailConfirmToken(
|
||||
mockUsers[0],
|
||||
mockUsers[0].profiles[0].id
|
||||
);
|
||||
expect(token).to.not.be.null;
|
||||
|
||||
return expect(UsersService.verifyEmailConfirmation(token)).to.eventually.not.be.rejected;
|
||||
return expect(UsersService.verifyEmailConfirmation(token)).to.eventually
|
||||
.not.be.rejected;
|
||||
});
|
||||
|
||||
it('should correctly reject an invalid token', async () => {
|
||||
return UsersService
|
||||
.verifyEmailConfirmation('cats')
|
||||
.catch((err) => {
|
||||
expect(err).to.not.be.null;
|
||||
});
|
||||
return UsersService.verifyEmailConfirmation('cats').catch(err => {
|
||||
expect(err).to.not.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
it('should update the user model when verification is complete', () => {
|
||||
return UsersService
|
||||
.createEmailConfirmToken(mockUsers[0], mockUsers[0].profiles[0].id)
|
||||
.then((token) => {
|
||||
return UsersService.createEmailConfirmToken(
|
||||
mockUsers[0],
|
||||
mockUsers[0].profiles[0].id
|
||||
)
|
||||
.then(token => {
|
||||
expect(token).to.not.be.null;
|
||||
|
||||
return UsersService.verifyEmailConfirmation(token);
|
||||
@@ -142,25 +162,27 @@ describe('services.UsersService', () => {
|
||||
.then(() => {
|
||||
return UsersService.findById(mockUsers[0].id);
|
||||
})
|
||||
.then((user) => {
|
||||
.then(user => {
|
||||
expect(user.profiles[0]).to.have.property('metadata');
|
||||
expect(user.profiles[0].metadata).to.have.property('confirmed_at');
|
||||
expect(user.profiles[0].metadata.confirmed_at).to.not.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#ignoreUser', () => {
|
||||
it('should add user id to ignoredUsers set', async () => {
|
||||
const user = mockUsers[0];
|
||||
const usersToIgnore = [mockUsers[1], mockUsers[2]];
|
||||
await UsersService.ignoreUsers(user.id, usersToIgnore.map((u) => u.id));
|
||||
await UsersService.ignoreUsers(user.id, usersToIgnore.map(u => u.id));
|
||||
const userAfterIgnoring = await UsersService.findById(user.id);
|
||||
expect(userAfterIgnoring.ignoresUsers.length).to.equal(2);
|
||||
|
||||
// ignore same user another time, make sure it's not added to the list.
|
||||
await UsersService.ignoreUsers(user.id, usersToIgnore.slice(0, 1).map((u) => u.id));
|
||||
await UsersService.ignoreUsers(
|
||||
user.id,
|
||||
usersToIgnore.slice(0, 1).map(u => u.id)
|
||||
);
|
||||
const userAfterIgnoring2 = await UsersService.findById(user.id);
|
||||
expect(userAfterIgnoring2.ignoresUsers.length).to.equal(2);
|
||||
});
|
||||
@@ -171,7 +193,7 @@ describe('services.UsersService', () => {
|
||||
await UsersService.setRole(usersToIgnore[0].id, 'STAFF');
|
||||
|
||||
try {
|
||||
await UsersService.ignoreUsers(user.id, usersToIgnore.map((u) => u.id));
|
||||
await UsersService.ignoreUsers(user.id, usersToIgnore.map(u => u.id));
|
||||
} catch (err) {
|
||||
expect(err.status).to.equal(400);
|
||||
expect(err.translation_key).to.equal('CANNOT_IGNORE_STAFF');
|
||||
@@ -180,18 +202,30 @@ describe('services.UsersService', () => {
|
||||
});
|
||||
|
||||
[
|
||||
{func: 'changeUsername', okStatus: 'REJECTED', notOKStatus: 'UNSET', newStatus: 'CHANGED'},
|
||||
{func: 'setUsername', okStatus: 'UNSET', notOKStatus: 'REJECTED', newStatus: 'SET'},
|
||||
].forEach(({func, okStatus, notOKStatus, newStatus}) => {
|
||||
{
|
||||
func: 'changeUsername',
|
||||
okStatus: 'REJECTED',
|
||||
notOKStatus: 'UNSET',
|
||||
newStatus: 'CHANGED',
|
||||
},
|
||||
{
|
||||
func: 'setUsername',
|
||||
okStatus: 'UNSET',
|
||||
notOKStatus: 'REJECTED',
|
||||
newStatus: 'SET',
|
||||
},
|
||||
].forEach(({ func, okStatus, notOKStatus, newStatus }) => {
|
||||
describe(`#${func}`, () => {
|
||||
[
|
||||
{status: okStatus},
|
||||
{error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: notOKStatus},
|
||||
{error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'SET'},
|
||||
{error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'APPROVED'},
|
||||
{error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'CHANGED'},
|
||||
].forEach(({status, error}) => {
|
||||
it(`${error ? 'should not' : 'should'} let them change the username if they have the status of ${status}`, async () => {
|
||||
{ status: okStatus },
|
||||
{ error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: notOKStatus },
|
||||
{ error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'SET' },
|
||||
{ error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'APPROVED' },
|
||||
{ error: 'EDIT_USERNAME_NOT_AUTHORIZED', status: 'CHANGED' },
|
||||
].forEach(({ status, error }) => {
|
||||
it(`${
|
||||
error ? 'should not' : 'should'
|
||||
} let them change the username if they have the status of ${status}`, async () => {
|
||||
const user = mockUsers[0];
|
||||
|
||||
// Set the user to the desired status.
|
||||
@@ -223,11 +257,16 @@ describe('services.UsersService', () => {
|
||||
await UsersService[func](user.id, 'spock');
|
||||
throw new Error('edit was processed successfully');
|
||||
} catch (err) {
|
||||
expect(err).have.property('translation_key', 'EDIT_USERNAME_NOT_AUTHORIZED');
|
||||
expect(err).have.property(
|
||||
'translation_key',
|
||||
'EDIT_USERNAME_NOT_AUTHORIZED'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it(`${func === 'changeUsername' ? 'should' : 'should not'} refuse changing the username to the same username`, async () => {
|
||||
it(`${
|
||||
func === 'changeUsername' ? 'should' : 'should not'
|
||||
} refuse changing the username to the same username`, async () => {
|
||||
const user = mockUsers[0];
|
||||
|
||||
// Set the user to the desired status.
|
||||
@@ -238,7 +277,10 @@ describe('services.UsersService', () => {
|
||||
await UsersService[func](user.id, user.username);
|
||||
throw new Error('edit was processed successfully');
|
||||
} catch (err) {
|
||||
expect(err).have.property('translation_key', 'SAME_USERNAME_PROVIDED');
|
||||
expect(err).have.property(
|
||||
'translation_key',
|
||||
'SAME_USERNAME_PROVIDED'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await UsersService[func](user.id, user.username);
|
||||
@@ -249,12 +291,11 @@ describe('services.UsersService', () => {
|
||||
|
||||
describe('#isValidUsername', () => {
|
||||
it('should not allow non-alphanumeric characters in usernames', () => {
|
||||
return UsersService
|
||||
.isValidUsername('hi🖕')
|
||||
return UsersService.isValidUsername('hi🖕')
|
||||
.then(() => {
|
||||
expect(false).to.be.true;
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
expect(err).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,6 @@ const chai = require('chai');
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('services.Wordlist', () => {
|
||||
|
||||
const wordlists = {
|
||||
banned: [
|
||||
'cookies',
|
||||
@@ -17,18 +16,19 @@ describe('services.Wordlist', () => {
|
||||
'p**ch',
|
||||
'p*ch',
|
||||
],
|
||||
suspect: [
|
||||
'do bad things',
|
||||
]
|
||||
suspect: ['do bad things'],
|
||||
};
|
||||
|
||||
let wordlist = new Wordlist();
|
||||
const settings = {id: '1', moderation: 'PRE', wordlist: {banned: ['bad words'], suspect: ['suspect words']}};
|
||||
const settings = {
|
||||
id: '1',
|
||||
moderation: 'PRE',
|
||||
wordlist: { banned: ['bad words'], suspect: ['suspect words'] },
|
||||
};
|
||||
|
||||
beforeEach(() => SettingsService.init(settings));
|
||||
|
||||
describe('#regexp', () => {
|
||||
|
||||
before(() => wordlist.upsert(wordlists));
|
||||
|
||||
it('does match on a bad word', () => {
|
||||
@@ -40,8 +40,8 @@ describe('services.Wordlist', () => {
|
||||
'how to do bad things',
|
||||
'How To do bad things!',
|
||||
'This stuff is $hit!',
|
||||
'That\'s a p**ch!',
|
||||
].forEach((word) => {
|
||||
"That's a p**ch!",
|
||||
].forEach(word => {
|
||||
expect(wordlist.regexp.banned.test(word)).to.be.true;
|
||||
});
|
||||
});
|
||||
@@ -54,16 +54,14 @@ describe('services.Wordlist', () => {
|
||||
'how to not do really bad things?',
|
||||
'i have $100 dollars.',
|
||||
'I have bad $ hit lling',
|
||||
'That\'s a p***ch!',
|
||||
].forEach((word) => {
|
||||
"That's a p***ch!",
|
||||
].forEach(word => {
|
||||
expect(wordlist.regexp.banned.test(word)).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#scan', () => {
|
||||
|
||||
it('does match on a bad word', () => {
|
||||
[
|
||||
'how to do really bad things',
|
||||
@@ -73,8 +71,8 @@ describe('services.Wordlist', () => {
|
||||
'how to do bad things',
|
||||
'How To do bad things!',
|
||||
'This stuff is $hit!',
|
||||
'That\'s a p**ch!',
|
||||
].forEach((word) => {
|
||||
"That's a p**ch!",
|
||||
].forEach(word => {
|
||||
expect(wordlist.scan('body', word)).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
@@ -87,43 +85,48 @@ describe('services.Wordlist', () => {
|
||||
'how to not do really bad things?',
|
||||
'i have $100 dollars.',
|
||||
'I have bad $ hit lling',
|
||||
'That\'s a p***ch!',
|
||||
].forEach((word) => {
|
||||
"That's a p***ch!",
|
||||
].forEach(word => {
|
||||
expect(wordlist.scan('body', word)).to.be.deep.equal({});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#filter', () => {
|
||||
|
||||
before(() => wordlist.upsert(wordlists));
|
||||
|
||||
it('matches on bodies containing bad words', () => {
|
||||
let errors = wordlist.filter({
|
||||
content: 'how to do really bad things?'
|
||||
}, 'content');
|
||||
let errors = wordlist.filter(
|
||||
{
|
||||
content: 'how to do really bad things?',
|
||||
},
|
||||
'content'
|
||||
);
|
||||
|
||||
expect(errors).to.have.property('banned', Errors.ErrContainsProfanity);
|
||||
});
|
||||
|
||||
it('does not match on bodies not containing bad words', () => {
|
||||
let errors = wordlist.filter({
|
||||
content: 'how to not do really bad things?'
|
||||
}, 'content');
|
||||
let errors = wordlist.filter(
|
||||
{
|
||||
content: 'how to not do really bad things?',
|
||||
},
|
||||
'content'
|
||||
);
|
||||
|
||||
expect(errors).to.not.have.property('banned');
|
||||
});
|
||||
|
||||
it('does not match on bodies not containing the bad word field', () => {
|
||||
let errors = wordlist.filter({
|
||||
author: 'how to do really bad things?',
|
||||
content: 'how to be a great person?'
|
||||
}, 'content');
|
||||
let errors = wordlist.filter(
|
||||
{
|
||||
author: 'how to do really bad things?',
|
||||
content: 'how to be a great person?',
|
||||
},
|
||||
'content'
|
||||
);
|
||||
|
||||
expect(errors).to.not.have.property('banned');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user