Этот коммит содержится в:
Mario Vitale
2023-03-27 16:28:42 +02:00
родитель da7a6825ce
Коммит ba6b97fb62
1142 изменённых файлов: 44 добавлений и 44 удалений

Просмотреть файл

@@ -0,0 +1,74 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
describe('Notifications', () => {
let testTeam;
let otherUser;
before(() => {
cy.apiInitSetup({loginAfter: true}).then(({team, user}) => {
testTeam = team;
otherUser = user;
cy.visit(`/${testTeam.name}`);
// # Open 'Settings' modal
cy.uiOpenSettingsModal().within(() => {
// # Open 'Words That Trigger Mentions' setting and uncheck all the checkboxes
cy.findByRole('heading', {name: 'Words That Trigger Mentions'}).should('be.visible').click();
cy.findByRole('checkbox', {name: `Your case-sensitive first name "${otherUser.first_name}"`}).should('not.be.checked');
cy.findByRole('checkbox', {name: `Your non case-sensitive username "${otherUser.username}"`}).should('not.be.checked');
cy.findByRole('checkbox', {name: 'Channel-wide mentions "@channel", "@all", "@here"'}).click().should('not.be.checked');
cy.findByRole('checkbox', {name: 'Other non case-sensitive words, separated by commas:'}).should('not.be.checked');
// # Save then close the modal
cy.uiSaveAndClose();
});
cy.apiLogout();
// # Login as sysadmin
cy.apiAdminLogin();
cy.visit(`/${testTeam.name}`);
});
});
it('MM-T550 Words that trigger mentions - @-icon still shows mentions list if all triggers deselected', () => {
const text = `${otherUser.username} test message!`;
// # Type @ in the input box
cy.focused().type('@');
// * Make sure that the suggestion list is visible and that otherUser's username is visible
cy.get('#suggestionList').should('be.visible').within(() => {
cy.findByText(`@${otherUser.username}`).should('be.visible');
});
// # Post the text that was declared earlier and logout from sysadmin account
cy.focused().type(`${text}{enter}{enter}`);
cy.apiLogout();
// # Login as otherUser and visit the team
cy.apiLogin(otherUser);
cy.visit(`/${testTeam.name}`);
// # Click on the @ button
cy.uiGetRecentMentionButton().click();
cy.get('#search-items-container').should('be.visible').within(() => {
// * Ensure that the mentions are visible in the RHS
cy.findByText(`@${otherUser.username}`).should('be.visible');
cy.findByText('test message!').should('be.visible');
});
});
});

Просмотреть файл

@@ -0,0 +1,285 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notification
import {getAdminAccount} from '../../../support/env';
import {spyNotificationAs} from '../../../support/notification';
describe('Notifications', () => {
const admin = getAdminAccount();
let testTeam;
let testChannel;
let otherChannel;
let receiver;
let sender;
before(() => {
cy.apiInitSetup({userPrefix: 'receiver'}).then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
receiver = user;
return cy.apiCreateChannel(team.id, 'test', 'Test');
}).then(({channel}) => {
otherChannel = channel;
return cy.apiCreateUser({prefix: 'sender'});
}).then(({user}) => {
sender = user;
return cy.apiAddUserToTeam(testTeam.id, sender.id);
}).then(() => {
cy.apiAddUserToChannel(testChannel.id, sender.id);
cy.apiAddUserToChannel(otherChannel.id, sender.id);
return cy.apiAddUserToChannel(otherChannel.id, receiver.id);
}).then(() => {
// # Login as receiver and visit off-topic channel
cy.apiLogin(receiver);
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
cy.get(`#sidebarItem_${otherChannel.name}`).click();
cy.get('#sidebarItem_off-topic').click();
});
});
it('MM-T547 still triggers notification if username is not listed in words that trigger mentions', () => {
// # Set Notification settings
setNotificationSettings({first: false, username: true, shouts: true, custom: true}, 'off-topic');
const message = `@${receiver.username} I'm messaging you! ${Date.now()}`;
// # Use another account to post a message @-mentioning our receiver
cy.postMessageAs({sender, message, channelId: otherChannel.id});
const body = `@${sender.username}: ${message}`;
cy.get('@notifySpy').should('have.been.calledWithMatch', otherChannel.display_name, (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${body}"`).to.equal(body);
expect(args.tag, `Notification tag: "${args.tag}" should match: "${body}"`).to.equal(body);
return true;
});
cy.get('@notifySpy').should('have.been.calledWithMatch',
otherChannel.display_name, {body, tag: body, requireInteraction: false, silent: false});
// * Verify unread mentions badge
cy.get(`#sidebarItem_${otherChannel.name}`).
scrollIntoView().
find('#unreadMentions').
should('be.visible').
and('have.text', '1');
// * Go to that channel
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify entire message
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
// * Verify highlight of username
cy.get('@postMessageText').
find(`[data-mention=${receiver.username}]`).
should('be.visible').
and('have.text', `@${receiver.username}`);
});
it('MM-T545 does not trigger notifications with "Your non case-sensitive username" unchecked', () => {
// # Set Notification settings
setNotificationSettings({first: false, username: false, shouts: true, custom: true}, 'off-topic');
const message = `Hey ${receiver.username}! I'm messaging you! ${Date.now()}`;
// # Use another account to post a message @-mentioning our receiver
cy.postMessageAs({sender, message, channelId: otherChannel.id});
// * Verify stub was not called
cy.get('@notifySpy').should('be.not.called');
// * Verify unread mentions badge does not exist
cy.get(`#sidebarItem_${otherChannel.name}`).
scrollIntoView().
find('#unreadMentions').
should('not.exist');
// # Go to the channel where you were messaged
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify message contents
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
// * Verify it's not highlighted
cy.get('@postMessageText').
find(`[data-mention=${receiver.username}]`).
should('not.exist');
});
it('MM-T548 does not trigger notifications with "channel-wide mentions" unchecked', () => {
// # Set Notification settings
setNotificationSettings({first: false, username: false, shouts: false, custom: true}, 'off-topic');
const channelMentions = ['@here', '@all', '@channel'];
channelMentions.forEach((mention) => {
const message = `Hey ${mention} I'm message you all! ${Date.now()}`;
// # Use another account to post a message @-mentioning our receiver
cy.postMessageAs({sender, message, channelId: otherChannel.id});
// * Verify stub was not called
cy.get('@notifySpy').should('be.not.called');
// * Verify unread mentions badge does not exist
cy.get(`#sidebarItem_${otherChannel.name}`).
find('#unreadMentions').
should('not.exist');
// # Go to the channel where you were messaged
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify message contents
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
// * Verify it's not highlighted
cy.get('@postMessageText').
find(`[data-mention=${receiver.username}]`).
should('not.exist');
});
});
it('MM-T184 Words that trigger mentions support Chinese', () => {
var customText = '番茄';
// # Set Notification settings
setNotificationSettings({first: false, username: false, shouts: false, custom: true, customText}, 'off-topic');
const message = '番茄 I\'m messaging you!';
const message2 = '我爱吃番茄炒饭 I\'m messaging you!';
// # Use another account to post a message @-mentioning our receiver
cy.postMessageAs({sender, message, channelId: otherChannel.id});
// # Check mention on other channel
// * Verify unread mentions badge
cy.get(`#sidebarItem_${otherChannel.name}`).
scrollIntoView().
find('#unreadMentions').
should('be.visible').
and('have.text', '1');
// * Go to that channel
cy.get(`#sidebarItem_${otherChannel.name}`).click({force: true});
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify entire message
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
// * Verify highlight of username
cy.get('@postMessageText').
find('.mention--highlight').
should('be.visible').
and('have.text', '番茄');
// # Check mention on test channel
cy.postMessageAs({sender: admin, message: message2, channelId: testChannel.id});
// * Verify unread mentions badge
cy.get(`#sidebarItem_${testChannel.name}`).
scrollIntoView().
find('#unreadMentions').
should('be.visible').
and('have.text', '1');
// * Go to that channel
cy.get(`#sidebarItem_${testChannel.name}`).click({force: true});
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify entire message
cy.get('@postMessageText').
should('be.visible').
and('have.text', message2);
// * Verify highlight of username
cy.get('@postMessageText').
find('.mention--highlight').
should('be.visible').
and('have.text', '番茄');
});
});
function setNotificationSettings(desiredSettings = {first: true, username: true, shouts: true, custom: true, customText: '@'}, channelName) {
// Navigate to settings modal
cy.uiOpenSettingsModal();
// Notifications header should be visible
cy.get('#notificationSettingsTitle').
scrollIntoView().
should('be.visible').
and('contain', 'Notifications');
// Open up 'Words that trigger mentions' sub-section
cy.get('#keysTitle').
scrollIntoView().
click();
const settings = [
{key: 'first', selector: '#notificationTriggerFirst'},
{key: 'username', selector: '#notificationTriggerUsername'},
{key: 'shouts', selector: '#notificationTriggerShouts'},
{key: 'custom', selector: '#notificationTriggerCustom'},
];
// Set check boxes to desired state
settings.forEach((setting) => {
const checkbox = desiredSettings[setting.key] ? {state: 'check', verify: 'be.checked'} : {state: 'uncheck', verify: 'not.be.checked'};
cy.get(setting.selector)[checkbox.state]().should(checkbox.verify);
});
// Set Custom field
if (desiredSettings.custom && desiredSettings.customText) {
cy.get('#notificationTriggerCustomText').
clear().
type(desiredSettings.customText);
}
// Click “Save” and close modal
cy.uiSaveAndClose();
// Setup notification spy
spyNotificationAs('notifySpy', 'granted');
// # Navigate to a channel we are NOT going to post to
cy.get(`#sidebarItem_${channelName}`).scrollIntoView().click({force: true});
}

