Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve: Apps-engine E2E tests #16781

Merged
merged 6 commits into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/apps/server/orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import { AppUploadsConverter } from './converters/uploads';
import { AppVisitorsConverter } from './converters/visitors';
import { AppRealLogsStorage, AppRealStorage } from './storage';

function isTesting() {
return process.env.TEST_MODE === 'true';
}


class AppServerOrchestrator {
constructor() {
Expand Down Expand Up @@ -97,7 +101,7 @@ class AppServerOrchestrator {
}

isDebugging() {
return settings.get('Apps_Framework_Development_Mode');
return settings.get('Apps_Framework_Development_Mode') && !isTesting();
}

getRocketChatLogger() {
Expand Down
8 changes: 8 additions & 0 deletions mocha_apps.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--require babel-mocha-es6-compiler
--require babel-polyfill
--reporter spec
--ui bdd
--timeout 10000
--bail
--file tests/end-to-end/teardown.js
tests/end-to-end/apps/*.js
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"testui": "cypress run --project tests",
"testunit": "mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"",
"testapi": "mocha --opts ./mocha_api.opts",
"testci": "npm run testapi && npm run testui",
"testapps": "mocha --opts ./mocha_apps.opts",
"testci": "npm run testapi && npm run testapps && npm run testui",
"translation-diff": "node .scripts/translationDiff.js",
"translation-fix-order": "node .scripts/fix-i18n.js",
"version": "node .scripts/version.js",
Expand Down
4 changes: 4 additions & 0 deletions tests/data/apps/apps-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.0.1.zip?raw=true';
export const APP_NAME = 'Apps.RocketChat.Tester';
export const APP_USERNAME = 'app.appsrocketchattester';
export const apps = (path = '') => `/api/apps${ path }`;
35 changes: 35 additions & 0 deletions tests/data/apps/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { request, credentials } from '../api-data';
import { apps, APP_URL, APP_NAME } from './apps-data';

export const getApps = () => new Promise((resolve) => {
request.get(apps())
.set(credentials)
.end((err, res) => {
resolve(res.body.apps);
});
});

export const removeAppById = (id) => new Promise((resolve) => {
request.delete(apps(`/${ id }`))
.set(credentials)
.end(resolve);
});

export const cleanupApps = async () => {
const apps = await getApps();
const testApp = apps.find((app) => app.name === APP_NAME);
if (testApp) {
await removeAppById(testApp.id);
}
};

export const installTestApp = () => new Promise((resolve) => {
request.post(apps())
.set(credentials)
.send({
url: APP_URL,
})
.end((err, res) => {
resolve(res.body.app);
});
});
14 changes: 14 additions & 0 deletions tests/data/chat.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,17 @@ export const deleteMessage = ({ roomId, msgId }) => {
msgId,
});
};

export const getMessageById = ({ msgId }) => {
if (!msgId) {
throw new Error('"msgId" is required in "getMessageById" test helper');
}

return new Promise((resolve) => {
request.get(api(`chat.getMessage?msgId=${ msgId }`))
.set(credentials)
.end((err, res) => {
resolve(res.body.message);
});
});
};
8 changes: 8 additions & 0 deletions tests/data/users.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,11 @@ export const login = (username, password) => new Promise((resolve) => {
resolve(userCredentials);
});
});

export const getUserByUsername = (username) => new Promise((resolve) => {
request.get(api(`users.info?username=${ username }`))
.set(credentials)
.end((err, res) => {
resolve(res.body.user);
});
});
107 changes: 107 additions & 0 deletions tests/end-to-end/apps/00-installation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { expect } from 'chai';

import { getCredentials, request, credentials, api } from '../../data/api-data.js';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { APP_URL, apps, APP_USERNAME } from '../../data/apps/apps-data.js';
import { cleanupApps } from '../../data/apps/helper.js';
import { getUserByUsername } from '../../data/users.helper.js';

describe('Apps - Installation', function() {
this.retries(0);

before((done) => getCredentials(done));

before(async () => cleanupApps());

describe('[Installation]', () => {
it('should throw an error when trying to install an app and the apps framework is enabled but the user does not have the permission', (done) => {
updateSetting('Apps_Framework_Development_Mode', true)
.then(() => updatePermission('manage-apps', []))
.then(() => {
request.post(apps())
.set(credentials)
.send({
url: APP_URL,
})
.expect('Content-Type', 'application/json')
.expect(403)
.expect((res) => {
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('User does not have the permissions required for this action [error-unauthorized]');
})
.end(done);
});
});
it('should throw an error when trying to install an app and the apps framework is disabled', (done) => {
updateSetting('Apps_Framework_Development_Mode', false)
.then(() => updatePermission('manage-apps', ['admin']))
.then(() => {
request.post(apps())
.set(credentials)
.send({
url: APP_URL,
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.a.property('success', false);
expect(res.body.error).to.be.equal('Installation from url is disabled.');
})
.end(done);
});
});
it('should install the app successfully from a URL', (done) => {
updateSetting('Apps_Framework_Development_Mode', true)
.then(() => {
request.post(apps())
.set(credentials)
.send({
url: APP_URL,
})
.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('app');
expect(res.body.app).to.have.a.property('id');
expect(res.body.app).to.have.a.property('version');
expect(res.body.app).to.have.a.property('status').and.to.be.equal('auto_enabled');
})
.end(done);
});
});
it('should have created the app user successfully', (done) => {
getUserByUsername(APP_USERNAME)
.then((user) => {
expect(user.username).to.be.equal(APP_USERNAME);
})
.then(done);
});
describe('Slash commands registration', () => {
it('should have created the "test-simple" slash command successfully', (done) => {
request.get(api('commands.get?command=test-simple'))
.set(credentials)
.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('command');
expect(res.body.command.command).to.be.equal('test-simple');
})
.end(done);
});
it('should have created the "test-with-arguments" slash command successfully', (done) => {
request.get(api('commands.get?command=test-with-arguments'))
.set(credentials)
.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('command');
expect(res.body.command.command).to.be.equal('test-with-arguments');
})
.end(done);
});
});
});
});
111 changes: 111 additions & 0 deletions tests/end-to-end/apps/01-send-messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { expect } from 'chai';

import { getCredentials, request, credentials } from '../../data/api-data.js';
import { apps } from '../../data/apps/apps-data.js';
import { cleanupApps, installTestApp } from '../../data/apps/helper.js';
import { getMessageById } from '../../data/chat.helper.js';
import { createRoom } from '../../data/rooms.helper';

describe('Apps - Send Messages As APP User', function() {
this.retries(0);
let app;

before((done) => getCredentials(done));
before(async () => {
await cleanupApps();
app = await installTestApp();
});

describe('[Send Message as app user]', () => {
it('should return an error when the room is not found', (done) => {
request.post(apps(`/public/${ app.id }/send-message-as-app-user`))
.send({
roomId: 'invalid-room',
})
.set(credentials)
.expect(404)
.expect((err, res) => {
expect(err).to.have.a.property('error');
expect(res).to.be.equal(undefined);
expect(err.error).to.have.a.property('text');
expect(err.error.text).to.be.equal('Room "invalid-room" could not be found');
})
.end(done);
});
describe('Send to a Public Channel', () => {
let publicMessageId;
it('should send a message as app user', (done) => {
request.post(apps(`/public/${ app.id }/send-message-as-app-user`))
.set(credentials)
.send({
roomId: 'GENERAL',
})
.expect(200)
.expect((res) => {
const response = JSON.parse(res.text);
expect(response).to.have.a.property('messageId');
publicMessageId = response.messageId;
})
.end(done);
});
it('should be a valid message', async () => {
const message = await getMessageById({ msgId: publicMessageId });
expect(message.msg).to.be.equal('Executing send-message-as-app-user test endpoint');
});
});
describe('Send to a Private Channel', () => {
let privateMessageId;
it('should send a message as app user', (done) => {
createRoom({
type: 'p',
name: `apps-e2etest-room-${ Date.now() }`,
})
.end((err, createdRoom) => {
request.post(apps(`/public/${ app.id }/send-message-as-app-user`))
.set(credentials)
.send({
roomId: createdRoom.body.group._id,
})
.expect(200)
.expect((res) => {
const response = JSON.parse(res.text);
expect(response).to.have.a.property('messageId');
privateMessageId = response.messageId;
})
.end(done);
});
});
it('should be a valid message', async () => {
const message = await getMessageById({ msgId: privateMessageId });
expect(message.msg).to.be.equal('Executing send-message-as-app-user test endpoint');
});
});
describe('Send to a DM Channel', () => {
let DMMessageId;
it('should send a message as app user', (done) => {
createRoom({
type: 'd',
username: 'rocket.cat',
})
.end((err, createdRoom) => {
request.post(apps(`/public/${ app.id }/send-message-as-app-user`))
.set(credentials)
.send({
roomId: createdRoom.body.room._id,
})
.expect(200)
.expect((res) => {
const response = JSON.parse(res.text);
expect(response).to.have.a.property('messageId');
DMMessageId = response.messageId;
})
.end(done);
});
});
it('should be a valid message', async () => {
const message = await getMessageById({ msgId: DMMessageId });
expect(message.msg).to.be.equal('Executing send-message-as-app-user test endpoint');
});
});
});
});
Loading