diff --git a/packages/rocketchat-api/package.js b/packages/rocketchat-api/package.js index d1a8958f6e611..347eff9d96c79 100644 --- a/packages/rocketchat-api/package.js +++ b/packages/rocketchat-api/package.js @@ -44,5 +44,4 @@ Package.onUse(function(api) { api.addFiles('server/v1/settings.js', 'server'); api.addFiles('server/v1/stats.js', 'server'); api.addFiles('server/v1/users.js', 'server'); - api.addFiles('server/v1/spotlight.js', 'server'); }); diff --git a/packages/rocketchat-api/server/v1/misc.js b/packages/rocketchat-api/server/v1/misc.js index dcc9df411f2f5..3937078483b5f 100644 --- a/packages/rocketchat-api/server/v1/misc.js +++ b/packages/rocketchat-api/server/v1/misc.js @@ -146,6 +146,22 @@ RocketChat.API.v1.addRoute('shield.svg', { authRequired: false }, { } }); +RocketChat.API.v1.addRoute('spotlight', { authRequired: true }, { + get() { + check(this.queryParams, { + query: String + }); + + const { query } = this.queryParams; + + const result = Meteor.runAsUser(this.userId, () => + Meteor.call('spotlight', query) + ); + + return RocketChat.API.v1.success(result); + } +}); + RocketChat.API.v1.addRoute('directory', { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); diff --git a/packages/rocketchat-api/server/v1/spotlight.js b/packages/rocketchat-api/server/v1/spotlight.js deleted file mode 100644 index 9dbea532fa11d..0000000000000 --- a/packages/rocketchat-api/server/v1/spotlight.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - This API returns the result of a query of rooms - and users, using Meteor's Spotlight method. - - Method: GET - Route: api/v1/spotlight - Query params: - - query: The term to be searched. - */ -RocketChat.API.v1.addRoute('spotlight', { authRequired: true }, { - get() { - check(this.queryParams, { - query: String - }); - - const { query } = this.queryParams; - - const result = Meteor.runAsUser(this.userId, () => - Meteor.call('spotlight', query, null, { - rooms: true, - users: true - }) - ); - - return RocketChat.API.v1.success(result); - } -}); diff --git a/packages/rocketchat-ui-sidenav/client/toolbar.js b/packages/rocketchat-ui-sidenav/client/toolbar.js index 69b85a75bc26a..536bbd4deb301 100644 --- a/packages/rocketchat-ui-sidenav/client/toolbar.js +++ b/packages/rocketchat-ui-sidenav/client/toolbar.js @@ -149,14 +149,15 @@ Template.toolbar.helpers({ query._id = query.rid; delete query.rid; } - - if (filterText[0] === '#') { + const searchForChannels = filterText[0] === '#'; + const searchForDMs = filterText[0] === '@'; + if (searchForChannels) { filterText = filterText.slice(1); type.users = false; query.t = 'c'; } - if (filterText[0] === '@') { + if (searchForDMs) { filterText = filterText.slice(1); type.rooms = false; query.t = 'd'; diff --git a/server/publications/spotlight.js b/server/publications/spotlight.js index 2514bb2a7107f..85708e9f73695 100644 --- a/server/publications/spotlight.js +++ b/server/publications/spotlight.js @@ -13,6 +13,16 @@ function fetchRooms(userId, rooms) { Meteor.methods({ spotlight(text, usernames, type = {users: true, rooms: true}, rid) { + const searchForChannels = text[0] === '#'; + const searchForDMs = text[0] === '@'; + if (searchForChannels) { + type.users = false; + text = text.slice(1); + } + if (searchForDMs) { + type.rooms = false; + text = text.slice(1); + } const regex = new RegExp(s.trim(s.escapeRegExp(text)), 'i'); const result = { users: [], diff --git a/tests/end-to-end/api/00-miscellaneous.js b/tests/end-to-end/api/00-miscellaneous.js index 4c29c369ba7f2..b239bbce2c125 100644 --- a/tests/end-to-end/api/00-miscellaneous.js +++ b/tests/end-to-end/api/00-miscellaneous.js @@ -2,8 +2,8 @@ /* globals expect */ /* eslint no-unused-vars: 0 */ -import {getCredentials, api, login, request, credentials} from '../../data/api-data.js'; -import {adminEmail, adminUsername, adminPassword, password} from '../../data/user.js'; +import { getCredentials, api, login, request, credentials } from '../../data/api-data.js'; +import { adminEmail, adminUsername, adminPassword, password } from '../../data/user.js'; import supertest from 'supertest'; describe('miscellaneous', function() { @@ -73,7 +73,6 @@ describe('miscellaneous', function() { .end(done); }); - describe('/directory', () => { let user; let testChannel; @@ -82,7 +81,7 @@ describe('miscellaneous', function() { const email = `${ username }@rocket.chat`; request.post(api('users.create')) .set(credentials) - .send({email, name: username, username, password}) + .send({ email, name: username, username, password }) .end((err, res) => { user = res.body.user; done(); @@ -165,6 +164,102 @@ describe('miscellaneous', function() { }) .end(done); }); + }); + describe('[/spotlight]', () => { + let user; + before((done) => { + const username = `user.test.${ Date.now() }`; + const email = `${ username }@rocket.chat`; + request.post(api('users.create')) + .set(credentials) + .send({ email, name: username, username, password }) + .end((err, res) => { + user = res.body.user; + done(); + }); + }); + let userCredentials; + let testChannel; + before((done) => { + request.post(api('login')) + .send({ + user: user.username, + password + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + userCredentials = {}; + userCredentials['X-Auth-Token'] = res.body.data.authToken; + userCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); + }); + after(done => { + request.post(api('users.delete')).set(credentials).send({ + userId: user._id + }).end(done); + user = undefined; + }); + it('create an channel', (done) => { + request.post(api('channels.create')) + .set(userCredentials) + .send({ + name: `channel.test.${ Date.now() }` + }) + .end((err, res) => { + testChannel = res.body.channel; + done(); + }); + }); + it('should fail when does not have query param', (done) => { + request.get(api('spotlight')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + }) + .end(done); + }); + it('should return object inside users array when search by a valid user', (done) => { + request.get(api('spotlight')) + .query({ + query: `@${ adminUsername }` + }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('users').and.to.be.an('array'); + expect(res.body.users[0]).to.have.property('_id'); + expect(res.body.users[0]).to.have.property('name'); + expect(res.body.users[0]).to.have.property('username'); + expect(res.body.users[0]).to.have.property('status'); + expect(res.body).to.have.property('rooms').and.to.be.an('array'); + }) + .end(done); + }); + it('must return the object inside the room array when searching for a valid room and that user is not a member of it', (done) => { + request.get(api('spotlight')) + .query({ + query: `#${ testChannel.name }` + }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('users').and.to.be.an('array'); + expect(res.body).to.have.property('rooms').and.to.be.an('array'); + expect(res.body.rooms[0]).to.have.property('_id'); + expect(res.body.rooms[0]).to.have.property('name'); + expect(res.body.rooms[0]).to.have.property('t'); + }) + .end(done); + }); }); }); diff --git a/tests/end-to-end/api/11-spotlight.js b/tests/end-to-end/api/11-spotlight.js deleted file mode 100644 index fcd9ca1a488f2..0000000000000 --- a/tests/end-to-end/api/11-spotlight.js +++ /dev/null @@ -1,40 +0,0 @@ -/* eslint-env mocha */ -/* globals expect */ - -import {getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[Spotlight]', function() { - this.retries(0); - - before(done => getCredentials(done)); - - describe('[/spotlight]', () => { - it('should fail when does not have query param', (done) => { - request.get(api('spotlight')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(400) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('error'); - }) - .end(done); - }); - - it('should return objects for a valid query param', (done) => { - request.get(api('spotlight')) - .query({ - query: 'foobar' - }) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('users').that.have.lengthOf(0); - expect(res.body).to.have.property('rooms').that.have.lengthOf(0); - }) - .end(done); - }); - }); -});