Просмотреть файл

@@ -0,0 +1,70 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testUser;
let testTeam;
let otherTeam;
let testTeamTownSquareUrl;
let siteName;
before(() => {
cy.apiGetConfig().then(({config}) => {
siteName = config.TeamSettings.SiteName;
});
cy.apiCreateTeam('team-b', 'Team B').then(({team}) => {
otherTeam = team;
});
cy.apiInitSetup().then(({team, user, townSquareUrl}) => {
testTeam = team;
testUser = user;
testTeamTownSquareUrl = townSquareUrl;
cy.apiAddUserToTeam(otherTeam.id, testUser.id);
cy.apiCreateUser().then(({user: otherUser}) => {
cy.apiAddUserToTeam(team.id, otherUser.id);
});
// # Remove mention notification (for initial channel).
cy.apiLogin(testUser);
cy.visit(testTeamTownSquareUrl);
cy.postMessage('hello');
cy.get('#sidebar-left').get('.unread-title').click();
// * Wait for some time, then verify that the badge is removed before logging out.
cy.wait(TIMEOUTS.ONE_SEC);
cy.get('.badge').should('not.exist');
cy.apiLogout();
});
});
it('MM-T556 Browser tab and team sidebar notification - no unreads/mentions', () => {
// # Test user views test team
cy.apiLogin(testUser);
cy.visit(testTeamTownSquareUrl);
cy.title().should('include', `Town Square - ${testTeam.display_name} ${siteName}`);
// * Browser tab shows channel name with no unread indicator
cy.get(`#${testTeam.name}TeamButton`).parent('.unread').should('not.exist');
cy.get('.badge').should('not.exist');
// * No unread/mention indicator in other team's sidebar
cy.get(`#${otherTeam.name}TeamButton`).parent('.unread').should('not.exist');
cy.get('.badge').should('not.exist');
});
});

Просмотреть файл

@@ -0,0 +1,151 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let user1;
let user2;
let team1;
let team2;
let testTeam1TownSquareUrl;
let testTeam2TownSquareUrl;
let siteName;
before(() => {
cy.apiGetConfig().then(({config}) => {
siteName = config.TeamSettings.SiteName;
});
cy.apiCreateUser().then(({user: otherUser}) => {
user2 = otherUser;
});
cy.apiCreateTeam('team-b', 'Team B').then(({team}) => {
team2 = team;
testTeam2TownSquareUrl = `/${team2.name}/channels/town-square`;
});
cy.apiInitSetup().then(({team, user, townSquareUrl}) => {
team1 = team;
user1 = user;
testTeam1TownSquareUrl = townSquareUrl;
cy.apiAddUserToTeam(team1.id, user2.id);
cy.apiAddUserToTeam(team2.id, user1.id);
cy.apiAddUserToTeam(team2.id, user2.id);
// # Remove mention notification (for initial channel).
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
cy.postMessage('hello');
cy.get('#sidebar-left').get('.unread-title').click();
// * Wait for some time, then verify that the badge is removed before logging out.
cy.wait(TIMEOUTS.ONE_SEC);
cy.get('.badge').should('not.exist');
cy.apiLogout();
});
});
it('MM-T560_1 Browser tab and team sidebar unreads and mentions - Mention in different team', () => {
// # User 1 views team A
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
// # Return to town square
cy.visit(testTeam1TownSquareUrl);
// * Check for no unreads or mentions
cy.get('.unread-title').should('not.exist');
//* Favicons should be default(blue)
verifyFaviconEquals('favicon-default-16x16.png');
// # Have the other user post an at-mention for you in any channel on team B
cy.apiGetChannelByName(team2.name, 'off-topic').then(({channel}) => {
cy.postMessageAs({sender: user2, message: `@${user1.username}`, channelId: channel.id});
});
cy.wait(TIMEOUTS.HALF_SEC);
// * Browser tab should displays (1) * channel - [team name] Mattermost
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
// * Team sidebar: Small dot left of team B icon in team sidebar
cy.get(`#${team2.name}TeamButton`).parent('.unread').should('be.visible').within(() => {
// * Team sidebar: a mention badge in top right corner of the badge with number "1"
cy.get('.badge').contains('1');
});
// * Favicon should turn red when there are mentions indicated
verifyFaviconEquals('favicon-mentions-16x16.png');
});
it('MM-T560_2 Team sidebar icon - Badge with mention count increments when added to channel', () => {
// # User 1 view and remain on team A
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
// * Browser tab should displays (1) * channel - [team name] Mattermost (for verify count increase)
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
// # Have another user view team B
cy.apiLogin(user2);
cy.visit(testTeam2TownSquareUrl);
// # Create a new channel
cy.uiCreateChannel({name: 'new-channel'});
cy.wait(TIMEOUTS.HALF_SEC);
// # Invites User 1
cy.get('#member_popover').should('be.visible').click();
cy.contains('Manage Members').click();
cy.contains('Add Members').click();
cy.get('.channel-invite__content').
should('be.visible').
find('input').
type(`${user1.username}{enter}`, {force: true});
cy.get('#saveItems').click();
cy.wait(TIMEOUTS.HALF_SEC);
// * User 1 should be added.
cy.getLastPost().
should('contain', `@${user1.username}`).
should('contain', 'added to the channel');
// # Switch to User 1 and visit the town-square
cy.apiLogout();
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
// * Title should be increased
// * Browser tab should displays (1) * channel - [team name] Mattermost
cy.title().should('include', `(2) Town Square - ${team1.display_name} ${siteName}`);
// * Team sidebar: Small dot left of team B icon in team sidebar
cy.get(`#${team2.name}TeamButton`).should('be.visible').within(() => {
// * Team sidebar: a mention badge in top right corner of the badge with number "1"
cy.get('.badge').contains('2');
});
});
});
function verifyFaviconEquals(expectedFixture) {
cy.get('link[rel=icon]').should('have.attr', 'href').then((defaultFaviconUrl) => {
cy.fixture(expectedFixture).then((imageData) => {
cy.request({url: defaultFaviconUrl, encoding: 'base64'}).then((response) => {
expect(response.status).to.equal(200);
expect(response.body).to.eq(imageData);
});
});
});
}

