diff --git a/tests/data/api-data.js b/tests/data/api-data.js index 9f45ba970c8ef..79dbdc2f53dfb 100644 --- a/tests/data/api-data.js +++ b/tests/data/api-data.js @@ -41,6 +41,10 @@ export function api(path) { return prefix + path; } +export function methodCall(methodName) { + return api(`method.call/${ methodName }`); +} + export function log(res) { console.log(res.req.path); console.log({ diff --git a/tests/end-to-end/api/00-miscellaneous.js b/tests/end-to-end/api/00-miscellaneous.js index 97825c47c9c97..3190fe7c8a15f 100644 --- a/tests/end-to-end/api/00-miscellaneous.js +++ b/tests/end-to-end/api/00-miscellaneous.js @@ -3,6 +3,7 @@ import { expect } from 'chai'; import { getCredentials, api, login, request, credentials } from '../../data/api-data.js'; import { adminEmail, adminUsername, adminPassword, password } from '../../data/user.js'; import { createUser, login as doLogin } from '../../data/users.helper'; +import { updateSetting } from '../../data/permissions.helper'; describe('miscellaneous', function() { this.retries(0); @@ -504,4 +505,34 @@ describe('miscellaneous', function() { .end(done); }); }); + + describe('[/shield.svg]', () => { + it('should fail if API_Enable_Shields is disabled', (done) => { + updateSetting('API_Enable_Shields', false).then(() => { + request.get(api('shield.svg')) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-endpoint-disabled'); + }) + .end(done); + }); + }); + + it('should succeed if API_Enable_Shields is enabled', (done) => { + updateSetting('API_Enable_Shields', true).then(() => { + request.get(api('shield.svg')) + .query({ + type: 'online', + icon: true, + channel: 'general', + name: 'Rocket.Chat', + }) + .expect('Content-Type', 'image/svg+xml;charset=utf-8') + .expect(200) + .end(done); + }); + }); + }); }); diff --git a/tests/end-to-end/api/01-users.js b/tests/end-to-end/api/01-users.js index e27af2b046549..8b7501e3b0006 100644 --- a/tests/end-to-end/api/01-users.js +++ b/tests/end-to-end/api/01-users.js @@ -602,6 +602,126 @@ describe('[Users]', function() { }); }); + describe('[/users.resetAvatar]', () => { + let user; + before(async () => { + user = await createUser(); + }); + + let userCredentials; + before(async () => { + userCredentials = await login(user.username, password); + }); + before((done) => { + updatePermission('edit-other-user-info', ['admin', 'user']).then(done); + }); + after(async () => { + await deleteUser(user); + user = undefined; + await updatePermission('edit-other-user-info', ['admin']); + }); + it('should set the avatar of the logged user by a local image', (done) => { + request.post(api('users.setAvatar')) + .set(userCredentials) + .attach('image', imgURL) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + it('should reset the avatar of the logged user', (done) => { + request.post(api('users.resetAvatar')) + .set(userCredentials) + .expect('Content-Type', 'application/json') + .send({ + userId: userCredentials['X-User-Id'], + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + it('should reset the avatar of another user by userId when the logged user has the necessary permission (edit-other-user-info)', (done) => { + request.post(api('users.resetAvatar')) + .set(userCredentials) + .send({ + userId: credentials['X-User-Id'], + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + it('should reset the avatar of another user by username and local image when the logged user has the necessary permission (edit-other-user-info)', (done) => { + request.post(api('users.resetAvatar')) + .set(credentials) + .send({ + username: adminUsername, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + it.skip('should prevent from resetting someone else\'s avatar when the logged user has not the necessary permission(edit-other-user-info)', (done) => { + updatePermission('edit-other-user-info', []).then(() => { + request.post(api('users.resetAvatar')) + .set(userCredentials) + .send({ + userId: credentials['X-User-Id'], + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + }); + }); + + describe('[/users.getAvatar]', () => { + let user; + before(async () => { + user = await createUser(); + }); + + let userCredentials; + before(async () => { + userCredentials = await login(user.username, password); + }); + after(async () => { + await deleteUser(user); + user = undefined; + await updatePermission('edit-other-user-info', ['admin']); + }); + it('should get the url of the avatar of the logged user via userId', (done) => { + request.get(api('users.getAvatar')) + .set(userCredentials) + .query({ + userId: userCredentials['X-User-Id'], + }) + .expect(307) + .end(done); + }); + it('should get the url of the avatar of the logged user via username', (done) => { + request.get(api('users.getAvatar')) + .set(userCredentials) + .query({ + username: user.username, + }) + .expect(307) + .end(done); + }); + }); + describe('[/users.update]', () => { before((done) => { updateSetting('Accounts_AllowUserProfileChange', true) @@ -2287,6 +2407,133 @@ describe('[Users]', function() { }); }); + describe('[/users.deactivateIdle]', () => { + let testUser; + let testUserCredentials; + const testRoleName = `role.test.${ Date.now() }`; + + before('Create a new role with Users scope', (done) => { + request.post(api('roles.create')) + .set(credentials) + .send({ + name: testRoleName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + before('Create test user', (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) => { + testUser = res.body.user; + done(); + }); + }); + before('Assign a role to test user', (done) => { + request.post(api('roles.addUserToRole')) + .set(credentials) + .send({ + roleName: testRoleName, + username: testUser.username, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + before('Login as test user', (done) => { + request.post(api('login')) + .send({ + user: testUser.username, + password, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + testUserCredentials = {}; + testUserCredentials['X-Auth-Token'] = res.body.data.authToken; + testUserCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); + }); + + it('should fail to deactivate if user doesnt have edit-other-user-active-status permission', (done) => { + updatePermission('edit-other-user-active-status', []).then(() => { + request.post(api('users.deactivateIdle')) + .set(credentials) + .send({ + daysIdle: 0, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'unauthorized'); + }) + .end(done); + }); + }); + it('should deactivate no users when no users in time range', (done) => { + updatePermission('edit-other-user-active-status', ['admin']).then(() => { + request.post(api('users.deactivateIdle')) + .set(credentials) + .send({ + daysIdle: 999999, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count', 0); + }) + .end(done); + }); + }); + it('should deactivate the test user when given its role and daysIdle = 0', (done) => { + updatePermission('edit-other-user-active-status', ['admin']).then(() => { + request.post(api('users.deactivateIdle')) + .set(credentials) + .send({ + daysIdle: 0, + role: testRoleName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count', 1); + }) + .end(done); + }); + }); + it('should not deactivate the test user again when given its role and daysIdle = 0', (done) => { + updatePermission('edit-other-user-active-status', ['admin']).then(() => { + request.post(api('users.deactivateIdle')) + .set(credentials) + .send({ + daysIdle: 0, + role: testRoleName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count', 0); + }) + .end(done); + }); + }); + }); + describe('[/users.requestDataDownload]', () => { it('should return the request data with fullExport false when no query parameter was send', (done) => { request.get(api('users.requestDataDownload')) diff --git a/tests/end-to-end/api/02-channels.js b/tests/end-to-end/api/02-channels.js index 4b4b2cee4a03a..1c9cd0fb26136 100644 --- a/tests/end-to-end/api/02-channels.js +++ b/tests/end-to-end/api/02-channels.js @@ -182,6 +182,235 @@ describe('[Channels]', function() { }); }); + it('/channels.online', (done) => { + request.get(api('channels.online')) + .set(credentials) + .query({ + query: '{ "_id": "GENERAL" }', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('online').and.to.be.an('array'); + }) + .end(done); + }); + + describe('[/channels.files]', () => { + it('should fail if invalid channel', (done) => { + request.get(api('channels.files')) + .set(credentials) + .query({ + roomId: 'invalid', + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-room-not-found'); + }) + .end(done); + }); + + it('should succeed when searching by roomId', (done) => { + request.get(api('channels.files')) + .set(credentials) + .query({ + roomId: 'GENERAL', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('files').and.to.be.an('array'); + }) + .end(done); + }); + + it('should succeed when searching by roomName', (done) => { + request.get(api('channels.files')) + .set(credentials) + .query({ + roomName: 'general', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('files').and.to.be.an('array'); + }) + .end(done); + }); + }); + + describe('[/channels.join]', () => { + let testChannelNoCode; + let testChannelWithCode; + let testUser; + let testUserCredentials; + before('Create test user', (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) => { + testUser = res.body.user; + done(); + }); + }); + before('Login as test user', (done) => { + request.post(api('login')) + .send({ + user: testUser.username, + password, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + testUserCredentials = {}; + testUserCredentials['X-Auth-Token'] = res.body.data.authToken; + testUserCredentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); + }); + before('Create no code channel', (done) => { + request.post(api('channels.create')) + .set(testUserCredentials) + .send({ + name: `${ apiPublicChannelName }-nojoincode`, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + testChannelNoCode = res.body.channel; + }) + .end(done); + }); + before('Create code channel', (done) => { + request.post(api('channels.create')) + .set(testUserCredentials) + .send({ + name: `${ apiPublicChannelName }-withjoincode`, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + testChannelWithCode = res.body.channel; + }) + .end(done); + }); + before('Set code for channel', (done) => { + request.post(api('channels.setJoinCode')) + .set(testUserCredentials) + .send({ + roomId: testChannelWithCode._id, + joinCode: '123', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + + it('should fail if invalid channel', (done) => { + request.post(api('channels.join')) + .set(credentials) + .send({ + roomId: 'invalid', + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-room-not-found'); + }) + .end(done); + }); + + it('should succeed when joining code-free channel without join code', (done) => { + request.post(api('channels.join')) + .set(credentials) + .send({ + roomId: testChannelNoCode._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('channel._id', testChannelNoCode._id); + }) + .end(done); + }); + + it('should fail when joining code-needed channel without join code and no join-without-join-code permission', (done) => { + updatePermission('join-without-join-code', []).then(() => { + request.post(api('channels.join')) + .set(credentials) + .send({ + roomId: testChannelWithCode._id, + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.nested.property('errorType', 'error-code-invalid'); + }) + .end(done); + }); + }); + + it('should succeed when joining code-needed channel without join code and with join-without-join-code permission', (done) => { + updatePermission('join-without-join-code', ['admin']).then(() => { + request.post(api('channels.join')) + .set(credentials) + .send({ + roomId: testChannelWithCode._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('channel._id', testChannelWithCode._id); + }) + .end(done); + }); + }); + + it('leave channel', (done) => { + request.post(api('channels.leave')) + .set(credentials) + .send({ + roomId: testChannelWithCode._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + + it('should succeed when joining code-needed channel with join code', (done) => { + request.post(api('channels.join')) + .set(credentials) + .send({ + roomId: testChannelWithCode._id, + joinCode: '123', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('channel._id', testChannelWithCode._id); + }) + .end(done); + }); + }); + it('/channels.invite', async () => { const roomInfo = await getRoomInfo(channel._id); diff --git a/tests/end-to-end/api/03-groups.js b/tests/end-to-end/api/03-groups.js index a303cea914a23..e33c3b6aeda8d 100644 --- a/tests/end-to-end/api/03-groups.js +++ b/tests/end-to-end/api/03-groups.js @@ -537,6 +537,83 @@ describe('[Groups]', function() { .end(done); }); + it('/groups.online', (done) => { + request.get(api('groups.online')) + .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('online').and.to.be.an('array'); + }) + .end(done); + }); + + it('/groups.members', (done) => { + request.get(api('groups.members')) + .set(credentials) + .query({ + roomId: group._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('total'); + expect(res.body).to.have.property('offset'); + expect(res.body).to.have.property('members').and.to.be.an('array'); + }) + .end(done); + }); + + it('/groups.files', (done) => { + request.get(api('groups.files')) + .set(credentials) + .query({ + roomId: group._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('total'); + expect(res.body).to.have.property('offset'); + expect(res.body).to.have.property('files').and.to.be.an('array'); + }) + .end(done); + }); + + describe('/groups.listAll', () => { + it('should fail if the user doesnt have view-room-administration permission', (done) => { + updatePermission('view-room-administration', []).then(() => { + request.get(api('groups.listAll')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'unauthorized'); + }) + .end(done); + }); + }); + it('should succeed if user has view-room-administration permission', (done) => { + updatePermission('view-room-administration', ['admin']).then(() => { + request.get(api('groups.listAll')) + .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('groups').and.to.be.an('array'); + }) + .end(done); + }); + }); + }); + it('/groups.counters', (done) => { request.get(api('groups.counters')) .set(credentials) diff --git a/tests/end-to-end/api/04-direct-message.js b/tests/end-to-end/api/04-direct-message.js index 5cc76691b73fc..3899e77c70a75 100644 --- a/tests/end-to-end/api/04-direct-message.js +++ b/tests/end-to-end/api/04-direct-message.js @@ -10,6 +10,7 @@ import { apiEmail, } from '../../data/api-data.js'; import { password, adminUsername } from '../../data/user.js'; +import { updateSetting, updatePermission } from '../../data/permissions.helper'; describe('[Direct Messages]', function() { @@ -239,6 +240,82 @@ describe('[Direct Messages]', function() { .end(done); }); + it('/im.files', (done) => { + request.get(api('im.files')) + .set(credentials) + .query({ + roomId: directMessage._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('files'); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('offset'); + expect(res.body).to.have.property('total'); + }) + .end(done); + }); + + describe('/im.messages.others', () => { + it('should fail when the endpoint is disabled', (done) => { + updateSetting('API_Enable_Direct_Message_History_EndPoint', false).then(() => { + request.get(api('im.messages.others')) + .set(credentials) + .query({ + roomId: directMessage._id, + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-endpoint-disabled'); + }) + .end(done); + }); + }); + it('should fail when the endpoint is enabled but the user doesnt have permission', (done) => { + updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { + updatePermission('view-room-administration', []).then(() => { + request.get(api('im.messages.others')) + .set(credentials) + .query({ + roomId: directMessage._id, + }) + .expect('Content-Type', 'application/json') + .expect(403) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error', 'unauthorized'); + }) + .end(done); + }); + }); + }); + it('should succeed when the endpoint is enabled and user has permission', (done) => { + updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { + updatePermission('view-room-administration', ['admin']).then(() => { + request.get(api('im.messages.others')) + .set(credentials) + .query({ + roomId: directMessage._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('messages').and.to.be.an('array'); + expect(res.body).to.have.property('offset'); + expect(res.body).to.have.property('count'); + expect(res.body).to.have.property('total'); + }) + .end(done); + }); + }); + }); + }); + it('/im.close', (done) => { request.post(api('im.close')) .set(credentials) diff --git a/tests/end-to-end/api/05-chat.js b/tests/end-to-end/api/05-chat.js index 2572e3a168102..86ae717104c97 100644 --- a/tests/end-to-end/api/05-chat.js +++ b/tests/end-to-end/api/05-chat.js @@ -733,6 +733,7 @@ describe('[Chat]', function() { ytEmbedMsgId = ytPostResponse.body.message._id; imgUrlMsgId = imgUrlResponse.body.message._id; + imgUrlMsgId = imgUrlResponse.body.message._id; }); it('should have an iframe oembed with style max-width', (done) => { @@ -1475,6 +1476,112 @@ describe('[Chat]', function() { }); }); + describe('[/chat.unStarMessage]', () => { + it('should return an error when starMessage is not allowed in this server', (done) => { + updateSetting('Message_AllowStarring', false).then(() => { + request.post(api('chat.unStarMessage')) + .set(credentials) + .send({ + messageId: message._id, + }) + .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 unstar Message successfully', (done) => { + updateSetting('Message_AllowStarring', true).then(() => { + request.post(api('chat.unStarMessage')) + .set(credentials) + .send({ + messageId: message._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.not.have.property('error'); + }) + .end(done); + }); + }); + }); + + describe('[/chat.ignoreUser]', () => { + it('should fail if invalid roomId', (done) => { + request.get(api('chat.ignoreUser')) + .set(credentials) + .query({ + rid: 'invalid', + userId: 'rocket.cat', + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-invalid-subscription'); + }) + .end(() => { + done(); + }); + }); + it('should fail if invalid userId', (done) => { + request.get(api('chat.ignoreUser')) + .set(credentials) + .query({ + rid: 'rocket.catrocketchat.internal.admin.test', + userId: 'invalid', + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-invalid-subscription'); + }) + .end(() => { + done(); + }); + }); + it('should successfully ignore user', (done) => { + request.get(api('chat.ignoreUser')) + .set(credentials) + .query({ + rid: 'rocket.catrocketchat.internal.admin.test', + userId: 'rocket.cat', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(() => { + done(); + }); + }); + it('should successfully unignore user', (done) => { + request.get(api('chat.ignoreUser')) + .set(credentials) + .query({ + rid: 'rocket.catrocketchat.internal.admin.test', + userId: 'rocket.cat', + ignore: false, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(() => { + done(); + }); + }); + }); + describe('[/chat.getPinnedMessages]', () => { let roomId; before((done) => { diff --git a/tests/end-to-end/api/22-push-token.js b/tests/end-to-end/api/22-push-token.js new file mode 100644 index 0000000000000..2223d20c6c16c --- /dev/null +++ b/tests/end-to-end/api/22-push-token.js @@ -0,0 +1,192 @@ +import { expect } from 'chai'; + +import { getCredentials, api, request, credentials } from '../../data/api-data.js'; + +describe('push token', function() { + this.retries(0); + + before((done) => getCredentials(done)); + + describe('POST [/push.token]', () => { + it('should fail if not logged in', (done) => { + request.post(api('push.token')) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should fail if missing type', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + value: 'token', + appName: 'com.example.rocketchat', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-type-param-not-valid'); + }) + .end(done); + }); + + it('should fail if missing value', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + type: 'gcm', + appName: 'com.example.rocketchat', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-token-param-not-valid'); + }) + .end(done); + }); + + it('should fail if missing appName', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + type: 'gcm', + value: 'token', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-appName-param-not-valid'); + }) + .end(done); + }); + + it('should fail if type param is unknown', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + type: 'unknownPlatform', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-type-param-not-valid'); + }) + .end(done); + }); + + it('should fail if token param is empty', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + type: 'gcm', + appName: 'com.example.rocketchat', + value: '', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-token-param-not-valid'); + }) + .end(done); + }); + + it('should add a token if valid', (done) => { + request.post(api('push.token')) + .set(credentials) + .send({ + type: 'gcm', + value: 'token', + appName: 'com.example.rocketchat', + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('result').and.to.be.an('object'); + }) + .end(done); + }); + }); + + describe('DELETE [/push.token]', () => { + it('should fail if not logged in', (done) => { + request.delete(api('push.token')) + .send({ + token: 'token', + }) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should fail if missing token key', (done) => { + request.delete(api('push.token')) + .set(credentials) + .send({}) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-token-param-not-valid'); + }) + .end(done); + }); + + it('should fail if token is empty', (done) => { + request.delete(api('push.token')) + .set(credentials) + .send({ + token: '', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-token-param-not-valid'); + }) + .end(done); + }); + + it('should fail if token is invalid', (done) => { + request.delete(api('push.token')) + .set(credentials) + .send({ + token: '123', + }) + .expect(404) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + + it('should delete a token if valid', (done) => { + request.delete(api('push.token')) + .set(credentials) + .send({ + token: 'token', + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + + it('should fail if token is already deleted', (done) => { + request.delete(api('push.token')) + .set(credentials) + .send({ + token: 'token', + }) + .expect(404) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + }); +}); diff --git a/tests/end-to-end/api/23-invites.js b/tests/end-to-end/api/23-invites.js new file mode 100644 index 0000000000000..834a3704c778b --- /dev/null +++ b/tests/end-to-end/api/23-invites.js @@ -0,0 +1,230 @@ +import { expect } from 'chai'; + +import { getCredentials, api, request, credentials } from '../../data/api-data.js'; + +describe('Invites', function() { + let testInviteID; + this.retries(0); + + before((done) => getCredentials(done)); + describe('POST [/findOrCreateInvite]', () => { + it('should fail if not logged in', (done) => { + request.post(api('findOrCreateInvite')) + .send({ + rid: 'GENERAL', + days: 1, + maxUses: 10, + }) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should fail if invalid roomid', (done) => { + request.post(api('findOrCreateInvite')) + .set(credentials) + .send({ + rid: 'invalid', + days: 1, + maxUses: 10, + }) + .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 create an invite for GENERAL', (done) => { + request.post(api('findOrCreateInvite')) + .set(credentials) + .send({ + rid: 'GENERAL', + days: 1, + maxUses: 10, + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('days', 1); + expect(res.body).to.have.property('maxUses', 10); + expect(res.body).to.have.property('uses'); + expect(res.body).to.have.property('_id'); + testInviteID = res.body._id; + }) + .end(done); + }); + + it('should return an existing invite for GENERAL', (done) => { + request.post(api('findOrCreateInvite')) + .set(credentials) + .send({ + rid: 'GENERAL', + days: 1, + maxUses: 10, + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('days', 1); + expect(res.body).to.have.property('maxUses', 10); + expect(res.body).to.have.property('uses'); + expect(res.body).to.have.property('_id', testInviteID); + }) + .end(done); + }); + }); + + describe('GET [/listInvites]', () => { + it('should fail if not logged in', (done) => { + request.get(api('listInvites')) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should return the existing invite for GENERAL', (done) => { + request.get(api('listInvites')) + .set(credentials) + .expect(200) + .expect((res) => { + expect(res.body[0]).to.have.property('_id', testInviteID); + }) + .end(done); + }); + }); + + describe('POST [/useInviteToken]', () => { + it('should fail if not logged in', (done) => { + request.post(api('useInviteToken')) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should fail if invalid token', (done) => { + request.post(api('useInviteToken')) + .set(credentials) + .send({ + token: 'invalid', + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-invalid-token'); + }) + .end(done); + }); + + it('should fail if missing token', (done) => { + request.post(api('useInviteToken')) + .set(credentials) + .send({ + }) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'error-invalid-token'); + }) + .end(done); + }); + + it('should use the existing invite for GENERAL', (done) => { + request.post(api('useInviteToken')) + .set(credentials) + .send({ + token: testInviteID, + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + }); + + describe('POST [/validateInviteToken]', () => { + it('should warn if invalid token', (done) => { + request.post(api('validateInviteToken')) + .set(credentials) + .send({ + token: 'invalid', + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('valid', false); + }) + .end(done); + }); + + it('should succeed when valid token', (done) => { + request.post(api('validateInviteToken')) + .set(credentials) + .send({ + token: testInviteID, + }) + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('valid', true); + }) + .end(done); + }); + }); + + describe('DELETE [/removeInvite]', () => { + it('should fail if not logged in', (done) => { + request.delete(api(`removeInvite/${ testInviteID }`)) + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + + it('should fail if invalid token', (done) => { + request.delete(api('removeInvite/invalid')) + .set(credentials) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'invalid-invitation-id'); + }) + .end(done); + }); + + it('should succeed when valid token', (done) => { + request.delete(api(`removeInvite/${ testInviteID }`)) + .set(credentials) + .expect(200) + .expect((res) => { + expect(res.body).to.equal(true); + }) + .end(done); + }); + + it('should fail when deleting the same invite again', (done) => { + request.delete(api(`removeInvite/${ testInviteID }`)) + .set(credentials) + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('errorType', 'invalid-invitation-id'); + }) + .end(done); + }); + }); +}); diff --git a/tests/end-to-end/api/24-methods.js b/tests/end-to-end/api/24-methods.js new file mode 100644 index 0000000000000..91c6cc3346c42 --- /dev/null +++ b/tests/end-to-end/api/24-methods.js @@ -0,0 +1,192 @@ +import { expect } from 'chai'; + +import { getCredentials, request, methodCall, api, credentials } from '../../data/api-data.js'; + +describe('Meteor.methods', function() { + this.retries(0); + + before((done) => getCredentials(done)); + + describe('[@loadMissedMessages]', () => { + let rid = false; + const date = { + $date: new Date().getTime(), + }; + let postMessageDate = false; + + const channelName = `methods-test-channel-${ Date.now() }`; + + before('@loadMissedMessages', (done) => { + request.post(api('groups.create')) + .set(credentials) + .send({ + name: channelName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('group._id'); + expect(res.body).to.have.nested.property('group.name', channelName); + expect(res.body).to.have.nested.property('group.t', 'p'); + expect(res.body).to.have.nested.property('group.msgs', 0); + rid = res.body.group._id; + }) + .end(done); + }); + + before('@loadMissedMessages', (done) => { + request.post(api('chat.sendMessage')) + .set(credentials) + .send({ + message: { + text: 'Sample message', + rid, + }, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + postMessageDate = { $date: new Date().getTime() }; + }) + .end(done); + }); + + before('@loadMissedMessages', (done) => { + request.post(api('chat.sendMessage')) + .set(credentials) + .send({ + message: { + text: 'Second Sample message', + rid, + }, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + }) + .end(done); + }); + + it('should fail if not logged in', (done) => { + request.post(methodCall('loadMissedMessages')) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: [rid, date], + }), + }) + .expect('Content-Type', 'application/json') + .expect(401) + .expect((res) => { + expect(res.body).to.have.property('status', 'error'); + expect(res.body).to.have.property('message'); + }) + .end(done); + }); + + it('should return an error if the rid param is empty', (done) => { + request.post(methodCall('loadMissedMessages')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: ['', date], + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.include('error-invalid-room'); + }) + .end(done); + }); + + it('should return an error if the start param is missing', (done) => { + request.post(methodCall('loadMissedMessages')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: [rid], + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.include('Match error'); + }) + .end(done); + }); + + it('should return and empty list if using current time', (done) => { + request.post(methodCall('loadMissedMessages')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: [rid, { $date: new Date().getTime() }], + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('result').that.is.a('array'); + expect(data.result.length).to.be.equal(0); + }) + .end(done); + }); + + it('should return two messages if using a time from before the first msg was sent', (done) => { + request.post(methodCall('loadMissedMessages')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: [rid, date], + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('result').that.is.a('array'); + expect(data.result.length).to.be.equal(2); + }) + .end(done); + }); + + it('should return a single message if using a time from in between the messages', (done) => { + request.post(methodCall('loadMissedMessages')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'loadMissedMessages', + params: [rid, postMessageDate], + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('result').that.is.a('array'); + expect(data.result.length).to.be.equal(1); + }) + .end(done); + }); + }); +});