Skip to content

Commit

Permalink
E2E: Fix test for email notification (mattermost#3032)
Browse files Browse the repository at this point in the history
* fix email notification

* create new test user instead of using user-2
  • Loading branch information
saturninoabril authored and Bob Lubecker committed Jul 2, 2019
1 parent de35928 commit d6ed968
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 35 deletions.
1 change: 0 additions & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"baseUrl": "http:https://localhost:8065",
"mailboxAPI": "http:https://localhost:9000/api/v1/mailbox/",
"viewportWidth": 1300,
"defaultCommandTimeout": 20000,
"taskTimeout": 20000,
Expand Down
50 changes: 34 additions & 16 deletions cypress/integration/email/mention_email_notification_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,47 @@
import users from '../../fixtures/users.json';
import * as TIMEOUTS from '../../fixtures/timeouts';

import {reUrl} from '../../utils';
import {getEmailUrl, getEmailMessageSeparator, reUrl} from '../../utils';

const user1 = users['user-1'];
const user2 = users['user-2'];

const text = `Hello @${user2.username}`;
const feedbackEmail = '[email protected]';
let config;

describe('Email notification', () => {
let mentionedUser;

before(() => {
cy.apiUpdateConfig({EmailSettings: {FeedbackEmail: feedbackEmail}});
cy.apiGetConfig().then((response) => {
config = response.body;
});

cy.visit('/');
cy.url().should('include', '/channels/town-square');

cy.getCurrentTeamId().then((teamId) => {
cy.createNewUser({}, [teamId]).then((user) => {
mentionedUser = user;
});
});
});

it('post a message that mentions a user', () => {
// # Login as user-1 and visit town-square channel
cy.apiLogin('user-1');
cy.visit('/ad-1/channels/town-square');

// # Post a message mentioning the new user
const text = `Hello @${mentionedUser.username}`;
cy.postMessage(text);

// Wait for a while to ensure that email notification is sent.
cy.wait(TIMEOUTS.SMALL);

cy.task('getRecentEmail', {username: 'user-2'}).then((response) => {
verifyEmailNotification(response, 'eligendi', 'Town Square', user2, user1, text, feedbackEmail);
const baseUrl = Cypress.config('baseUrl');
const mailUrl = getEmailUrl(baseUrl);

cy.task('getRecentEmail', {username: mentionedUser.username, mailUrl}).then((response) => {
const messageSeparator = getEmailMessageSeparator(baseUrl);
const user1 = users['user-1'];
verifyEmailNotification(response, config.TeamSettings.SiteName, 'eligendi', 'Town Square', mentionedUser, user1, text, config.EmailSettings.FeedbackEmail, config.SupportSettings.SupportEmail, messageSeparator);

const bodyText = response.data.body.text.split('\n');

Expand All @@ -55,36 +73,36 @@ describe('Email notification', () => {
});
});

function verifyEmailNotification(response, teamDisplayName, channelDisplayName, mentionedUser, byUser, message, fromEmail) {
function verifyEmailNotification(response, siteName, teamDisplayName, channelDisplayName, mentionedUser, byUser, message, feedbackEmail, supportEmail, messageSeparator) {
const isoDate = new Date().toISOString().substring(0, 10);
const {data, status} = response;

// * Should return success status
expect(status).to.equal(200);

// * Verify that email is addressed to user-2
// * Verify that email is addressed to mentionedUser
expect(data.to.length).to.equal(1);
expect(data.to[0]).to.contain(mentionedUser.email);

// * Verify that email is from default feedback email
expect(data.from).to.contain(fromEmail);
expect(data.from).to.contain(feedbackEmail);

// * Verify that date is current
expect(data.date).to.contain(isoDate);

// * Verify that the email subject is correct
expect(data.subject).to.contain(`[Mattermost] Notification in ${teamDisplayName}`);
expect(data.subject).to.contain(`[${siteName}] Notification in ${teamDisplayName}`);

// * Verify that the email body is correct
const bodyText = data.body.text.split('\r\n');
const bodyText = data.body.text.split(messageSeparator);
expect(bodyText.length).to.equal(16);
expect(bodyText[1]).to.equal('You have a new notification.');
expect(bodyText[4]).to.equal(`Channel: ${channelDisplayName}`);
expect(bodyText[5]).to.contain(`@${byUser.username}`);
expect(bodyText[7]).to.equal(`${message}`);
expect(bodyText[9]).to.contain('Go To Post');
expect(bodyText[11]).to.equal('Any questions at all, mail us any time: [email protected]');
expect(bodyText[11]).to.equal(`Any questions at all, mail us any time: ${supportEmail}`);
expect(bodyText[12]).to.equal('Best wishes,');
expect(bodyText[13]).to.equal('The Mattermost Team');
expect(bodyText[13]).to.equal(`The ${siteName} Team`);
expect(bodyText[15]).to.equal('To change your notification preferences, log in to your team site and go to Account Settings > Notifications.');
}
31 changes: 17 additions & 14 deletions cypress/integration/signin_authentication/forgot_password_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@

/*eslint max-nested-callbacks: ["error", 5]*/

import {reUrl} from '../../utils';
import {getEmailUrl, getEmailMessageSeparator, reUrl} from '../../utils';

const feedbackEmail = '[email protected]';
let config;

describe('Signin/Authentication', () => {
before(() => {
cy.apiUpdateConfig({EmailSettings: {FeedbackEmail: feedbackEmail}});
cy.apiGetConfig().then((response) => {
config = response.body;
});
Expand All @@ -26,12 +24,12 @@ describe('Signin/Authentication', () => {
cy.loginAsNewUser().then((user) => {
cy.apiLogout();

resetPasswordAndLogin(user, feedbackEmail);
resetPasswordAndLogin(user, config.EmailSettings.FeedbackEmail, config.SupportSettings.SupportEmail);
});
});
});

function verifyForgotPasswordEmail(response, toUser, fromEmail) {
function verifyForgotPasswordEmail(response, toUser, feedbackEmail, supportEmail, messageSeparator) {
const isoDate = new Date().toISOString().substring(0, 10);
const {data, status} = response;

Expand All @@ -43,7 +41,7 @@ function verifyForgotPasswordEmail(response, toUser, fromEmail) {
expect(data.to[0]).to.contain(toUser.email);

// * Verify that email is from default feedback email
expect(data.from).to.contain(fromEmail);
expect(data.from).to.contain(feedbackEmail);

// * Verify that date is current
expect(data.date).to.contain(isoDate);
Expand All @@ -52,19 +50,19 @@ function verifyForgotPasswordEmail(response, toUser, fromEmail) {
expect(data.subject).to.equal(`[${config.TeamSettings.SiteName}] Reset your password`);

// * Verify that the email body is correct
const bodyText = data.body.text.split('\r\n');
const bodyText = data.body.text.split(messageSeparator);
expect(bodyText.length).to.equal(14);
expect(bodyText[1]).to.equal('You requested a password reset');
expect(bodyText[4]).to.equal('To change your password, click "Reset Password" below.');
expect(bodyText[5]).to.contain('If you did not mean to reset your password, please ignore this email and your password will remain the same. The password reset link expires in 24 hours.');
expect(bodyText[7]).to.contain('Reset Password');
expect(bodyText[9]).to.contain('Any questions at all, mail us any time: [email protected]');
expect(bodyText[9]).to.contain(`Any questions at all, mail us any time: ${supportEmail}`);
expect(bodyText[10]).to.equal('Best wishes,');
expect(bodyText[11]).to.equal(`The ${config.TeamSettings.SiteName} Team`);
expect(bodyText[13]).to.equal('To change your notification preferences, log in to your team site and go to Account Settings > Notifications.');
}

function resetPasswordAndLogin(user, fromEmail) {
function resetPasswordAndLogin(user, feedbackEmail, supportEmail) {
const newPassword = 'newpasswd';

// # Visit '/'
Expand Down Expand Up @@ -94,11 +92,16 @@ function resetPasswordAndLogin(user, fromEmail) {
cy.get('span').last().should('have.text', 'Please check your inbox.');
});

cy.task('getRecentEmail', {username: user.username}).then((response) => {
const baseUrl = Cypress.config('baseUrl');
const mailUrl = getEmailUrl(baseUrl);

cy.task('getRecentEmail', {username: user.username, mailUrl}).then((response) => {
const separator = getEmailMessageSeparator(baseUrl);

// * Verify contents password reset email
verifyForgotPasswordEmail(response, user, fromEmail);
verifyForgotPasswordEmail(response, user, feedbackEmail, supportEmail, separator);

const bodyText = response.data.body.text.split('\r\n');
const bodyText = response.data.body.text.split(separator);
const passwordResetLink = bodyText[7].match(reUrl)[0];
const token = passwordResetLink.split('token=')[1];

Expand Down Expand Up @@ -127,8 +130,8 @@ function resetPasswordAndLogin(user, fromEmail) {
cy.get('#loginPassword').should('be.visible').type(newPassword);
cy.get('#loginButton').click();

// * Verify that it successfully logged in and redirects to /ad-1/channels/town-square
cy.url().should('contain', '/ad-1/channels/town-square');
// * Verify that it successfully logged in and redirects to /channels/town-square
cy.url().should('contain', '/channels/town-square');

// # Logout
cy.apiLogout();
Expand Down
10 changes: 6 additions & 4 deletions cypress/plugins/get_recent_email.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

const axios = require('axios');

const cypressConfig = require('../../cypress.json');

module.exports = async ({username}) => {
const mailboxUrl = cypressConfig.mailboxAPI + username;
module.exports = async ({username, mailUrl}) => {
const mailboxUrl = `${mailUrl}/${username}`;
let response;
let recentEmail;

Expand All @@ -17,6 +15,10 @@ module.exports = async ({username}) => {
return {status: error.status, data: null};
}

if (!recentEmail || !recentEmail.id) {
return {status: 501, data: null};
}

let recentEmailMessage;
const mailMessageUrl = `${mailboxUrl}/${recentEmail.id}`;
try {
Expand Down
18 changes: 18 additions & 0 deletions cypress/support/api_commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,24 @@ Cypress.Commands.add('loginAsNewUser', (user = {}) => {
});
});

/**
* Saves channel display mode preference of a user directly via API
* This API assume that the user is logged in and has cookie to access
* @param {String} status - "online" (default), "offline", "away" or "dnd"
*/
Cypress.Commands.add('apiUpdateUserStatus', (status = 'online') => {
return cy.getCookie('MMUSERID').then((cookie) => {
const data = {user_id: cookie.value, status};

return cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/users/me/status',
method: 'PUT',
body: data,
});
});
});

// *****************************************************************************
// Posts
// https://api.mattermost.com/#tag/posts
Expand Down
16 changes: 16 additions & 0 deletions cypress/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,21 @@ export function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}

export function getEmailUrl(baseUrl) {
if (baseUrl === 'http:https://localhost:8065') {
return 'http:https://localhost:9000/api/v1/mailbox';
}

return `${baseUrl}/mail`;
}

export function getEmailMessageSeparator(baseUrl) {
if (baseUrl === 'http:https://localhost:8065') {
return '\r\n';
}

return '\n';
}

export const reUrl = /(https?:\/\/[^ ]*)/;

0 comments on commit d6ed968

Please sign in to comment.