Просмотреть файл

@@ -0,0 +1,135 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
FixedCloudConfig,
getMentionEmailTemplate,
verifyEmailBody,
} from '../../../utils';
describe('Notifications', () => {
let config;
let sender;
let testTeam;
let testChannel;
let testChannelUrl;
let receiver;
before(() => {
cy.shouldHaveEmailEnabled();
// # Get config
cy.apiGetConfig().then((data) => {
({config} = data);
});
cy.apiInitSetup().then(({team, channel, user, channelUrl}) => {
testTeam = team;
testChannel = channel;
testChannelUrl = channelUrl;
sender = user;
cy.apiCreateUser().then(({user: user1}) => {
receiver = user1;
cy.apiAddUserToTeam(testTeam.id, receiver.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, receiver.id);
// # Login as receiver and visit test channel
cy.apiLogin(receiver);
cy.visit(testChannelUrl);
// # Open 'Notifications' of 'Settings' modal
cy.uiOpenSettingsModal().within(() => {
// # Open 'Email Notifications' setting and set to 'Immediately'
cy.findByRole('heading', {name: 'Email Notifications'}).should('be.visible').click();
cy.findByRole('radio', {name: 'Immediately'}).click().should('be.checked');
// # Save then close the modal
cy.uiSaveAndClose();
});
// # As receiver, set status to offline and logout
cy.uiGetSetStatusButton().click();
cy.findByText('Offline').should('be.visible').click();
cy.apiLogout();
// # Login as sender and visit test channel
cy.apiLogin(sender);
cy.visit(testChannelUrl);
});
});
});
});
it('MM-T506 Channel links show as links in notification emails', () => {
const baseUrl = Cypress.config('baseUrl');
const message = {
orig: `This is a message in ~${testChannel.name} channel for @${receiver.username} `,
emailLinked: `This is a message in ~${testChannel.name} ( ${baseUrl}/landing#/${testTeam.name}/channels/${testChannel.name} ) channel for @${receiver.username}`,
posted: `This is a message in ~${testChannel.display_name} channel for @${receiver.username} `,
};
// # Post a message as sender that contains the channel name and receiver's username
cy.postMessage(message.orig);
// # Wait for a while to ensure that email notification is sent.
cy.wait(TIMEOUTS.FIVE_SEC);
cy.getLastPostId().then((postId) => {
// # Login as the receiver and visit test channel
cy.apiLogin(receiver);
cy.visit(testChannelUrl);
cy.get('#confirmModalButton').
should('be.visible').
and('have.text', 'Yes, set my status to "Online"').
click();
cy.getRecentEmail(receiver).then((data) => {
const {body, from, subject} = data;
const siteName = config.TeamSettings.SiteName;
const feedbackEmail = config.EmailSettings.FeedbackEmail || FixedCloudConfig.EmailSettings.FEEDBACK_EMAIL;
// * Verify that email is from default feedback email
expect(from).to.contain(feedbackEmail);
// * Verify that the email subject is correct
expect(subject).to.contain(`[${siteName}] Notification in ${testTeam.display_name}`);
// * Verify that the email body is correct
const expectedEmailBody = getMentionEmailTemplate(
sender.username,
message.emailLinked,
postId,
siteName,
testTeam.name,
testChannel.display_name,
);
verifyEmailBody(expectedEmailBody, body);
const permalink = body[3].split(' ')[4];
const permalinkPostId = permalink.split('/')[6];
// # Visit permalink (e.g. click on email link) then view in browser to proceed
cy.visit(permalink);
cy.findByText('View in Browser').click();
// * Verify that message is correct
const postText = `#postMessageText_${permalinkPostId}`;
cy.get(postText).should('have.text', message.posted);
// * Should match last post and permalink post IDs
expect(permalinkPostId).to.equal(postId);
});
});
});
});

Просмотреть файл

@@ -0,0 +1,70 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testTeam;
let otherUser;
before(() => {
cy.apiInitSetup().then(({team}) => {
testTeam = team;
cy.apiCreateUser().then(({user}) => {
otherUser = user;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
cy.apiLogin(otherUser);
});
cy.visit(`/${testTeam.name}`);
// # Open 'Settings' modal
cy.uiOpenSettingsModal().within(() => {
cy.get('#keysEdit').should('be.visible').click();
// * As otherUser, ensure that 'Your non-case sensitive username' is not checked
cy.get('#notificationTriggerUsername').should('not.be.checked');
// # Close the modal
cy.get('#accountSettingsHeader').find('button').should('be.visible').click();
});
cy.apiLogout();
// # Login as sysadmin
cy.apiAdminLogin();
cy.visit(`/${testTeam.name}`);
});
});
it('MM-T546 Words that trigger mentions - Deselect username, still get mention when added to private channel', () => {
// # Create a new private channel
cy.apiCreateChannel(testTeam.id, 'private-channel', 'Private Channel', 'P').then(({channel}) => {
// # Add otherUser to the newly created private channel and logout from sysadmin account
cy.apiAddUserToChannel(channel.id, otherUser.id);
cy.apiLogout();
// # Login as otherUser and visit team
cy.apiLogin(otherUser);
cy.visit(`/${testTeam.name}`);
// * Verify that the channel appears in LHS
cy.get(`#sidebarItem_${channel.name}`, {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').within(() => {
// * Verify that the channel name is visible and is the channel otherUser was invited to
cy.findByText(channel.display_name).should('be.visible');
// * Ensure that the unread mentions badge is visible and has the text '1'
cy.get('#unreadMentions').should('have.text', 1);
});
});
});
});

Просмотреть файл

