[NEW] Rest endpoints of discussions (#13987)

* Fix validations on create discussion function

* Add Rest endpoint to be able to create discussions

* Add Rest endpoint to get list of discussion of room

* Revert rename of Rest params, keep the same of DDP calls

* Fix assign statement

* Fix broken tests

* Fix tests
pull/14103/head
Marcos Spessatto Defendi 7 years ago committed by Rodrigo Nascimento
parent bc6d7a22a2
commit e9a4895414
  1. 51
      app/api/server/v1/rooms.js
  2. 7
      app/discussion/server/methods/createDiscussion.js
  3. 250
      tests/end-to-end/api/09-rooms.js

@ -218,3 +218,54 @@ API.v1.addRoute('rooms.leave', { authRequired: true }, {
return API.v1.success();
},
});
API.v1.addRoute('rooms.createDiscussion', { authRequired: true }, {
post() {
const { prid, pmid, reply, t_name, users } = this.bodyParams;
if (!prid) {
return API.v1.failure('Body parameter "prid" is required.');
}
if (!t_name) {
return API.v1.failure('Body parameter "t_name" is required.');
}
if (users && !Array.isArray(users)) {
return API.v1.failure('Body parameter "users" must be an array.');
}
const discussion = Meteor.runAsUser(this.userId, () => Meteor.call('createDiscussion', {
prid,
pmid,
t_name,
reply,
users: users || [],
}));
return API.v1.success({ discussion });
},
});
API.v1.addRoute('rooms.getDiscussions', { authRequired: true }, {
get() {
const room = findRoomByIdOrName({ params: this.requestParams() });
const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();
if (!Meteor.call('canAccessRoom', room._id, this.userId, {})) {
return API.v1.failure('not-allowed', 'Not Allowed');
}
const ourQuery = Object.assign(query, { prid: room._id });
const discussions = Rooms.find(ourQuery, {
sort: sort ? sort : { fname: 1 },
skip: offset,
limit: count,
fields,
}).fetch();
return API.v1.success({
discussions,
count: discussions.length,
offset,
total: Rooms.find(ourQuery).count(),
});
},
});

