[IMPROVE] Replace discussionsOfARoom publication by REST (#15908)

pull/15926/head
Marcos Spessatto Defendi 6 years ago committed by Diego Sampaio
parent 25bb253713
commit 5bd373c8d7
  1. 25
      app/api/server/lib/messages.js
  2. 24
      app/api/server/v1/chat.js
  3. 1
      app/discussion/client/index.js
  4. 3
      app/discussion/client/lib/discussionsOfRoom.js
  5. 58
      app/discussion/client/views/DiscussionTabbar.js
  6. 1
      app/discussion/server/publications/discussionsOfRoom.js
  7. 6
      app/models/server/raw/Messages.js
  8. 414
      tests/end-to-end/api/05-chat.js

@ -115,3 +115,28 @@ export async function findSnippetedMessages({ uid, roomId, pagination: { offset,
total,
};
}
export async function findDiscussionsFromRoom({ uid, roomId, pagination: { offset, count, sort } }) {
const room = await Rooms.findOneById(roomId);
if (!await canAccessRoomAsync(room, { _id: uid })) {
throw new Error('error-not-allowed');
}
const cursor = Messages.findDiscussionsByRoom(roomId, {
sort: sort || { ts: -1 },
skip: offset,
limit: count,
});
const total = await cursor.count();
const messages = await cursor.toArray();
return {
messages,
count: messages.length,
offset,
total,
};
}

@ -9,7 +9,7 @@ import { API } from '../api';
import Rooms from '../../../models/server/models/Rooms';
import Users from '../../../models/server/models/Users';
import { settings } from '../../../settings';
import { findMentionedMessages, findStarredMessages, findSnippetedMessageById, findSnippetedMessages } from '../lib/messages';
import { findMentionedMessages, findStarredMessages, findSnippetedMessageById, findSnippetedMessages, findDiscussionsFromRoom } from '../lib/messages';
API.v1.addRoute('chat.delete', { authRequired: true }, {
post() {
@ -680,3 +680,25 @@ API.v1.addRoute('chat.getSnippetedMessages', { authRequired: true }, {
return API.v1.success(messages);
},
});
API.v1.addRoute('chat.getDiscussions', { authRequired: true }, {
get() {
const { roomId } = this.queryParams;
const { sort } = this.parseJsonQuery();
const { offset, count } = this.getPaginationItems();
if (!roomId) {
throw new Meteor.Error('error-invalid-params', 'The required "roomId" query param is missing.');
}
const messages = Promise.await(findDiscussionsFromRoom({
uid: this.userId,
roomId,
pagination: {
offset,
count,
sort,
},
}));
return API.v1.success(messages);
},
});

@ -5,7 +5,6 @@ import './views/DiscussionTabbar';
// Other UI extensions
import './lib/messageTypes/discussionMessage';
import './lib/discussionsOfRoom';
import './createDiscussionMessageAction';
import './discussionFromMessageBox';
import './tabBar';

@ -1,3 +0,0 @@
import { Mongo } from 'meteor/mongo';
export const DiscussionOfRoom = new Mongo.Collection('rocketchat_discussions_of_room');

@ -1,18 +1,24 @@
import _ from 'underscore';
import { ReactiveVar } from 'meteor/reactive-var';
import { Mongo } from 'meteor/mongo';
import { Template } from 'meteor/templating';
import { messageContext } from '../../../ui-utils/client/lib/messageContext';
import { DiscussionOfRoom } from '../lib/discussionsOfRoom';
import { Messages } from '../../../models/client';
import { APIClient } from '../../../utils/client';
import { upsertMessageBulk } from '../../../ui-utils/client/lib/RoomHistoryManager';
import './DiscussionTabbar.html';
const LIMIT_DEFAULT = 50;
Template.discussionsTabbar.helpers({
hasMessages() {
return Template.instance().cursor.count() > 0;
return Template.instance().messages.find().count();
},
messages() {
return Template.instance().cursor;
const instance = Template.instance();
return instance.messages.find({}, { limit: instance.limit.get(), sort: { ts: -1 } });
},
message() {
return _.extend(this, { customClass: 'pinned', actionContext: 'pinned' });
@ -25,31 +31,47 @@ Template.discussionsTabbar.helpers({
Template.discussionsTabbar.onCreated(function() {
this.rid = this.data.rid;
this.cursor = DiscussionOfRoom.find({
rid: this.rid,
}, {
sort: {
ts: -1,
},
});
this.messages = new Mongo.Collection(null);
this.hasMore = new ReactiveVar(true);
this.limit = new ReactiveVar(50);
this.limit = new ReactiveVar(LIMIT_DEFAULT);
this.autorun(() => {
const { rid } = Template.currentData();
this.subscribe('discussionsOfRoom', rid, this.limit.get(), () => {
const discussionCount = this.cursor.count();
if (discussionCount < this.limit.get()) {
this.hasMore.set(false);
}
const query = {
rid: this.rid,
drid: { $exists: true },
};
this.cursor && this.cursor.stop();
this.limit.set(LIMIT_DEFAULT);
this.cursor = Messages.find(query).observe({
added: ({ _id, ...message }) => {
this.messages.upsert({ _id }, message);
},
changed: ({ _id, ...message }) => {
this.messages.upsert({ _id }, message);
},
removed: ({ _id }) => {
this.messages.remove({ _id });
},
});
});
this.autorun(async () => {
const limit = this.limit.get();
const { messages, total } = await APIClient.v1.get(`chat.getDiscussions?roomId=${ this.rid }&count=${ limit }`);
upsertMessageBulk({ msgs: messages }, this.messages);
this.hasMore.set(total > limit);
});
});
Template.discussionsTabbar.events({
'scroll .js-list': _.throttle(function(e, instance) {
if (e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight - 10 && instance.hasMore.get()) {
instance.limit.set(instance.limit.get() + 50);
instance.limit.set(instance.limit.get() + LIMIT_DEFAULT);
}
}, 200),
});

@ -3,6 +3,7 @@ import { Meteor } from 'meteor/meteor';
import { Messages } from '../../../models/server';
Meteor.publish('discussionsOfRoom', function(rid, limit = 50) {
console.warn('The publication "discussionsOfRoom" is deprecated and will be removed after version v3.0.0');
if (!this.userId) {
return this.ready();
}

@ -41,4 +41,10 @@ export class MessagesRaw extends BaseRaw {
return this.find(query, options);
}
findDiscussionsByRoom(rid, options) {
const query = { rid, drid: { $exists: true } };
return this.find(query, options);
}
}

@ -1442,6 +1442,240 @@ describe('[Chat]', function() {
});
});
});
describe('[/chat.getMentionedMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getMentionedMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getMentionedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return the mentioned messages', (done) => {
request.get(api('chat.getMentionedMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
describe('[/chat.getStarredMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getStarredMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getStarredMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return the starred messages', (done) => {
request.get(api('chat.getStarredMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
describe('[/chat.getSnippetedMessageById]', () => {
it('should return an error when the snippeted messages is disabled', (done) => {
updateSetting('Message_AllowSnippeting', false).then(() => {
request.get(api('chat.getSnippetedMessageById?messageId=invalid-id'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
});
it('should return an error when the required "messageId" parameter is not sent', (done) => {
updateSetting('Message_AllowSnippeting', true).then(() => {
request.get(api('chat.getSnippetedMessageById'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
});
});
describe('[/chat.getSnippetedMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getSnippetedMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getSnippetedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return an error when the snippeted messages is disabled', (done) => {
updateSetting('Message_AllowSnippeting', false).then(() => {
request.get(api('chat.getSnippetedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
});
it('should return the snippeted messages', (done) => {
updateSetting('Message_AllowSnippeting', true).then(() => {
request.get(api('chat.getSnippetedMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
it('should return an error when the messageId is invalid', (done) => {
request.get(api('chat.getSnippetedMessageById?messageId=invalid-id'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('invalid-message');
})
.end(done);
});
});
describe('[/chat.getDiscussions]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getDiscussions'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getDiscussions?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return the discussions of a room', (done) => {
request.get(api('chat.getDiscussions?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
it('should return an error when the messageId is invalid', (done) => {
request.get(api('chat.getSnippetedMessageById?messageId=invalid-id'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('invalid-message');
})
.end(done);
});
});
});
describe('Threads', () => {
@ -2110,184 +2344,4 @@ describe('Threads', () => {
});
});
});
describe('[/chat.getMentionedMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getMentionedMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getMentionedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return the mentioned messages', (done) => {
request.get(api('chat.getMentionedMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
describe('[/chat.getStarredMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getStarredMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getStarredMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return the starred messages', (done) => {
request.get(api('chat.getStarredMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
describe('[/chat.getSnippetedMessageById]', () => {
it('should return an error when the snippeted messages is disabled', (done) => {
updateSetting('Message_AllowSnippeting', false).then(() => {
request.get(api('chat.getSnippetedMessageById?messageId=invalid-id'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
});
it('should return an error when the required "messageId" parameter is not sent', (done) => {
updateSetting('Message_AllowSnippeting', true).then(() => {
request.get(api('chat.getSnippetedMessageById'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
});
});
describe('[/chat.getSnippetedMessages]', () => {
it('should return an error when the required "roomId" parameter is not sent', (done) => {
request.get(api('chat.getSnippetedMessages'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-invalid-params');
})
.end(done);
});
it('should return an error when the roomId is invalid', (done) => {
request.get(api('chat.getSnippetedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
it('should return an error when the snippeted messages is disabled', (done) => {
updateSetting('Message_AllowSnippeting', false).then(() => {
request.get(api('chat.getSnippetedMessages?roomId=invalid-room'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('error-not-allowed');
})
.end(done);
});
});
it('should return the snippeted messages', (done) => {
updateSetting('Message_AllowSnippeting', true).then(() => {
request.get(api('chat.getSnippetedMessages?roomId=GENERAL'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body.messages).to.be.an('array');
expect(res.body).to.have.property('offset');
expect(res.body).to.have.property('total');
expect(res.body).to.have.property('count');
})
.end(done);
});
});
it('should return an error when the messageId is invalid', (done) => {
request.get(api('chat.getSnippetedMessageById?messageId=invalid-id'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('invalid-message');
})
.end(done);
});
});
});

Loading…
Cancel
Save