@@ -0,0 +1,326 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as MESSAGES from '../../../fixtures/messages';
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {spyNotificationAs} from '../../../support/notification';
import {
changeDesktopNotificationAs,
changeTeammateNameDisplayAs,
} from './helper';
describe('Desktop notifications', () => {
let testTeam;
let testUser;
let otherUser;
before(() => {
// Initialise a user
cy.apiInitSetup().then(({team, user}) => {
otherUser = user;
testTeam = team;
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiCreateUser().then(({user}) => {
testUser = user;
cy.apiAddUserToTeam(testTeam.id, testUser.id);
cy.apiLogin(testUser);
// Visit town-square.
cy.visit(`/${testTeam.name}/channels/town-square`);
});
});
it('MM-T482 Desktop Notifications - (at) here not rec\'d when logged off', () => {
spyNotificationAs('withoutNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification if are mentioned.
changeDesktopNotificationAs('#desktopNotificationMentions');
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Logout the user
cy.uiLogout();
// Have another user send a post.
cy.postMessageAs({sender: otherUser, message: '@here', channelId: channel.id});
});
// # Login with the user and visit town-square
cy.apiLogin(testUser);
cy.visit(`/${testTeam.name}/channels/town-square`);
// * Desktop notification is not received.
cy.get('@withoutNotification').should('not.have.been.called');
// * Should not have unread mentions indicator.
cy.get('#sidebarItem_off-topic').
scrollIntoView().
find('#unreadMentions').
should('not.exist');
// # Verify that off-topic channel is unread and then click.
cy.findByLabelText('off-topic public channel unread').
should('exist').
click();
// # Get last post message text
cy.getLastPostId().then((postId) => {
cy.get(`#postMessageText_${postId}`).as('postMessageText');
});
// * Verify message has @here mention and it is highlighted.
cy.get('@postMessageText').
find('[data-mention="here"]').
should('exist');
// * Verify no email notification received for the mention.
cy.getRecentEmail(testUser).then((data) => {
// # Verify that the email subject is about joining.
expect(data.subject).to.contain('You joined');
});
});
it('MM-T487 Desktop Notifications - For all activity with apostrophe, emoji, and markdown in notification', () => {
spyNotificationAs('withNotification', 'granted');
const actualMsg = '*I\'m* [hungry](http://example.com) :taco: ![Mattermost](https://mattermost.com/wp-content/uploads/2022/02/logoHorizontal.png)';
const expected = '@' + otherUser.username + ': I\'m hungry :taco: Mattermost';
// # Ensure notifications are set up to fire a desktop notification if are mentioned.
changeDesktopNotificationAs('#desktopNotificationAllActivity');
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
});
});
it('MM-T495 Desktop Notifications - Can set to DND and no notification fires on DM', () => {
cy.apiCreateDirectChannel([otherUser.id, testUser.id]).then(({channel}) => {
// # Ensure notifications are set up to fire a desktop notification if you receive a DM
cy.apiPatchUser(testUser.id, {notify_props: {...testUser.notify_props, desktop: 'all'}});
spyNotificationAs('withoutNotification', 'granted');
// # Post the following: /dnd
cy.uiGetPostTextBox().clear().type('/dnd{enter}');
// # Have another user send you a DM
cy.postMessageAs({sender: otherUser, message: MESSAGES.TINY, channelId: channel.id});
// * Desktop notification is not received
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withoutNotification').should('not.have.been.called');
// * Verify that the status indicator next to your name has changed to "Do Not Disturb"
cy.uiGetSetStatusButton().
find('.icon-minus-circle').
should('be.visible');
});
});
it('MM-T497 Desktop Notifications for empty string without mention badge', () => {
// # Visit the MM webapp with the notification API stubbed
spyNotificationAs('withNotification', 'granted');
const actualMsg = '---';
const expected = '@' + otherUser.username + ' did something new';
// # Ensure notifications are set up to fire a desktop notification for all activity.
changeDesktopNotificationAs('#desktopNotificationAllActivity');
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
// * Verify that the channel is now unread without a mention badge
cy.get(`#sidebarItem_${channel.name} .badge`).should('not.exist');
});
});
it('MM-T488 Desktop Notifications - Teammate name display set to username', () => {
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification if are mentioned
changeDesktopNotificationAs('#desktopNotificationMentions');
// # Ensure display settings are set to "Show username"
changeTeammateNameDisplayAs('#name_formatFormatA');
const actualMsg = `@${testUser.username} How are things?`;
const expected = `@${otherUser.username}: @${testUser.username} How are things?`;
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
});
});
it('MM-T490 Desktop Notifications - Teammate name display set to first and last name', () => {
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification if are mentioned
changeDesktopNotificationAs('#desktopNotificationMentions');
// # Ensure display settings are set to "Show first and last name"
changeTeammateNameDisplayAs('#name_formatFormatC');
const actualMsg = `@${testUser.username} How are things?`;
const expected = `@${otherUser.first_name} ${otherUser.last_name}: @${testUser.username} How are things?`;
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
});
});
it('MM-T491 - Channel notifications: No desktop notification when in focus', () => {
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
const message = '/echo test 3';
// # Go to test channel
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
spyNotificationAs('withNotification', 'granted');
// # Have another user send a post with delay
cy.postMessageAs({sender: otherUser, message, channelId: channel.id});
// * Desktop notification is not received
cy.get('@withNotification').should('not.have.been.called');
});
});
it('MM-T494 - Channel notifications: Send Desktop Notifications - Only mentions and DMs', () => {
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification
changeDesktopNotificationAs('#desktopNotificationMentions');
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
const messageWithoutNotification = 'message without notification';
const messageWithNotification = `random message with mention @${testUser.username}`;
const expected = `@${otherUser.username}: ${messageWithNotification}`;
// # Have another user send a post with no mention
cy.postMessageAs({sender: otherUser, message: messageWithoutNotification, channelId: channel.id});
// * Desktop notification is not received
cy.get('@withNotification').should('not.have.been.called');
// Have another user send a post with a mention
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
// * Desktop notification is received
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
// # Have another user post a direct message
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(({channel: dmChannel}) => {
cy.postMessageAs({sender: otherUser, message: 'hi', channelId: dmChannel.id});
// * DM notification is received
cy.get('@withNotification').should('have.been.called');
});
});
});
it('MM-T496 - Channel notifications: Send Desktop Notifications - Never', () => {
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to never fire a desktop notification
changeDesktopNotificationAs('#desktopNotificationNever');
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
const messageWithNotification = `random message with mention @${testUser.username}`;
// Have another user send a post with a mention
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
// * Desktop notification is not received
cy.get('@withNotification').should('not.have.been.called');
// # Have another user post a direct message
cy.apiCreateDirectChannel([testUser.id, otherUser.id]).then(({channel: dmChannel}) => {
cy.postMessageAs({sender: otherUser, message: 'hi', channelId: dmChannel.id});
// * DM notification is not received
cy.get('@withNotification').should('not.have.been.called');
});
});
});
it('MM-T499 - Channel notifications: Desktop Notification Sounds OFF', () => {
spyNotificationAs('withNotification', 'granted');
// # Open settings modal
cy.uiOpenSettingsModal().within(() => {
// # Click "Desktop"
cy.findByText('Desktop Notifications').should('be.visible').click();
// # Select sound off.
cy.get('#soundOff').check();
// # Ensure sound dropdown is not visible
cy.get('#displaySoundNotification').should('not.exist');
// # Click "Save" and close the modal
cy.uiSaveAndClose();
});
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
const messageWithNotification = `random message with mention @${testUser.username}`;
// # Have another user send a post with a mention
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: channel.id});
// * Desktop notification is received without sound
cy.get('@withNotification').should('have.been.calledWithMatch', 'Off-Topic', (args) => {
expect(args.silent).to.equal(true);
return true;
});
});
});
});

Просмотреть файл

@@ -0,0 +1,82 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import {spyNotificationAs} from '../../../support/notification';
import {changeDesktopNotificationAs} from './helper';
describe('Desktop notifications', () => {
let testTeam;
let testChannel;
let testUser;
let otherUser;
before(() => {
cy.apiCreateUser().then(({user}) => {
otherUser = user;
});
// Initialize a user
cy.apiInitSetup().then(({team, channel, user, offTopicUrl}) => {
testUser = user;
testTeam = team;
testChannel = channel;
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
});
// Login then visit off-topic
cy.apiLogin(testUser);
cy.visit(offTopicUrl);
});
});
it('MM-T885 Channel notifications: Desktop notifications mentions only', () => {
// # Ensure notifications are set up to fire a desktop notification
changeDesktopNotificationAs('#desktopNotificationAllActivity');
const messageWithNotification = `random message with mention @${testUser.username}`;
const expected = `@${otherUser.username}: ${messageWithNotification}`;
// # Go to test channel
cy.uiClickSidebarItem(testChannel.name);
// # Set channel notifications to show on mention only
cy.uiOpenChannelMenu('Notification Preferences');
cy.findByText('Send desktop notifications').click();
cy.findByRole('radio', {name: 'Only for mentions'}).click();
cy.uiSaveAndClose();
// # Visit off-topic
cy.uiClickSidebarItem('off-topic');
spyNotificationAs('withNotification', 'granted');
// Have another user send a post with no mention
cy.postMessageAs({sender: otherUser, message: 'random message no mention', channelId: testChannel.id});
// * Desktop notification is not received
cy.get('@withNotification').should('not.have.been.called');
// Have another user send a post with a mention
cy.postMessageAs({sender: otherUser, message: messageWithNotification, channelId: testChannel.id});
// * Desktop notification is received
cy.get('@withNotification').should('have.been.calledWithMatch', testChannel.display_name, (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
// * Notification badge is aligned to the right of LHS
cy.uiGetSidebarItem(testChannel.name).find('.badge').should('exist').and('have.css', 'margin', '0px 4px');
});
});