@ -38,6 +38,9 @@ const create = ({ prid, pmid, t_name, reply, users }) => {
let message = false;
if (pmid) {
message = Messages.findOne({ _id: pmid });
if (!message) {
throw new Meteor.Error('error-invalid-message', 'Invalid message', { method: 'DiscussionCreation' });
}
if (prid) {
if (prid !== getParentRoom(message.rid)._id) {
throw new Meteor.Error('error-invalid-arguments', { method: 'DiscussionCreation' });
@ -52,7 +55,9 @@ const create = ({ prid, pmid, t_name, reply, users }) => {
}
const p_room = Rooms.findOne(prid);
if (!p_room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'DiscussionCreation' });
}
if (p_room.prid) {
throw new Meteor.Error('error-nested-discussion', 'Cannot create nested discussions', { method: 'DiscussionCreation' });
}

@ -1,7 +1,8 @@
import { getCredentials, api, request, credentials } from '../../data/api-data.js';
import { password } from '../../data/user';
import { closeRoom, createRoom } from '../../data/rooms.helper';
import { updatePermission } from '../../data/permissions.helper';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { sendSimpleMessage } from '../../data/chat.helper';
describe('[Rooms]', function() {
this.retries(0);
@ -549,4 +550,251 @@ describe('[Rooms]', function() {
});
});
});
describe('/rooms.createDiscussion', () => {
let testChannel;
const testChannelName = `channel.test.${ Date.now() }`;
let messageSent;
before((done) => {
createRoom({ type: 'c', name: testChannelName })
.end((err, res) => {
testChannel = res.body.channel;
sendSimpleMessage({
roomId: testChannel._id,
}).end((err, res) => {
messageSent = res.body.message;
done();
});
});
});
it('should throw an error when the user tries to create a discussion and the feature is disabled', (done) => {
updateSetting('Discussion_enabled', false).then(() => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: 'valid name',
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
})
.end(() => updateSetting('Discussion_enabled', true).then(done));
});
});
it('should throw an error when the user tries to create a discussion and does not have at least one of the required permissions', (done) => {
updatePermission('start-discussion', []).then(() => {
updatePermission('start-discussion-other-user', []).then(() => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: 'valid name',
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
})
.end(() => {
updatePermission('start-discussion', ['admin', 'user', 'guest'])
.then(() => updatePermission('start-discussion-other-user', ['admin', 'user', 'guest']))
.then(done);
});
});
});
});
it('should throw an error when the user tries to create a discussion without the required parameter "prid"', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Body parameter \"prid\" is required.');
})
.end(done);
});
it('should throw an error when the user tries to create a discussion without the required parameter "t_name"', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Body parameter \"t_name\" is required.');
})
.end(done);
});
it('should throw an error when the user tries to create a discussion with the required parameter invalid "users"(different from an array)', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: 'valid name',
users: 'invalid-type-of-users',
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Body parameter \"users\" must be an array.');
})
.end(done);
});
it('should throw an error when the user tries to create a discussion with the channel\'s id invalid', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: 'invalid-id',
t_name: 'valid name',
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-invalid-room');
})
.end(done);
});
it('should throw an error when the user tries to create a discussion with the message\'s id invalid', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: 'valid name',
pmid: 'invalid-message',
})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-invalid-message');
})
.end(done);
});
it('should create a discussion successfully when send only the required parameters', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: `discussion-create-from-tests-${ testChannel.name }`,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('discussion').and.to.be.an('object');
})
.end(done);
});
it('should create a discussion successfully when send the required parameters plus the optional parameter "reply"', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: `discussion-create-from-tests-${ testChannel.name }`,
reply: 'reply from discussion tests',
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('discussion').and.to.be.an('object');
})
.end(done);
});
it('should create a discussion successfully when send the required parameters plus the optional parameter "users"', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: `discussion-create-from-tests-${ testChannel.name }`,
reply: 'reply from discussion tests',
users: ['rocket.cat'],
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('discussion').and.to.be.an('object');
})
.end(done);
});
it('should create a discussion successfully when send the required parameters plus the optional parameter "pmid"', (done) => {
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: `discussion-create-from-tests-${ testChannel.name }`,
reply: 'reply from discussion tests',
users: ['rocket.cat'],
pmid: messageSent._id,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('discussion').and.to.be.an('object');
})
.end(done);
});
});
describe('/rooms.getDiscussions', () => {
let testChannel;
const testChannelName = `channel.test.getDiscussions${ Date.now() }`;
let discussion;
before((done) => {
createRoom({ type: 'c', name: testChannelName })
.end((err, res) => {
testChannel = res.body.channel;
request.post(api('rooms.createDiscussion'))
.set(credentials)
.send({
prid: testChannel._id,
t_name: `discussion-create-from-tests-${ testChannel.name }`,
})
.end((err, res) => {
discussion = res.body.discussion;
done();
});
});
});
after((done) => closeRoom({ type: 'p', roomId: discussion._id }).then(done));
it('should throw an error when the user tries to gets a list of discussion without a required parameter "roomId"', (done) => {
request.get(api('rooms.getDiscussions'))
.set(credentials)
.query({})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'The parameter \"roomId\" or \"roomName\" is required [error-roomid-param-not-provided]');
})
.end(done);
});
it('should throw an error when the user tries to gets a list of discussion and he cannot access the room', (done) => {
updatePermission('view-c-room', []).then(() => {
request.get(api('rooms.getDiscussions'))
.set(credentials)
.query({})
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Not Allowed');
})
.end(() => updatePermission('view-c-room', ['admin', 'user', 'bot', 'anonymous']).then(done));
});
});
it('should return a list of discussions with ONE discussion', (done) => {
request.get(api('rooms.getDiscussions'))
.set(credentials)
.query({
roomId: testChannel._id,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('discussions').and.to.be.an('array');
expect(res.body.discussions).to.have.lengthOf(1);
})
.end(done);
});
});
});

Loading…
Cancel
Save