Просмотреть файл

@@ -0,0 +1,109 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {spyNotificationAs} from '../../../support/notification';
import {getAdminAccount} from '../../../support/env';
import {
changeDesktopNotificationAs,
changeTeammateNameDisplayAs,
} from './helper';
describe('Desktop notifications', () => {
let testTeam;
let testUser;
let otherUser;
before(() => {
cy.apiInitSetup().then(({team, user}) => {
otherUser = user;
testTeam = team;
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiCreateUser().then(({user}) => {
testUser = user;
cy.apiAddUserToTeam(testTeam.id, testUser.id);
cy.apiLogin(testUser);
// Visit town-square.
cy.visit(`/${testTeam.name}/channels/town-square`);
});
});
it('MM-T489_1 Display teammate nickname when nickname exists', () => {
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification if are mentioned
changeDesktopNotificationAs('#desktopNotificationMentions');
// # Ensure display settings are set to "Show nickname if one exists, otherwise show first and last name"
changeTeammateNameDisplayAs('#name_formatFormatB');
const actualMsg = `@${testUser.username} first`;
const expected = `@${otherUser.nickname}: ${actualMsg}`;
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', channel.display_name, (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
});
});
it('MM-T489_2 Display teammates first and last name when nickname does not exists', () => {
cy.apiGetChannelByName(testTeam.name, 'Off-Topic').then(({channel}) => {
// # Ensure other user is without nickname set up
patchUser(otherUser.id, {nickname: ''});
spyNotificationAs('withNotification', 'granted');
// # Ensure notifications are set up to fire a desktop notification if are mentioned
changeDesktopNotificationAs('#desktopNotificationMentions');
// # Ensure display settings are set to "Show nickname if one exists, otherwise show first and last name"
changeTeammateNameDisplayAs('#name_formatFormatB');
const actualMsg = `@${testUser.username} second`;
const expected = `@${otherUser.first_name} ${otherUser.last_name}: ${actualMsg}`;
// # Have another user send a post.
cy.postMessageAs({sender: otherUser, message: actualMsg, channelId: channel.id});
// * Desktop notification should be received with expected body.
cy.wait(TIMEOUTS.HALF_SEC);
cy.get('@withNotification').should('have.been.calledWithMatch', channel.display_name, (args) => {
expect(args.body, `Notification body: "${args.body}" should match: "${expected}"`).to.equal(expected);
return true;
});
});
});
});
function patchUser(userId, data) {
const sysadmin = getAdminAccount();
return cy.externalRequest({
user: sysadmin,
method: 'PUT',
path: `users/${userId}/patch`,
data,
}).its('status').should('eq', 200);
}

Просмотреть файл

@@ -0,0 +1,71 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
describe('Notifications', () => {
let user1;
let user2;
let team1;
let team2;
let testTeam1TownSquareUrl;
let siteName;
before(() => {
cy.apiInitSetup().then(({team, user}) => {
team1 = team;
user1 = user;
testTeam1TownSquareUrl = `/${team.name}/channels/town-square`;
cy.apiCreateUser().then(({user: otherUser}) => {
user2 = otherUser;
cy.apiAddUserToTeam(team.id, user2.id);
});
cy.apiCreateTeam('team-b', 'Team B').then(({team: anotherTeam}) => {
team2 = anotherTeam;
cy.apiAddUserToTeam(team2.id, user1.id);
cy.apiAddUserToTeam(team2.id, user2.id);
});
cy.apiGetConfig().then(({config}) => {
siteName = config.TeamSettings.SiteName;
});
// # Remove mention notification (for initial channel).
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
cy.findByText('CHANNELS').get('.unread-title').click();
cy.findByText('CHANNELS').get('.unread-title').should('not.exist');
cy.apiLogout();
});
});
it('MM-T561 Browser tab and team sidebar - direct messages don\'t add indicator on team icon in team sidebar (but do in browser tab)', () => {
// # User A: Join teams A and B. Open team A
cy.apiLogin(user1);
cy.visit(testTeam1TownSquareUrl);
// # User B: Join team B
// # User B: Post a direct message to user A
cy.apiCreateDirectChannel([user1.id, user2.id]).then(({channel: ownDMChannel}) => {
cy.postMessageAs({sender: user2, message: `@${user1.username}`, channelId: ownDMChannel.id});
});
// * Browser tab shows: (1) * Town Square - [team name] Mattermost
cy.title().should('include', `(1) Town Square - ${team1.display_name} ${siteName}`);
// * Team sidebar shows: No unread / mention indicator in team sidebar on either team
cy.get(`#${team2.name}TeamButton`).parent('.unread').should('not.exist');
cy.get(`#${team2.name}TeamButton`).parent().within(() => {
cy.get('.badge').should('not.exist');
});
});
});

Просмотреть файл

@@ -0,0 +1,30 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export function changeDesktopNotificationAs(category) {
// # Open settings modal
cy.uiOpenSettingsModal().within(() => {
// # Click "Desktop Notifications"
cy.findByText('Desktop Notifications').should('be.visible').click();
// # Select category.
cy.get(category).check();
// # Click "Save" and close the modal
cy.uiSaveAndClose();
});
}
export function changeTeammateNameDisplayAs(category) {
// # Open settings modal
cy.uiOpenSettingsModal('Display').within(() => {
// # Click "Desktop"
cy.findByText('Teammate Name Display').click();
// # Select category.
cy.get(category).check();
// # Click "Save" and close the modal
cy.uiSaveAndClose();
});
}

Просмотреть файл

@@ -0,0 +1,134 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testTeam;
let userB;
let channelA;
let channelB;
before(() => {
// # Login as new user and visit town-square
cy.apiInitSetup().then(({team, user}) => {
testTeam = team;
// # Add 1 user
cy.apiCreateUser().then(({user: newUser}) => {
userB = newUser;
cy.apiAddUserToTeam(testTeam.id, userB.id);
});
// # Create two channels
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
channelA = channel;
});
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
channelB = channel;
});
cy.apiLogin(user);
});
});
it('MM-T567 - Channel Notifications - Turn on Ignore mentions for @channel, @here and @all', () => {
cy.visit(`/${testTeam.name}/channels/${channelA.name}`);
// # Add users to channel
addNumberOfUsersToChannel(1);
cy.getLastPostId().then((id) => {
// * The system message should contain 'added to the channel by you'
cy.get(`#postMessageText_${id}`).should('contain', 'added to the channel by you');
});
// # Set ignore mentions
setIgnoreMentions(true);
// # Go to a different channel
cy.visit(`/${testTeam.name}/channels/${channelB.name}`);
// # Post messages as another user on the first channel
cy.postMessageAs({sender: userB, message: '@all test', channelId: channelA.id});
cy.postMessageAs({sender: userB, message: '@channel test', channelId: channelA.id});
cy.postMessageAs({sender: userB, message: '@here test', channelId: channelA.id});
// * Assert the channel is unread with no mentions
cy.get(`#sidebarItem_${channelA.name}`).wait(TIMEOUTS.ONE_SEC).should('have.class', 'unread-title');
cy.get(`#sidebarItem_${channelA.name} > #unreadMentions`).should('not.exist');
});
it('MM-T568 - Channel Notifications - Turn off Ignore mentions for @channel, @here and @all', () => {
cy.visit(`/${testTeam.name}/channels/${channelA.name}`);
// # Unset ignore mentions
setIgnoreMentions(false);
// # Go to a different channel
cy.visit(`/${testTeam.name}/channels/${channelB.name}`);
// # Post messages as another user on the first channel
cy.postMessageAs({sender: userB, message: '@all test', channelId: channelA.id});
cy.postMessageAs({sender: userB, message: '@channel test', channelId: channelA.id});
cy.postMessageAs({sender: userB, message: '@here test', channelId: channelA.id});
// * Assert the channel is unread with 3 mentions
cy.get(`#sidebarItem_${channelA.name}`).should('have.class', 'unread-title');
cy.get(`#sidebarItem_${channelA.name} > #unreadMentions`).should('exist').wait(TIMEOUTS.ONE_SEC).should('contain', '3');
});
});
function addNumberOfUsersToChannel(num = 1) {
// # Open channel menu and click 'Add Members'
cy.uiOpenChannelMenu('Add Members');
cy.get('#addUsersToChannelModal').should('be.visible');
// * Assert that modal appears
// # Click the first row for a number of times
Cypress._.times(num, () => {
cy.get('#selectItems input').typeWithForce('u');
cy.get('#multiSelectList').should('be.visible').children().first().click();
});
// # Click the button "Add" to add user to a channel
cy.get('#saveItems').click();
// # Wait for the modal to disappear
cy.get('#addUsersToChannelModal').should('not.exist');
}
function setIgnoreMentions(toSet) {
let stringToSet = 'Off';
if (toSet) {
stringToSet = 'On';
}
// # Open channel menu and click Notification Preferences
cy.uiOpenChannelMenu('Notification Preferences');
// # Click on the edit button for ignore channel mentions
cy.get('#ignoreChannelMentionsEdit').should('exist').click();
// # Click on selected option
cy.get(`#ignoreChannelMentions${stringToSet}`).should('exist').click();
// # Click on save to save the configuration
cy.get('#saveSetting').should('exist').click();
// * Assert that the option selected is reflected
cy.get('#ignoreChannelMentionsDesc').should('contain', stringToSet);
// # Click on the X button to close the modal
cy.get('#channelNotificationModalLabel').siblings('.close').click();
}

Просмотреть файл

@@ -0,0 +1,98 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notification
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
FixedCloudConfig,
getMentionEmailTemplate,
verifyEmailBody,
} from '../../../utils';
describe('Email notification', () => {
let config;
let sender;
let receiver;
let testTeam;
before(() => {
// # Do email test if setup properly
cy.shouldHaveEmailEnabled();
// # Get config
cy.apiGetConfig().then((data) => {
({config} = data);
});
cy.apiCreateUser().then(({user}) => {
receiver = user;
});
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
sender = user;
testTeam = team;
cy.apiAddUserToTeam(team.id, receiver.id);
// # Login and go to off-topic
cy.apiLogin(sender);
cy.visit(offTopicUrl);
});
});
it('MM-T4062 Post a message that mentions a user', () => {
// # Post a message mentioning other user
const message = `Hello @${receiver.username} `;
cy.postMessage(message);
// # Wait for a while to ensure that email notification is sent.
cy.wait(TIMEOUTS.FIVE_SEC);
cy.getLastPostId().then((postId) => {
cy.getRecentEmail(receiver).then((data) => {
const {body, from, subject} = data;
const siteName = config.TeamSettings.SiteName;
const feedbackEmail = config.EmailSettings.FeedbackEmail || FixedCloudConfig.EmailSettings.FEEDBACK_EMAIL;
// * Verify that email is from default feedback email
expect(from).to.contain(feedbackEmail);
// * Verify that the email subject is correct
expect(subject).to.contain(`[${siteName}] Notification in ${testTeam.display_name}`);
// * Verify that the email body is correct
const expectedEmailBody = getMentionEmailTemplate(
sender.username,
message.trim(),
postId,
siteName,
testTeam.name,
'Off-Topic',
);
verifyEmailBody(expectedEmailBody, body);
const permalink = body[3].split(' ')[4];
const permalinkPostId = permalink.split('/')[6];
// # Visit permalink (e.g. click on email link) then view in browser to proceed
cy.visit(permalink);
cy.findByText('View in Browser').click();
const postText = `#postMessageText_${permalinkPostId}`;
cy.get(postText).should('have.text', message);
// * Should match last post and permalink post IDs
expect(permalinkPostId).to.equal(postId);
});
});
});
});

Просмотреть файл

@@ -0,0 +1,97 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as MESSAGES from '../../../fixtures/messages';
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testTeam;
let testChannel;
let otherUser;
beforeEach(() => {
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
otherUser = user;
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
});
});
it('MM-T565 New message bar - Doesnt display for emoji reaction', () => {
// # Make a starting post from the user 1
cy.postMessage(MESSAGES.SMALL);
// # Make a few posts from user 2 so that center can be scrolled
Cypress._.times(30, (postNumber) => {
cy.postMessageAs({sender: otherUser, message: `P${postNumber}`, channelId: testChannel.id});
});
// # Make a final post from the user 1 where reaction will be added
cy.postMessage('This post will have a reaction');
// # Scroll to top of the channel to first post
cy.getNthPostId(1).then((firstPostId) => {
cy.get(`#post_${firstPostId}`).should('exist').scrollIntoView();
});
// # Get the last posted message
cy.getLastPostId().then((lastPostID) => {
// # Add a reaction to the last post with another user
cy.reactToMessageAs({sender: otherUser, postId: lastPostID, reaction: 'smile'});
});
// * Verify that new message bar is not visible even after a new reaction
// was added to the message in the bottom
cy.get('.toast.toast__visible').should('not.exist');
});
it('MM-T566 New message bar - Displays in permalink view', () => {
cy.makeClient().then(async (client) => {
const townChannel = await client.getChannelByName(testTeam.id, 'town-square');
const townChannelId = townChannel.id;
// # Post messages in town-square channel
Cypress._.times(15, (postNumber) => {
cy.postMessageAs({sender: otherUser, message: `P${postNumber}`, channelId: townChannelId});
});
// # Enter "in:town-square" in the search bar and hit ENTER
cy.get('#searchBox').
typeWithForce('in:town-square').
typeWithForce('{enter}').
typeWithForce('{enter}');
// # Click "Jump" to one of the search results
cy.get('a.search-item__jump').last().click();
// * Verify permalink in main channel view (post highlighted, fades in 6sec.)
cy.getNthPostId(1).then((postIdTest) => {
cy.get(`#post_${postIdTest}`, {timeout: TIMEOUTS.HALF_MIN}).should('have.class', 'post--highlight');
cy.clock();
cy.tick(6000);
cy.get(`#post_${postIdTest}`).should('not.have.class', 'post--highlight');
});
// # Other user post a message in town-square channel
cy.postMessageAs({
sender: otherUser,
message: 'message from user B',
channelId: townChannelId,
});
// * Verify New message bar appears
cy.get('.NotificationSeparator').should('exist');
});
});
});

Просмотреть файл

@@ -0,0 +1,57 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import {getRandomId} from '../../../utils';
describe('Notifications', () => {
let otherUser;
let offTopicChannelId;
const numberOfPosts = 30;
before(() => {
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
otherUser = user;
cy.apiGetChannelByName(team.name, 'off-topic').then(({channel}) => {
offTopicChannelId = channel.id;
});
cy.visit(offTopicUrl);
});
});
it('MM-T562 New message bar - Message posted while scrolled up in same channel', () => {
// # Post 30 random messages from the 'otherUser' account in off-topic
Cypress._.times(numberOfPosts, (num) => {
cy.postMessageAs({sender: otherUser, message: `${num} ${getRandomId()}`, channelId: offTopicChannelId});
});
// # Scroll to the top of the channel so that the 'Jump to New Messages' button would be visible
cy.get('.post-list__dynamic').scrollTo('top');
// # Post two new messages as 'otherUser'
cy.postMessageAs({sender: otherUser, message: 'Random Message', channelId: offTopicChannelId});
cy.postMessageAs({sender: otherUser, message: 'Last Message', channelId: offTopicChannelId});
// * Verify that the last message is currently not visible
cy.findByText('Last Message').should('not.be.visible');
// # Click on the 'Jump to New Messages' button
cy.get('.toast__visible').should('be.visible').click();
// * Verify that the last message is now visible
cy.findByText('Last Message').should('be.visible');
// * Verify that 'Jump to New Messages' is not visible
cy.get('.toast__visible').should('not.exist');
});
});

Просмотреть файл

@@ -0,0 +1,68 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testTeam;
let otherUser;
before(() => {
cy.apiInitSetup().then(({team}) => {
testTeam = team;
cy.apiCreateUser().then(({user}) => {
otherUser = user;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
cy.apiLogin(otherUser);
});
cy.visit(`/${testTeam.name}/channels/town-square`);
});
});
it('MM-T555 Notification Preferences do not save when modal is closed without saving', () => {
// # Call function that clicks on Settings -> Notifications -> Email Notifications -> Send Email Notifications -> Never without saving
openSettingsAndClickEmailEdit(true);
// # Call function that checks Settings -> Notifications -> Email Notifications -> Send Email Notifications -> Never is not saved
openSettingsAndClickEmailEdit(false);
});
function openSettingsAndClickEmailEdit(shouldBeClicked = false) {
// # Open 'Settings' modal
cy.uiOpenSettingsModal().within(() => {
// # Click on the 'Edit' button next to Email Notifications
cy.get('#emailEdit').click();
if (shouldBeClicked) {
// * Ensure that 'Send email notifications' is set to 'Immediately'
cy.get('#emailNotificationImmediately').should('be.visible').and('be.checked');
// # Check that 'Never' is not currently checked, and click it
cy.get('#emailNotificationNever').should('be.visible').and('not.be.checked').click();
// # Wait for half a second just to be sure the setting was correctly checked
cy.wait(TIMEOUTS.HALF_SEC);
// # Close the modal
cy.get('#accountSettingsHeader').find('button').should('be.visible').click();
} else {
// * Ensure that 'Send email notifications' is set to 'Immediately'
cy.get('#emailNotificationImmediately').should('be.visible').and('be.checked');
// * Ensure that 'Send email notifications' is not set to 'Never'
cy.get('#emailNotificationNever').should('be.visible').and('not.be.checked');
}
});
}
});

Просмотреть файл

@@ -0,0 +1,54 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import {getRandomId} from '../../../utils';
describe('Notifications', () => {
let otherUser;
let offTopicChannelId;
const numberOfPosts = 30;
before(() => {
cy.apiInitSetup().then(({team, user, offTopicUrl}) => {
otherUser = user;
cy.apiGetChannelByName(team.name, 'off-topic').then(({channel}) => {
offTopicChannelId = channel.id;
});
cy.visit(offTopicUrl);
});
});
it('MM-T564 New message bar - Own user posts a reply while scrolled up in a channel', () => {
// # Post 30 random messages from the 'otherUser' account in off-topic
Cypress._.times(numberOfPosts, (num) => {
cy.postMessageAs({sender: otherUser, message: `${num} ${getRandomId()}`, channelId: offTopicChannelId});
});
// # Click on the post comment icon of the last message
cy.clickPostCommentIcon();
// # Scroll to the top of the channel so that the 'Jump to New Messages' button would be visible (if it existed)
cy.get('.post-list__dynamic').scrollTo('top');
// # Post a reply in RHS
const message = 'This is a test message';
cy.postMessageReplyInRHS(message);
// * 'Jump to New Messages' is not visible
cy.get('.toast__visible').should('not.exist');
// * Message gets posted in off-topic
cy.uiWaitUntilMessagePostedIncludes(message);
});
});

Просмотреть файл

@@ -0,0 +1,250 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import {spyNotificationAs} from '../../../support/notification';
describe('reply-notifications', () => {
let testTeam;
let testChannelUrl;
let testChannelId;
let testChannelName;
let receiver;
let sender;
before(() => {
cy.apiCreateUser().then(({user}) => {
sender = user;
});
cy.apiInitSetup().then(({team, channel, user, channelUrl}) => {
testTeam = team;
receiver = user;
testChannelUrl = channelUrl;
testChannelId = channel.id;
testChannelName = channel.name;
cy.apiAddUserToTeam(testTeam.id, sender.id).then(() => {
cy.apiAddUserToChannel(testChannelId, sender.id);
});
// # Login as receiver
cy.apiLogin(receiver);
});
});
it('MM-T551 Do not trigger notifications on messages in reply threads unless I\'m mentioned', () => {
cy.visit(testChannelUrl);
// Setup notification spy
spyNotificationAs('notifySpy', 'granted');
// # Set users notification settings
setReplyNotificationsSetting('#notificationCommentsNever');
// # Post a message
cy.postMessage('Hi there, this is a root message');
// # Get post id of message
cy.getLastPostId().then((postId) => {
// # Switch to town-square so that unread notifications in test channel may be triggered
cy.uiClickSidebarItem('town-square');
cy.uiGetSidebarItem(testChannelName).click({force: true});
// # Post a message in original thread as another user
cy.postMessage('This is a reply to the root post');
// * Verify stub was not called
cy.get('@notifySpy').should('be.not.called');
// * Verify unread mentions badge does not exist
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('not.exist');
// # Switch again to other channel
cy.uiClickSidebarItem('town-square');
// # Reply to a post as another user mentioning the receiver
cy.postMessageAs({sender, message: `Another reply with mention @${receiver.username}`, channelId: testChannelId, rootId: postId});
// * Verify stub was called
cy.get('@notifySpy').should('be.called');
// * Verify unread mentions badge exists
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
});
});
it('MM-T552 Trigger notifications on messages in threads that I start', () => {
cy.visit(testChannelUrl);
// Setup notification spy
spyNotificationAs('notifySpy', 'granted');
// # Set users notification settings
setReplyNotificationsSetting('#notificationCommentsRoot');
// # Post a message
cy.postMessage('Hi there, this is another root message');
// # Get post id of message
cy.getLastPostId().then((postId) => {
// # Switch to town-square so that unread notifications in test channel may be triggered
cy.uiClickSidebarItem('town-square');
// # Post a message in original thread as another user
const message = 'This is a reply to the root post';
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: postId}).then(() => {
// * Verify stub was called
cy.get('@notifySpy').should('be.called');
// * Verify unread mentions badge exists
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
// # Navigate to test channel
cy.uiClickSidebarItem(testChannelName);
// * Verify entire message
cy.getLastPostId().then((msgId) => {
cy.get(`#postMessageText_${msgId}`).as('postMessageText');
// * Verify reply bar highlight
cy.get(`#post_${msgId}`).should('have.class', 'mention-comment');
});
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
});
});
});
it('MM-T553 Trigger notifications on messages in reply threads that I start or participate in - start thread', () => {
cy.visit(testChannelUrl);
// Setup notification spy
spyNotificationAs('notifySpy', 'granted');
// # Set users notification settings
setReplyNotificationsSetting('#notificationCommentsAny');
// # Post a message
cy.postMessage('Hi there, this is another root message');
// # Get post id of message
cy.getLastPostId().then((postId) => {
// # Switch to town-square so that unread notifications in test channel may be triggered
cy.uiClickSidebarItem('town-square');
// # Post a message in original thread as another user
const message = 'This is a reply to the root post';
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: postId}).then(() => {
// * Verify stub was called
cy.get('@notifySpy').should('be.called');
// * Verify unread mentions badge exists
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
// # Navigate to test channel
cy.uiClickSidebarItem(testChannelName);
// * Verify entire message
cy.getLastPostId().then((msgId) => {
cy.get(`#postMessageText_${msgId}`).as('postMessageText');
// * Verify reply bar highlight
cy.get(`#post_${msgId}`).should('have.class', 'mention-comment');
});
cy.get('@postMessageText').
should('be.visible').
and('have.text', message);
});
});
});
it('MM-T554 Trigger notifications on messages in reply threads that I start or participate in - participate in', () => {
cy.visit(testChannelUrl);
// Setup notification spy
spyNotificationAs('notifySpy', 'granted');
// # Set users notification settings
setReplyNotificationsSetting('#notificationCommentsAny');
// # Make a root post as some other user
const rootPostMessage = 'a root message by some other user';
cy.postMessageAs({sender, message: rootPostMessage, channelId: testChannelId}).then((post) => {
const rootPostId = post.id;
const rootPostMessageId = `#rhsPostMessageText_${rootPostId}`;
// # Click comment icon to open RHS
cy.clickPostCommentIcon(rootPostId);
// * Check that the RHS is open
cy.get('#rhsContainer').should('be.visible');
// * Verify that the original message is in the RHS
cy.get('#rhsContainer').find(rootPostMessageId).should('have.text', `${rootPostMessage}`);
// # Post a reply as receiver, i.e. participate in the thread
cy.postMessageReplyInRHS('this is a reply from the receiver');
// # Wait till receiver's post is visible
cy.getLastPostId().then(() => {
// # Switch to town-square so that unread notifications in test channel may be triggered
cy.uiClickSidebarItem('town-square');
// # Post a message in thread as another user
const message = 'This is a reply by sender';
cy.postMessageAs({sender, message, channelId: testChannelId, rootId: rootPostId}).then(() => {
// * Verify stub was called
cy.get('@notifySpy').should('be.called');
// * Verify unread mentions badge exists
cy.uiGetSidebarItem(testChannelName).find('#unreadMentions').should('be.visible');
// # Navigate to test channel
cy.uiClickSidebarItem(testChannelName);
cy.getLastPostId().then((msgId) => {
// * Verify entire message
cy.get(`#postMessageText_${msgId}`).
should('be.visible').
and('have.text', message);
// * Verify reply bar highlight
cy.get(`#rhsPost_${msgId}`).should('have.class', 'mention-comment');
});
});
});
});
});
});
function setReplyNotificationsSetting(idToToggle) {
// Navigate to settings modal
cy.uiOpenSettingsModal();
// Notifications header should be visible
cy.get('#notificationSettingsTitle').
scrollIntoView().
should('be.visible').
and('contain', 'Notifications');
// Open up 'Reply Notifications' sub-section
cy.get('#commentsTitle').
scrollIntoView().
click();
cy.get(idToToggle).check().should('be.checked');
// Click “Save” and close modal
cy.uiSaveAndClose();
}

Просмотреть файл

@@ -0,0 +1,80 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Notifications', () => {
let testUser;
let otherUser;
let testTeam;
beforeEach(() => {
cy.apiInitSetup().then(({team, user}) => {
testUser = user;
testTeam = team;
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
});
cy.apiLogin(testUser).then(() => {
// # Create new test channel
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Channel').then(({channel}) => {
cy.apiAddUserToChannel(channel.id, otherUser.id);
// # Create more channels for scrolling in LHS
Cypress._.times(40, (i) => {
cy.apiCreateChannel(testTeam.id, `channel-test-${i}`, `channel-${i}`).then((out) => {
cy.apiAddUserToChannel(out.channel.id, otherUser.id);
});
});
// # Most page of messages so the channel can be scrolled up
Cypress._.times(40, (i) => {
cy.postMessageAs({sender: testUser, message: `test${i}`, channelId: channel.id});
});
// # Go to test channel
cy.visit(`/${team.name}/channels/${channel.name}`);
// # Scroll above the last few messages
cy.get('div.post-list__dynamic', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').
scrollTo(0, '70%', {duration: TIMEOUTS.ONE_SEC}).
wait(TIMEOUTS.ONE_SEC);
// # scroll to the last channel
cy.get('#sidebar-left li').last().scrollIntoView();
});
});
});
});
it('MM-T563 New message bar - Reply posted while scrolled up in same channel', () => {
// # Login as other user
cy.apiLogin(otherUser);
// # Get last post and reply a message
cy.getLastPostId().then((postId) => {
cy.clickPostCommentIcon(postId);
const replyMessage = 'A reply to an older post';
cy.postMessageReplyInRHS(replyMessage);
});
// # Login as test user
cy.apiLogin(testUser);
// * Verify the toast is visible with correct message
cy.get('div.toast').should('be.visible').contains('1 new message');
});
});

Просмотреть файл

@@ -0,0 +1,113 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// *********************************************************** ****
// Stage: @prod
// Group: @channels @notifications
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {getRandomId} from '../../../utils';
describe('Notifications', () => {
let testTeam;
let firstUser;
let secondUser;
before(() => {
cy.apiInitSetup().then(({team}) => {
testTeam = team;
// # Create two users with same first name in username
const firstUsername = `test${getRandomId()}`;
cy.apiCreateUser({user: generateTestUser(firstUsername)}).then(({user: user1}) => {
firstUser = user1;
cy.apiAddUserToTeam(testTeam.id, firstUser.id);
});
const secondUsername = `${firstUsername}.one`;
cy.apiCreateUser({user: generateTestUser(secondUsername)}).then(({user: user2}) => {
secondUser = user2;
cy.apiAddUserToTeam(testTeam.id, secondUser.id);
});
});
});
it('MM-T486 Users with the same firstname in their username should not get a mention when one of them leaves a channel', () => {
// # Login as first user
cy.apiLogin(firstUser);
cy.apiCreateChannel(testTeam.id, 'test_channel', 'Test Channel').then(({channel}) => {
// # Visit the newly created channel as the first user and invite the second user
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
cy.apiAddUserToChannel(channel.id, secondUser.id);
// # Go to the 'Off Topic' channel and logout
cy.get('#sidebarItem_off-topic', {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').click();
cy.apiLogout();
// # Login as the second user and go to the team site
cy.apiLogin(secondUser);
cy.visit(`/${testTeam.name}`);
// * Verify that the channel that the first created is visible and that there is one unread mention (for being invited)
cy.get(`#sidebarItem_${channel.name}`, {timeout: TIMEOUTS.HALF_MIN}).should('be.visible').within(() => {
cy.findByText(channel.display_name).should('be.visible');
cy.get('#unreadMentions').should('have.text', '1');
});
// # Go to the test channel
cy.get(`#sidebarItem_${channel.name}`).click();
// # Verify that the mention does not exist anymore
checkUnreadMentions(channel);
// # Leave the test channel and logout
cy.uiOpenChannelMenu('Leave Channel');
cy.apiLogout();
// # Login as first user and visit town square
cy.apiLogin(firstUser);
cy.visit(`/${testTeam.name}/channels/town-square`);
// * Check that the display name of the team the user was invited to is being correctly displayed
cy.uiOpenUserMenu().findByText(`@${firstUser.username}`);
// # Close the user menu
cy.uiGetSetStatusButton().click();
// * Check that 'Town Square' is currently being selected
cy.get('.active').within(() => {
cy.get('#sidebarItem_town-square').should('exist');
});
// * Verify that the first user did not get a mention from the test channel when the second user left
checkUnreadMentions(channel);
});
});
// Function to check that the unread mentions badge does not exist (the user was not mentioned in the test channel)
function checkUnreadMentions(testChannel) {
cy.get(`#sidebarItem_${testChannel.name}`).within(() => {
cy.get('#unreadMentions').should('not.exist');
});
}
// Function to generate a test user with a random username
function generateTestUser(username) {
const randomId = getRandomId();
return {
email: `${username}${randomId}@sample.mattermost.com`,
username,
password: 'passwd',
first_name: `First${randomId}`,
last_name: `Last${randomId}`,
nickname: `Nickname${randomId}`,
};
}
});