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

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

@@ -0,0 +1,147 @@
// 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 @enterprise @not_cloud @system_console @license_removal
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {getAdminAccount} from '../../../../../support/env';
import {promoteToChannelOrTeamAdmin} from '../channel_moderation/helpers.js';
describe('System console', () => {
const sysadmin = getAdminAccount();
let teamAdmin;
let regularUser;
let teamName;
let privateChannelName;
before(() => {
cy.shouldNotRunOnCloudEdition();
// * Check if server has license
cy.apiRequireLicense();
// # Set channel permissions as listed in the test
setChannelPermission();
// # Create regular user and team admin
cy.apiInitSetup({userPrefix: 'regular-user'}).then(({team, user}) => {
teamName = team.name;
regularUser = user;
cy.apiCreateUser({prefix: 'team-admin'}).then(({user: newUser}) => {
cy.apiAddUserToTeam(team.id, newUser.id).then(() => {
teamAdmin = newUser;
promoteToChannelOrTeamAdmin(teamAdmin.id, team.id, 'teams');
cy.apiCreateChannel(team.id, 'private', 'Private', 'P').then(({channel}) => {
privateChannelName = channel.name;
Cypress._.forEach([teamAdmin.id, regularUser.id], (userId) => cy.apiAddUserToChannel(channel.id, userId));
});
});
});
});
});
it('MM-41397 - License page shows upgrade to Enterprise for E20 licenses', () => {
cy.visit('/admin_console/about/license');
cy.get('.admin-console__header').
should('be.visible').
and('have.text', 'Edition and License');
// Validate prompt to increase headcount in Enterprise licenses
cy.get('.EnterpriseEditionRightPannel').
should('be.visible').
within(() => {
cy.findByText('Need to increase your headcount?');
cy.findByText('Were here to work with you and your needs. Contact us today to get more seats on your plan.');
cy.findByRole('button', {name: 'Contact sales'});
});
// Validate Compare plans link is not present for Enterprise licenses
cy.findByRole('link', {name: 'Compare Plans'}).should('not.exist');
});
it('MM-T1201 - Remove and re-add license - Permissions freeze in place when license is removed (and then re-added)', () => {
// * Verify user access per permissions changed while on E20
verifyUserChannelPermission(teamName, privateChannelName, sysadmin, teamAdmin, regularUser);
// # Remove license and verify user access when downgraded to E0/team edition
cy.apiAdminLogin();
cy.apiDeleteLicense();
verifyUserChannelPermission(teamName, privateChannelName, sysadmin, teamAdmin, regularUser);
// # Re-add license and verify user access when upgraded to E20
cy.apiAdminLogin();
cy.apiRequireLicense();
verifyUserChannelPermission(teamName, privateChannelName, sysadmin, teamAdmin, regularUser);
});
});
// # Set channel permissions as listed in the test
function setChannelPermission() {
cy.visit('admin_console/user_management/permissions/system_scheme');
cy.findByTestId('resetPermissionsToDefault').click();
cy.get('#confirmModalButton').click();
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').click();
cy.findByTestId('all_users-private_channel-manage_private_channel_properties-checkbox').click();
cy.findByTestId('team_admin-private_channel-manage_private_channel_properties-checkbox').click();
cy.findByTestId('saveSetting').click();
}
function verifyCreatePublicChannel(teamName, testUsers) {
for (const testUser of testUsers) {
const {user, canCreate, isSysadmin} = testUser;
// # Login as a user, and visit the team and channel
cy.apiLogin(user);
cy.visit(`/${teamName}/channels/town-square`);
// # Click on create new channel at LHS
cy.uiBrowseOrCreateChannel('Create New Channel').click();
cy.findByRole('dialog', {name: 'Create a new channel'}).within(() => {
// * Verify if creating a public channel is disabled or not
cy.get('#public-private-selector-button-O').should(isSysadmin || canCreate ? 'not.have.class' : 'have.class', 'disabled');
// * Verify if creating a private channel is not disabled
cy.get('#public-private-selector-button-P').should('not.have.class', 'disabled');
});
}
}
function verifyRenamePrivateChannel(teamName, privateChannelName, testUsers) {
for (const testUser of testUsers) {
const {user, canRename} = testUser;
cy.apiLogin(user);
cy.visit(`/${teamName}/channels/${privateChannelName}`);
// * Click the dropdown menu and verify if the rename option is visible or not
cy.get('#channelHeaderDropdownIcon', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').click();
cy.get('#channelRename').should(canRename ? 'be.visible' : 'not.exist');
}
}
function verifyUserChannelPermission(teamName, privateChannelName, sysadmin, teamAdmin, regularUser) {
// * Verify that system admin sees option to create public channels and team admins / members do not
verifyCreatePublicChannel(teamName, [
{user: sysadmin, canCreate: true, isSysadmin: true},
{user: teamAdmin, canCreate: false},
{user: regularUser, canCreate: false},
]);
// * Verify that team admin and system admin see option to rename private channel, and member does not
verifyRenamePrivateChannel(teamName, privateChannelName, [
{user: sysadmin, canRename: true},
{user: teamAdmin, canRename: true},
{user: regularUser, canRename: false},
]);
}

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

@@ -0,0 +1,31 @@
// 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 @enterprise @not_cloud @system_console @license_removal
describe('System console', () => {
before(() => {
// * Ensure we are on self-hosted Starter edition
cy.shouldNotRunOnCloudEdition();
cy.apiDeleteLicense();
});
it('MM-T5132 License page shows View plans button', () => {
cy.visit('/admin_console/about/license');
// *Validate View plans button exits
cy.get('.StarterLeftPanel').get('#starter_edition_view_plans').contains('View plans');
// # Click View plans
cy.get('.StarterLeftPanel').get('#starter_edition_view_plans').click();
// *Ensure pricing modal is open
cy.get('#pricingModal').should('exist');
});
});

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

@@ -0,0 +1,92 @@
// 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 @enterprise @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Archived channels', () => {
let testChannel;
before(() => {
cy.apiRequireLicense();
cy.apiUpdateConfig({
TeamSettings: {
ExperimentalViewArchivedChannels: true,
},
});
cy.apiInitSetup({
channelPrefix: {name: '000-archive', displayName: '000 Archive Test'},
}).then(({channel}) => {
testChannel = channel;
// # Archive the channel
cy.apiDeleteChannel(testChannel.id);
});
});
it('are present in the channels list view', () => {
// # Go to the channels list view
cy.visit('/admin_console/user_management/channels');
// * Verify the archived channel is visible
cy.findByText(testChannel.display_name, {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
// * Verify the deleted channel displays the correct icon
cy.findByTestId(`${testChannel.name}-archive-icon`).should('be.visible');
});
it('appear in the search results of the channels list view', () => {
// # Go to the channels list view
cy.visit('/admin_console/user_management/channels');
// # Search for the archived channel
cy.findByTestId('searchInput', {timeout: TIMEOUTS.ONE_MIN}).type(`${testChannel.display_name}{enter}`);
// * Verify the archived channel is in the results
cy.findByText(testChannel.display_name).should('be.visible');
});
it('display an unarchive button and a limited set of other UI elements', () => {
// # Go to the channel details view
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// * Verify the Unarchive Channel button is visible
cy.get('button.ArchiveButton', {timeout: TIMEOUTS.ONE_MIN}).findByText('Unarchive Channel').should('be.visible');
// * Verify that only one widget is visible
cy.get('div.AdminPanel').should('be.visible').and('have.length', 1);
});
it('can be unarchived', () => {
// # Go to the channel details view
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// # Click Unarchive Channel button
cy.get('button.ArchiveButton', {timeout: TIMEOUTS.ONE_MIN}).findAllByText('Unarchive Channel').click();
// * Verify the Archive Channel button is visible
cy.get('button.ArchiveButton', {timeout: TIMEOUTS.TWO_SEC}).findAllByText('Archive Channel').should('be.visible');
// * Verify that the other widget appears
cy.get('div.AdminPanel').should('be.visible').should('have.length', 5);
// # Save and wait for redirect
cy.get('#saveSetting').click();
cy.get('.DataGrid', {timeout: TIMEOUTS.TWO_SEC}).scrollIntoView().should('be.visible');
// * Verify via the API that the channel is unarchived
cy.apiGetChannel(testChannel.id).then(({channel}) => {
expect(channel.delete_at).to.eq(0);
});
});
});

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

@@ -0,0 +1,120 @@
// 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 @enterprise @system_console @mfa
import ldapUsers from '../../../../fixtures/ldap_users.json';
import * as TIMEOUTS from '../../../../fixtures/timeouts';
import {getAdminAccount} from '../../../../support/env';
const authenticator = require('authenticator');
describe('Settings', () => {
let mfaUser;
let samlUser;
const ldapUser = ldapUsers['test-1'];
before(() => {
cy.apiInitSetup().then(({user}) => {
mfaUser = user;
cy.apiUpdateConfig({
ServiceSettings: {
EnableMultifactorAuthentication: true,
},
});
// * Check if server has license for LDAP
cy.apiRequireLicenseForFeature('LDAP');
return cy.apiSyncLDAPUser({ldapUser});
}).then(() => {
return cy.apiCreateUser();
}).then(({user: user2}) => {
// # Create SAML user
samlUser = user2;
const body = {
from: 'email',
auto: false,
};
body.matches = {};
body.matches[user2.email] = user2.username;
return migrateAuthToSAML(body);
}).then(() => {
return cy.apiGenerateMfaSecret(mfaUser.id);
}).then((res) => {
// # Create MFA user
const token = authenticator.generateToken(res.code.secret);
return cy.apiActivateUserMFA(mfaUser.id, true, token);
});
});
it('MM-T953 Verify correct authentication method', () => {
cy.visit('/admin_console/user_management/users');
const adminUsername = getAdminAccount().username;
// # Type sysadmin
cy.get('#searchUsers').clear().type(adminUsername).wait(TIMEOUTS.HALF_SEC);
// * Verify sign-in method
cy.findByTestId('userListRow').within(() => {
cy.get('.more-modal__details').
should('be.visible').
and('contain.text', 'Sign-in Method: Email');
});
// # Type saml user
cy.get('#searchUsers').clear().type(samlUser.username).wait(TIMEOUTS.HALF_SEC);
// * Verify sign-in method
cy.findByTestId('userListRow').within(() => {
cy.get('.more-modal__details').
should('be.visible').
and('contain.text', 'Sign-in Method: SAML');
});
// # Type ldap user
cy.get('#searchUsers').clear().type(ldapUser.username).wait(TIMEOUTS.HALF_SEC);
// * Verify sign-in method
cy.findByTestId('userListRow').within(() => {
cy.get('.more-modal__details').
should('be.visible').
and('contain.text', 'Sign-in Method: LDAP');
});
// # Type mfa user
cy.get('#searchUsers').clear().type(mfaUser.username).wait(TIMEOUTS.HALF_SEC);
// * Verify sign-in method
cy.findByTestId('userListRow').within(() => {
cy.get('.more-modal__details').
should('be.visible').
and('contain.text', 'MFA: Yes');
});
});
});
function migrateAuthToSAML(body) {
return cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/users/migrate_auth/saml',
method: 'POST',
body,
timeout: TIMEOUTS.ONE_MIN,
}).then((response) => {
expect(response.status).to.equal(200);
return cy.wrap(response);
});
}

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

@@ -0,0 +1,203 @@
// 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 @enterprise
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Channel members test', () => {
let testChannel;
let user1;
let user2;
let sysadmin;
before(() => {
// # Login as sysadmin
cy.apiAdminLogin().then((res) => {
sysadmin = res.user;
});
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
user1 = user;
testChannel = channel;
cy.apiCreateUser().then(({user: newUser}) => {
user2 = newUser;
cy.apiAddUserToTeam(team.id, user2.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, user2.id);
});
});
});
});
it('MM-23938 - Channel members block is only visible when channel is not group synced', () => {
// # Visit the channel page
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// * Assert that the members block is visible on non group synced channel
cy.get('#channelMembers').scrollIntoView().should('be.visible');
// # Click the sync group members switch
cy.findByTestId('syncGroupSwitch').
scrollIntoView().
findByRole('button').
click({force: true});
// * Assert that the members block is no longer visible
cy.get('#channelMembers').should('not.exist');
});
it('MM-23938 - Channel Members block can search for users, remove users, add users and modify their roles', () => {
// # Visit the channel page
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// * Assert that the members block is visible on non group synced team
cy.get('#channelMembers').scrollIntoView().should('be.visible');
// # Search for user1 that we know is in the team
searchFor(user1.email);
// # Wait till loading complete and then remove the only visible user
cy.get('#channelMembers .DataGrid_loading').should('not.exist');
cy.get('#channelMembers .UserGrid_removeRow a').should('be.visible').click();
// # Attempt to save
cy.get('#saveSetting').click();
// * Assert that confirmation modal contains the right message
cy.get('#confirmModalBody').should('be.visible').and('contain', '1 user will be removed.').and('contain', 'Are you sure you wish to remove this user?');
// # Cancel
cy.get('#cancelModalButton').click();
// # Search for user2 that we know is in the team
searchFor(user2.email);
// # Wait till loading complete and then remove the only visible user
cy.get('#channelMembers .DataGrid_loading').should('not.exist');
cy.get('#channelMembers .UserGrid_removeRow a').should('be.visible').click();
// # Attempt to save
cy.get('#saveSetting').click();
// * Assert that confirmation modal contains the right message
cy.get('#confirmModalBody').should('be.visible').and('contain', '2 users will be removed.').and('contain', 'Are you sure you wish to remove these users?');
// # Confirm Save
cy.get('#confirmModalButton').click();
// # Check that the members block is no longer visible meaning that the save has succeeded and we were redirected out
cy.get('#channelMembers').should('not.exist');
// # Visit the channel page
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// # Search for user1 that we know is no longer in the team
searchFor(user1.email);
// * Assert that no matching users found
cy.get('#channelMembers .DataGrid_rows').should('contain', 'No users found');
// # Search for user2 that we know is no longer in the team
searchFor(user2.email);
// * Assert that no matching users found
cy.get('#channelMembers .DataGrid_rows').should('contain', 'No users found');
// # Open the add members modal
cy.get('#addChannelMembers').click();
// # Enter user1 and user2 emails
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(`${user1.email}{enter}${user2.email}{enter}`);
// # Confirm add the users
cy.get('#addUsersToChannelModal #saveItems').click();
// # Search for user1
searchFor(user1.email);
// * Assert that the user is now added to the members block and contains text denoting that they are New
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', user1.email).and('contain', 'New');
// # Open the user role dropdown menu
cy.get(`#userGridRoleDropdown_${user1.username}`).click();
// * Verify that the menu is opened
cy.get('.Menu__content').should('be.visible').within(() => {
// # Make the user an admin
cy.findByText('Make Channel Admin').should('be.visible');
cy.findByText('Make Channel Admin').click();
});
// # Search for user2
searchFor(user2.email);
// * Assert that the user is now added to the members block and contains text denoting that they are New
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', user2.email).and('contain', 'New');
// # Search for sysadmin
searchFor(sysadmin.email);
// * Assert that searching for users after adding users returns only relevant search results
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', sysadmin.email);
// # Attempt to save
saveConfig();
// # Visit the channel page
cy.visit(`/admin_console/user_management/channels/${testChannel.id}`);
// # Search user1 that we know is now in the team again
searchFor(user1.email);
cy.get('#channelMembers .DataGrid_loading').should('not.exist');
// * Assert that the user is now saved as an admin
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', user1.email).and('not.contain', 'New').and('contain', 'Channel Admin');
// # Open the user role dropdown menu
cy.get(`#userGridRoleDropdown_${user1.username}`).click();
// * Verify that the menu is opened
cy.get('.Menu__content').should('be.visible').within(() => {
// # Make the user a regular member again
cy.findByText('Make Channel Member').should('be.visible').click();
});
// * Assert user1 is now back to being a regular member
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', user1.email).and('not.contain', 'New').and('contain', 'Member');
// # Search user2 that we know is now in the team again
searchFor(user2.email);
cy.get('#channelMembers .DataGrid_loading').should('not.exist');
// * Assert user2 is now saved as a regular member
cy.get('#channelMembers .DataGrid_rows').children(0).should('contain', user2.email).and('not.contain', 'New').and('contain', 'Member');
// # Attempt to save
saveConfig();
});
});
function saveConfig() {
// # Click save
cy.get('#saveSetting').click();
// # Check that the members block is no longer visible meaning that the save has succeeded and we were redirected out
cy.get('#channelMembers').should('not.exist');
}
function searchFor(searchTerm) {
cy.get('#channelMembers .DataGrid_search input[type="text"]').scrollIntoView().clear().type(searchTerm);
cy.wait(TIMEOUTS.HALF_SEC); // Timeout required to wait for timeout that happens when search input changes
}

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

@@ -0,0 +1,179 @@
// 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 @enterprise @system_console @channel_moderation
import {checkboxesTitleToIdMap} from './constants';
import {
disablePermission,
enablePermission,
postChannelMentionsAndVerifySystemMessageExist,
postChannelMentionsAndVerifySystemMessageNotExist,
saveConfigForChannel,
saveConfigForScheme,
visitChannel,
visitChannelConfigPage,
} from './helpers';
describe('MM-23102 - Channel Moderation - Channel Mentions', () => {
let regularUser;
let guestUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
regularUser = user;
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
});
});
});
it('MM-T1551 Channel Mentions option for Guests', () => {
// # Uncheck the Channel Mentions option for Guests and save
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_GUESTS);
saveConfigForChannel();
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user has the permission to user special mentions like @all @channel and @here
postChannelMentionsAndVerifySystemMessageExist(testChannel.name);
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
// # check the channel mentions option for guests and save
enablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_GUESTS);
saveConfigForChannel();
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user has the permission to user special mentions like @all @channel and @here
postChannelMentionsAndVerifySystemMessageNotExist(testChannel);
});
it('MM-T1552 Channel Mentions option for Members', () => {
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
// # Uncheck the channel mentions option for guests and save
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
// # Check Member user does not has the permission to use special mentions like @all @channel and @here
postChannelMentionsAndVerifySystemMessageExist(testChannel.name);
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
// # check the channel mentions option for guests and save
enablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
// # Check Member user has the permission to user special mentions like @all @channel and @here
postChannelMentionsAndVerifySystemMessageNotExist(testChannel);
});
it('MM-T1555 Channel Mentions option removed when Create Post is disabled', () => {
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
// # Uncheck the create posts option for guests
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_GUESTS);
// * Option to allow Channel Mentions for Guests should also be disabled when Create Post option is disabled.
// * A message Guests can not use channel mentions without the ability to create posts should be displayed.
cy.findByTestId('admin-channel_settings-channel_moderation-channelMentions-disabledGuestsDueToCreatePosts').
should('have.text', 'Guests can not use channel mentions without the ability to create posts.');
cy.findByTestId(checkboxesTitleToIdMap.CHANNEL_MENTIONS_GUESTS).should('be.disabled');
// # check the create posts option for guests and uncheck for members
enablePermission(checkboxesTitleToIdMap.CREATE_POSTS_GUESTS);
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_MEMBERS);
// * Option to allow Channel Mentions for Members should also be disabled when Create Post option is disabled.
// * A message Members can not use channel mentions without the ability to create posts should be displayed.
cy.findByTestId('admin-channel_settings-channel_moderation-channelMentions-disabledMemberDueToCreatePosts').
should('have.text', 'Members can not use channel mentions without the ability to create posts.');
cy.findByTestId(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS).should('be.disabled');
// # Uncheck the create posts option for guests
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_GUESTS);
// * Ensure that channel mentions for members and guests is disabled
// * Ensure message Guests & Members can not use channel mentions without the ability to create posts
cy.findByTestId('admin-channel_settings-channel_moderation-channelMentions-disabledBothDueToCreatePosts').
should('have.text', 'Guests and members can not use channel mentions without the ability to create posts.');
cy.findByTestId(checkboxesTitleToIdMap.CHANNEL_MENTIONS_GUESTS).should('be.disabled');
cy.findByTestId(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS).should('be.disabled');
});
it('MM-T1556 Message when user without channel mention permission uses special channel mentions', () => {
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
cy.findByTestId('post_textbox').clear().type('@');
// * Ensure that @here, @all, and @channel do not show up in the autocomplete list
cy.findAllByTestId('mentionSuggestion_here').should('not.exist');
cy.findAllByTestId('mentionSuggestion_all').should('not.exist');
cy.findAllByTestId('mentionSuggestion_channel').should('not.exist');
// * When you type @all, @enter, and @channel make sure that a system message shows up notifying you nothing happened.
postChannelMentionsAndVerifySystemMessageExist(testChannel.name);
});
it('MM-T1557 Confirm sending notifications while using special channel mentions', () => {
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
saveConfigForChannel();
// # Set @channel and @all confirmation dialog to true
cy.visit('admin_console/environment/notifications');
cy.findByTestId('TeamSettings.EnableConfirmNotificationsToChanneltrue').check();
saveConfigForScheme();
// # Visit test channel
visitChannel(regularUser, testChannel, testTeam);
// * Type at all and enter that no confirmation dialogue shows up
cy.postMessage('@all ');
cy.get('#confirmModalLabel').should('not.exist');
// * Type at channel and enter that no confirmation dialogue shows up
cy.postMessage('@channel ');
cy.get('#confirmModalLabel').should('not.exist');
// * Type at here and enter that no confirmation dialogue shows up
cy.postMessage('@here ');
cy.get('#confirmModalLabel').should('not.exist');
});
});

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

@@ -0,0 +1,26 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export const checkboxesTitleToIdMap = {
ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS: 'all_users-public_channel-manage_public_channel_members_and_read_groups-checkbox',
ALL_USERS_MANAGE_PRIVATE_CHANNEL_MEMBERS: 'all_users-private_channel-manage_private_channel_members_and_read_groups-checkbox',
ALL_USERS_MANAGE_OAUTH_APPLICATIONS: 'all_users-integrations-manage_oauth-checkbox',
CREATE_POSTS_GUESTS: 'create_post-guests',
CREATE_POSTS_MEMBERS: 'create_post-members',
POST_REACTIONS_GUESTS: 'create_reactions-guests',
POST_REACTIONS_MEMBERS: 'create_reactions-members',
MANAGE_MEMBERS_GUESTS: 'manage_members-guests',
MANAGE_MEMBERS_MEMBERS: 'manage_members-members',
CHANNEL_MENTIONS_MEMBERS: 'use_channel_mentions-members',
CHANNEL_MENTIONS_GUESTS: 'use_channel_mentions-guests',
};
export const checkBoxes = [
checkboxesTitleToIdMap.CREATE_POSTS_GUESTS,
checkboxesTitleToIdMap.CREATE_POSTS_MEMBERS,
checkboxesTitleToIdMap.POST_REACTIONS_GUESTS,
checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS,
checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS,
checkboxesTitleToIdMap.CHANNEL_MENTIONS_GUESTS,
checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS,
];

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

@@ -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 @enterprise @system_console @channel_moderation
import {checkboxesTitleToIdMap} from './constants';
import {
disablePermission,
enablePermission,
saveConfigForChannel,
visitChannel,
visitChannelConfigPage,
} from './helpers';
describe('MM-23102 - Channel Moderation - Create Posts', () => {
let regularUser;
let guestUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
regularUser = user;
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
});
});
});
it('MM-T1541 Create Post option for Guests', () => {
// # Go to channel configuration page of
visitChannelConfigPage(testChannel);
// # Uncheck the Create Posts option for Guests and Save
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_GUESTS);
saveConfigForChannel();
// # Login as a Guest user and visit the same channel
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user should not have the permission to create a post on a channel when the option is removed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled');
// # As a system admin, check the option to allow Create Posts for Guests and save
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.CREATE_POSTS_GUESTS);
saveConfigForChannel();
// # Login as a Guest user and visit the same channel
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user should have the permission to create a post on a channel when the option is allowed
// * Guest user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled');
});
it('MM-T1542 Create Post option for Members', () => {
// # Go to system admin page and to channel configuration page of test channel
visitChannelConfigPage(testChannel);
// # Uncheck the Create Posts option for Members and Save
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_MEMBERS);
saveConfigForChannel();
// # Login as a Guest user and visit test channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member should not have the permission to create a post on a channel when the option is removed.
// * User should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled');
// # As a system admin, check the option to allow Create Posts for Members and save
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.CREATE_POSTS_MEMBERS);
saveConfigForChannel();
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member should have the permission to create a post on a channel when the option is allowed
// * Member user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox').clear();
cy.findByTestId('post_textbox_placeholder').should('have.text', `Write to ${testChannel.display_name}`);
cy.findByTestId('post_textbox').should('not.be.disabled');
});
});

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

@@ -0,0 +1,304 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {getAdminAccount} from '../../../../../support/env';
import {checkBoxes} from './constants';
// # Visits the channel configuration for a channel with channelName
export const visitChannelConfigPage = (channel) => {
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/channels');
cy.get('.DataGrid_searchBar').within(() => {
cy.findByPlaceholderText('Search').type(`${channel.name}{enter}`);
});
cy.findByText('Edit').click();
cy.wait(TIMEOUTS.ONE_SEC);
};
// # Disable a permission
export const disablePermission = (permission) => {
cy.waitUntil(() => cy.findByTestId(permission).scrollIntoView().should('be.visible').then((el) => {
const classAttribute = el[0].getAttribute('class');
if (classAttribute.includes('checked') || classAttribute.includes('intermediate')) {
el[0].click();
return false;
}
return true;
}));
cy.findByTestId(permission).should('not.have.class', 'checked');
};
// # Saves channel config and navigates back to the channel config page if specified
export const saveConfigForChannel = (channelName = false, clickConfirmationButton = false) => {
cy.get('#saveSetting').then((btn) => {
if (btn.is(':enabled')) {
btn.click();
if (clickConfirmationButton) {
cy.get('#confirmModalButton').click();
}
// # Wait for location path to end with /admin_console/user_management/channels
cy.waitUntil(() => cy.location().then((location) => {
return location.href.endsWith('/admin_console/user_management/channels');
}));
// # Make sure the save is complete by looking for the search input which is only visible on the team's index page
cy.get('.DataGrid_searchBar').should('be.visible').within(() => {
cy.findByPlaceholderText('Search').should('be.visible');
});
if (channelName) {
// # Search for the channel.
cy.get('.DataGrid_searchBar').within(() => {
cy.findByPlaceholderText('Search').type(`${channelName}{enter}`);
});
cy.findByText('Edit').click();
}
}
});
};
// # Visits a channel as the member specified
export const visitChannel = (user, channel, team) => {
cy.apiLogin(user);
cy.visit(`/${team.name}/channels/${channel.name}`);
cy.get('#postListContent', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
};
// # Checks to see if we got a system message warning after using @all/@here/@channel
export const postChannelMentionsAndVerifySystemMessageExist = (channelName) => {
function getSystemMessage(text) {
return `Channel notifications are disabled in ${channelName}. The ${text} did not trigger any notifications.`;
}
// # Type @all and post it to the channel
cy.postMessage('@all ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is the system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', getSystemMessage('@all'));
});
// # Type @here and post it to the channel
cy.postMessage('@here ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is the system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', getSystemMessage('@here'));
});
cy.postMessage('@channel ');
// # Type last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is the system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', getSystemMessage('@channel'));
});
};
// # Enable a permission
export const enablePermission = (permission) => {
cy.waitUntil(() => cy.findByTestId(permission).scrollIntoView().should('be.visible').then((el) => {
const classAttribute = el[0].getAttribute('class');
if (!classAttribute.includes('checked')) {
el[0].click();
return false;
}
return true;
}));
cy.findByTestId(permission).should('have.class', 'checked');
};
// # Checks to see if we did not get a system message warning after using @all/@here/@channel
export const postChannelMentionsAndVerifySystemMessageNotExist = (channel) => {
function getSystemMessage(text) {
return `Channel notifications are disabled in ${channel.name}. The ${text} did not trigger any notifications.`;
}
cy.postMessage('@all ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is NOT a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('not.have.text', getSystemMessage('@all'));
});
cy.postMessage('@here ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is NOT a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('not.have.text', getSystemMessage('@here'));
});
cy.postMessage('@channel ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
// * Assert that the last message posted is NOT a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('not.have.text', getSystemMessage('@channel'));
});
};
// # Wait's until the Saving text becomes Save
const waitUntilConfigSave = () => {
cy.waitUntil(() => cy.get('#saveSetting').then((el) => {
return el[0].innerText === 'Save';
}));
};
// Clicks the save button in the system console page.
// waitUntilConfigSaved: If we need to wait for the save button to go from saving -> save.
// Usually we need to wait unless we are doing this in team override scheme
export const saveConfigForScheme = (waitUntilConfigSaved = true, clickConfirmationButton = false) => {
// # Save if possible (if previous test ended abruptly all permissions may already be enabled)
cy.get('#saveSetting').then((btn) => {
if (btn.is(':enabled')) {
btn.click();
}
});
if (clickConfirmationButton) {
cy.get('#confirmModalButton').click();
}
if (waitUntilConfigSaved) {
waitUntilConfigSave();
}
};
// # Goes to the System Scheme page as System Admin
export const goToSystemScheme = () => {
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and('have.text', 'System Scheme');
};
// # Goes to the permissions page and creates a new team override scheme with schemeName
export const goToPermissionsAndCreateTeamOverrideScheme = (schemeName, team) => {
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions');
cy.findByTestId('team-override-schemes-link').click();
cy.get('#scheme-name').type(schemeName);
cy.findByTestId('add-teams').click();
cy.get('#selectItems input').typeWithForce(team.display_name);
cy.get('#multiSelectList').should('be.visible').children().first().click({force: true});
cy.get('#saveItems').should('be.visible').click();
saveConfigForScheme(false);
cy.wait(TIMEOUTS.ONE_SEC);
};
// # Goes to the permissions page and clicks edit or delete for a team override scheme
export const deleteOrEditTeamScheme = (schemeDisplayName, editOrDelete) => {
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions');
cy.findByTestId(`${schemeDisplayName}-${editOrDelete}`).click();
if (editOrDelete === 'delete') {
cy.get('#confirmModalButton').click();
}
};
// # Open channel members rhs
export const viewManageChannelMembersRHS = () => {
// # Click member count to open member list rhs
cy.get('.member-rhs__trigger').click();
};
// # Enable (check) all the permissions in the channel moderation widget through the API
export const enableDisableAllChannelModeratedPermissionsViaAPI = (channel, enable = true) => {
cy.externalRequest(
{
user: getAdminAccount(),
method: 'PUT',
path: `channels/${channel.id}/moderations/patch`,
data:
[
{
name: 'create_post',
roles: {
members: enable,
guests: enable,
},
},
{
name: 'create_reactions',
roles: {
members: enable,
guests: enable,
},
},
{
name: 'manage_members',
roles: {
members: enable,
},
},
{
name: 'use_channel_mentions',
roles: {
members: enable,
guests: enable,
},
},
],
},
);
};
// # This goes to the system scheme and clicks the reset permissions to default and then saves the setting
export const resetSystemSchemePermissionsToDefault = () => {
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
cy.findByTestId('resetPermissionsToDefault').click();
cy.get('#confirmModalButton').click();
saveConfigForScheme();
};
export const demoteToChannelOrTeamMember = (userId, id, channelsOrTeams = 'channels') => {
cy.externalRequest({
user: getAdminAccount(),
method: 'put',
path: `${channelsOrTeams}/${id}/members/${userId}/schemeRoles`,
data: {
scheme_user: true,
scheme_admin: false,
},
});
};
export const promoteToChannelOrTeamAdmin = (userId, id, channelsOrTeams = 'channels') => {
cy.externalRequest({
user: getAdminAccount(),
method: 'put',
path: `${channelsOrTeams}/${id}/members/${userId}/schemeRoles`,
data: {
scheme_user: true,
scheme_admin: true,
},
});
};
// # Disable (uncheck) all the permissions in the channel moderation widget
export const disableAllChannelModeratedPermissions = () => {
checkBoxes.forEach((buttonId) => {
cy.findByTestId(buttonId).then((btn) => {
if (btn.hasClass('checked')) {
btn.click();
}
});
});
};
// # Enable (check) all the permissions in the channel moderation widget
export const enableAllChannelModeratedPermissions = () => {
checkBoxes.forEach((buttonId) => {
cy.findByTestId(buttonId).then((btn) => {
if (!btn.hasClass('checked')) {
btn.click();
}
});
});
};

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

@@ -0,0 +1,320 @@
// 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 @enterprise @system_console @channel_moderation
import {getRandomId} from '../../../../../utils';
import {checkboxesTitleToIdMap} from './constants';
import {
deleteOrEditTeamScheme,
demoteToChannelOrTeamMember,
disablePermission,
enablePermission,
enableDisableAllChannelModeratedPermissionsViaAPI,
goToPermissionsAndCreateTeamOverrideScheme,
goToSystemScheme,
postChannelMentionsAndVerifySystemMessageNotExist,
promoteToChannelOrTeamAdmin,
saveConfigForChannel,
saveConfigForScheme,
viewManageChannelMembersModal,
visitChannel,
visitChannelConfigPage,
} from './helpers';
describe('MM-23102 - Channel Moderation - Higher Scoped Scheme', () => {
let regularUser;
let guestUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiResetRoles();
cy.apiInitSetup().then(({team, channel, user}) => {
regularUser = user;
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
});
});
});
it('MM-T1559 Effect of changing System Schemes on a Channel for which Channel Moderation Settings was modified', () => {
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
// # check the channel mentions option for guests and save
enablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
saveConfigForChannel();
goToSystemScheme();
disablePermission(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS);
saveConfigForScheme();
// * Ensure manage members for members is disabled
visitChannelConfigPage(testChannel);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
visitChannel(regularUser, testChannel, testTeam);
// # View members modal
viewManageChannelMembersModal('View');
// * Add Members button does not exist
cy.get('#showInviteModal').should('not.exist');
});
it('MM-T1560 Effect of changing System Schemes on a Channel for which Channel Moderation Settings was never modified', () => {
// # Reset system scheme to default and create a new channel to ensure that this channels moderation settings have never been modified
cy.apiAdminLogin();
cy.apiCreateChannel(testTeam.id, 'never-modified', `Never Modified ${getRandomId()}`).then(({channel}) => {
goToSystemScheme();
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS).click();
saveConfigForScheme();
// # Visit Channel page and Search for the channel.
// * ensure manage members for members is disabled
visitChannelConfigPage(channel);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
visitChannel(regularUser, channel, testTeam);
// # View members modal
viewManageChannelMembersModal('View');
// * Add Members button does not exist
cy.get('#showInviteModal').should('not.exist');
});
});
it('MM-T1561 Effect of changing Team Override Schemes on a Channel for which Channel Moderation Settings was never modified', () => {
// # Reset system scheme to default and create a new channel to ensure that this channels moderation settings have never been modified
cy.apiAdminLogin();
cy.apiCreateChannel(testTeam.id, 'never-modified', `Never Modified ${getRandomId()}`).then(({channel}) => {
goToPermissionsAndCreateTeamOverrideScheme(channel.name, testTeam);
deleteOrEditTeamScheme(channel.name, 'edit');
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS).click();
saveConfigForScheme(false);
// # Visit Channel page and Search for the channel.
// * Assert message for manage member for members appears and that it's disabled
visitChannelConfigPage(channel);
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('have.text', `Manage members for members are disabled in ${channel.name} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
visitChannel(regularUser, channel, testTeam);
// # View members modal
viewManageChannelMembersModal('View');
// * Add Members button does not exist
cy.get('#showInviteModal').should('not.exist');
});
});
it('MM-T1562 Effect of changing Team Override Schemes on a Channel for which Channel Moderation Settings was modified', () => {
const teamOverrideSchemeName = testChannel.name + getRandomId();
// # Reset system scheme to default and create a new channel to ensure that this channels moderation settings have never been modified
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
disablePermission(checkboxesTitleToIdMap.CHANNEL_MENTIONS_MEMBERS);
saveConfigForChannel();
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
saveConfigForChannel();
goToPermissionsAndCreateTeamOverrideScheme(teamOverrideSchemeName, testTeam);
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS).click();
saveConfigForScheme(false);
// # Visit Channel page and Search for the channel.
// * Assert message shows and manage members for members is disabled
visitChannelConfigPage(testChannel);
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
visitChannel(regularUser, testChannel, testTeam);
// # View members modal
viewManageChannelMembersModal('View');
// * Add Members button does not exist
cy.get('#showInviteModal').should('not.exist');
});
it('MM-T1578 Manage Members removed for Public Channels', () => {
const teamOverrideSchemeName = testChannel.name + getRandomId();
// # Create a new team override scheme and remove manage public channel members
// * Ensure that manage private channel members is checked
goToPermissionsAndCreateTeamOverrideScheme(teamOverrideSchemeName, testTeam);
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS).click();
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PRIVATE_CHANNEL_MEMBERS).should('be.visible').and('have.class', 'checked');
saveConfigForScheme(false);
// # Visit Channel page and Search for the channel.
// * Ensure message is disabled and manage members for members is disabled
visitChannelConfigPage(testChannel);
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Public');
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
// # Turn channel into a private channel
cy.findByTestId('allow-all-toggle').click();
saveConfigForChannel(testChannel.display_name, true);
// * Ensure it is private and no error message is shown and that manage members for members is not disabled
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Private');
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('not.have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('not.be.disabled');
// # Turn channel back to public channel
cy.findByTestId('allow-all-toggle').click();
saveConfigForChannel(testChannel.display_name, true);
// * ensure it got reverted back to a Public channel
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Public');
});
it('MM-T1579 Manage Members removed for Private Channels / Permissions inherited when channel converted from Public to Private', () => {
const teamOverrideSchemeName = testChannel.name + getRandomId();
// # Create a new team override scheme and remove manage private channel members from it
// * Ensure that manage public channel members is checked
goToPermissionsAndCreateTeamOverrideScheme(teamOverrideSchemeName, testTeam);
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PRIVATE_CHANNEL_MEMBERS).click();
cy.findByTestId(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS).should('be.visible').and('have.class', 'checked');
saveConfigForScheme(false);
// # Visit Channel page and Search for the channel.
visitChannelConfigPage(testChannel);
// * Ensure that error message is not displayed and manage members for members is not disabled
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Public');
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('not.have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('not.be.disabled');
// # Turn it into a private channel
cy.findByTestId('allow-all-toggle').click();
saveConfigForChannel(testChannel.display_name, true);
// * Ensure it is a private channel and that a message is disabled and also manage members for members is disabled
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Private');
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
// # Turn channel back to public channel
cy.findByTestId('allow-all-toggle').click();
saveConfigForChannel(testChannel.display_name, true);
// * Ensure it got reset back to a public channel
cy.findByTestId('allow-all-toggle').should('has.have.text', 'Public');
});
it('MM-T1581 Check if user is allowed to Edit or Delete their own posts on a Read-Only channel', () => {
visitChannel(regularUser, testChannel, testTeam);
cy.postMessage(`test message ${Date.now()}`);
cy.findByTestId('post_textbox_placeholder').should('not.have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('not.be.disabled');
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.CREATE_POSTS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
// * user should see a message stating that this channel is read-only and the textbox area should be disabled
cy.findByTestId('post_textbox_placeholder').should('have.text', 'This channel is read-only. Only members with permission can post here.');
cy.findByTestId('post_textbox').should('be.disabled');
cy.getLastPostId().then((postId) => {
cy.clickPostDotMenu(postId);
// * As per test case, ensure edit and delete button show up
cy.get(`#edit_post_${postId}`).should('exist');
cy.get(`#delete_post_${postId}`).should('exist');
});
});
it('MM-T1582 Channel Moderation Settings should not be applied for Channel Admins', () => {
enableDisableAllChannelModeratedPermissionsViaAPI(testChannel, false);
visitChannel(regularUser, testChannel, testTeam);
promoteToChannelOrTeamAdmin(regularUser.id, testChannel.id);
// * Assert user can post message and user channel mentions
postChannelMentionsAndVerifySystemMessageNotExist(testChannel);
// # Check Channel Admin have the permission to react to any post on a channel when all channel moderation permissions are off.
// * Channel Admin should see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('exist');
});
// # View members modal
viewManageChannelMembersModal('Manage');
// * Add Members button does not exist
cy.get('#showInviteModal').should('exist');
demoteToChannelOrTeamMember(regularUser.id, testChannel.id);
});
it('MM-T1583 Channel Moderation Settings should not be applied for Team Admins', () => {
enableDisableAllChannelModeratedPermissionsViaAPI(testChannel, false);
visitChannel(regularUser, testChannel, testTeam);
promoteToChannelOrTeamAdmin(regularUser.id, testTeam.id, 'teams');
// * Assert user can post message and user channel mentions
postChannelMentionsAndVerifySystemMessageNotExist(testChannel);
// # Check Channel Admin have the permission to react to any post on a channel when all channel moderation permissions are off.
// * Channel Admin should see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('exist');
});
// # View members modal
viewManageChannelMembersModal('Manage');
// * Add Members button does not exist
cy.get('#showInviteModal').should('exist');
demoteToChannelOrTeamMember(regularUser.id, testTeam.id, 'teams');
});
});

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

@@ -0,0 +1,195 @@
// 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 @enterprise @system_console @channel_moderation
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {getRandomId} from '../../../../../utils';
import {checkboxesTitleToIdMap} from './constants';
import {
deleteOrEditTeamScheme,
disablePermission,
enablePermission,
goToPermissionsAndCreateTeamOverrideScheme,
goToSystemScheme,
saveConfigForChannel,
saveConfigForScheme,
viewManageChannelMembersRHS,
visitChannel,
visitChannelConfigPage,
} from './helpers';
function addButtonExists() {
cy.uiGetRHS().contains('button', 'Add').should('be.visible');
}
function addButtonDoesNotExists() {
cy.uiGetRHS().contains('button', 'Add').should('not.exist');
}
describe('MM-23102 - Channel Moderation - Manage Members', () => {
let regularUser;
let guestUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiResetRoles();
cy.apiInitSetup().then(({team, channel, user}) => {
regularUser = user;
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
});
});
});
it('MM-T1547 No option to Manage Members for Guests', () => {
visitChannelConfigPage(testChannel);
// * Assert that Manage Members for Guests does not exist (checkbox is not there)
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_GUESTS).should('not.exist');
visitChannel(guestUser, testChannel, testTeam);
// # View members rhs
viewManageChannelMembersRHS();
// * Add Members button does not exist
addButtonDoesNotExists();
});
it('MM-T1548 Manage Members option for Members', () => {
// # Visit test channel page and turn off the Manage members for Members and then save
visitChannelConfigPage(testChannel);
disablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does not exist
addButtonDoesNotExists();
cy.uiGetRHS().contains('button', 'Add').should('not.exist');
// # Visit test channel page and turn off the Manage members for Members and then save
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS);
saveConfigForChannel();
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does exist
addButtonExists();
});
it('MM-T1549 Manage Members option removed for Members in System Scheme', () => {
// Edit the System Scheme and disable the Manage Members option for Members & Save.
goToSystemScheme();
disablePermission(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS);
saveConfigForScheme();
// # Visit test channel page
visitChannelConfigPage(testChannel);
// * Assert that Manage Members option should be disabled for a Members.
// * A message Manage members for members are disabled in the System Scheme should be displayed.
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('exist').
and('have.text', 'Manage members for members are disabled in System Scheme.');
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_GUESTS).should('not.exist');
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does not exist
addButtonDoesNotExists();
// Edit the System Scheme and enable the Manage Members option for Members & Save.
goToSystemScheme();
enablePermission(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS);
saveConfigForScheme();
// # Visit test channel page
visitChannelConfigPage(testChannel);
// * Assert that Manage Members option should be enabled for a Members.
// * A message Manage members for members are enabled in the System Scheme should be displayed.
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('not.exist');
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does not exist
addButtonExists();
});
it('MM-T1550 Manage Members option removed for Members in Team Override Scheme', () => {
const teamOverrideSchemeName = `manage_members_${getRandomId()}`;
// # Create a new team override scheme and remove manage members option for members
goToPermissionsAndCreateTeamOverrideScheme(teamOverrideSchemeName, testTeam);
// # Disable mange channel members
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
disablePermission(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS);
saveConfigForScheme(false);
cy.wait(TIMEOUTS.FIVE_SEC);
// * Assert that Manage Members is disabled for members and a message is displayed
visitChannelConfigPage(testChannel);
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('exist').
and('have.text', `Manage members for members are disabled in ${teamOverrideSchemeName} Team Scheme.`);
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('be.disabled');
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_GUESTS).should('not.exist');
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does not exist in manage channel members modal
addButtonDoesNotExists();
// # Enable manage channel members
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
enablePermission(checkboxesTitleToIdMap.ALL_USERS_MANAGE_PUBLIC_CHANNEL_MEMBERS);
saveConfigForScheme(false);
cy.wait(TIMEOUTS.FIVE_SEC);
visitChannelConfigPage(testChannel);
cy.findByTestId('admin-channel_settings-channel_moderation-manageMembers-disabledMember').
should('not.exist');
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_MEMBERS).should('have.class', 'checkbox checked');
cy.findByTestId(checkboxesTitleToIdMap.MANAGE_MEMBERS_GUESTS).should('not.exist');
visitChannel(regularUser, testChannel, testTeam);
viewManageChannelMembersRHS();
// * Add Members button does exist in manage channel members modal
addButtonExists();
});
});

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

@@ -0,0 +1,227 @@
// 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 @enterprise @system_console @channel_moderation
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {getRandomId} from '../../../../../utils';
import {getAdminAccount} from '../../../../../support/env';
import {checkboxesTitleToIdMap} from './constants';
import {
deleteOrEditTeamScheme,
disablePermission,
enablePermission,
goToPermissionsAndCreateTeamOverrideScheme,
goToSystemScheme,
saveConfigForChannel,
saveConfigForScheme,
visitChannel,
visitChannelConfigPage,
} from './helpers';
describe('MM-23102 - Channel Moderation - Post Reactions', () => {
let regularUser;
let guestUser;
let testTeam;
let testChannel;
const admin = getAdminAccount();
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
regularUser = user;
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
// Post a few messages in the channel
visitChannel(admin, testChannel, testTeam);
for (let i = 0; i < 3; i++) {
cy.postMessage(`test message ${Date.now()}`);
}
});
});
});
it('MM-T1543 Post Reactions option for Guests', () => {
visitChannelConfigPage(testChannel);
// # Uncheck the post reactions option for Guests and save
disablePermission(checkboxesTitleToIdMap.POST_REACTIONS_GUESTS);
saveConfigForChannel();
// # Login as a Guest user and visit the same channel
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user should not have the permission to react to any post on a channel when the option is removed.
// * Guest user should not see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('not.exist');
});
// # Visit test channel configuration page and enable post reactions for guest and save
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.POST_REACTIONS_GUESTS);
saveConfigForChannel();
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest user should have the permission to react to any post on a channel when the option is allowed.
// * Guest user should see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('exist');
});
});
it('MM-T1544 Post Reactions option for Members', () => {
visitChannelConfigPage(testChannel);
// # Uncheck the Create reactions option for Members and save
disablePermission(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS);
saveConfigForChannel();
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member user should not have the permission to react to any post on a channel when the option is removed.
// * Member user should not see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('not.exist');
});
// # Visit test Channel configuration page and enable post reactions for members and save
visitChannelConfigPage(testChannel);
enablePermission(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS);
saveConfigForChannel();
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member user should have the permission to react to any post on a channel when the option is allowed.
// * Member user should see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('exist');
});
});
it('MM-T1545 Post Reactions option removed for Guests and Members in System Scheme', () => {
// # Login as sysadmin and visit the Permissions page in the system console.
// # Edit the System Scheme and remove the Post Reaction option for Guests & Save.
goToSystemScheme();
cy.get('.guest').should('be.visible').within(() => {
cy.findByText('Post Reactions').click();
});
saveConfigForScheme();
// # Visit the Channels page and click on a channel.
visitChannelConfigPage(testChannel);
// * Assert that post reaction is disabled for guest and not disabled for members and a message is displayed
cy.findByTestId('admin-channel_settings-channel_moderation-postReactions-disabledGuest').
should('exist').
and('have.text', 'Post reactions for guests are disabled in System Scheme.');
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS).should('not.be.disabled');
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_GUESTS).should('be.disabled');
// # Go to system admin page and then go to the system scheme and remove post reaction option for all members and save
goToSystemScheme();
cy.get('#all_users-posts-reactions').click();
saveConfigForScheme();
visitChannelConfigPage(testChannel);
// * Post Reaction option should be disabled for a Members. A message Post reactions for guests & members are disabled in the System Scheme should be displayed.
cy.findByTestId('admin-channel_settings-channel_moderation-postReactions-disabledBoth').
should('exist').
and('have.text', 'Post reactions for members and guests are disabled in System Scheme.');
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS).should('be.disabled');
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_GUESTS).should('be.disabled');
// # Login as a Guest user and visit the same channel
visitChannel(guestUser, testChannel, testTeam);
// # Check Guest User should not have the permission to react to any post on any channel when the option is removed from the System Scheme.
// * Guest user should not see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('not.exist');
});
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member should not have the permission to react to any post on any channel when the option is removed from the System Scheme.
// * Member user should not see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('not.exist');
});
});
// GUEST PERMISSIONS DON'T EXIST ON TEAM OVERRIDE SCHEMES SO GUEST PORTION NOT IMPLEMENTED!
// ONLY THE MEMBERS PORTION OF THIS TEST IS IMPLEMENTED
it('MM-T1546_4 Post Reactions option removed for Guests & Members in Team Override Scheme', () => {
const teamOverrideSchemeName = `post_reactions_${getRandomId()}`;
// # Create a new team override scheme
goToPermissionsAndCreateTeamOverrideScheme(teamOverrideSchemeName, testTeam);
visitChannelConfigPage(testChannel);
// * Assert that post reaction is disabled for members
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS).should('have.class', 'checkbox checked');
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member should have the permission to react to any post on any channel in that team
// * User should see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('exist');
});
// # Go to system admin page and then go to the system scheme and remove post reaction option for all members and save
deleteOrEditTeamScheme(teamOverrideSchemeName, 'edit');
cy.get('#all_users-posts-reactions').click();
saveConfigForScheme(false);
// # Wait until the groups have been saved (since it redirects you)
cy.wait(TIMEOUTS.ONE_SEC);
visitChannelConfigPage(testChannel);
// * Assert that post reaction is disabled for members
cy.findByTestId(checkboxesTitleToIdMap.POST_REACTIONS_MEMBERS).should('have.class', 'checkbox disabled');
// # Login as a Member user and visit the same channel
visitChannel(regularUser, testChannel, testTeam);
// # Check Member should not have the permission to react to any post on any channel in that team
// * User should not see the smiley face that allows a user to react to a post
cy.getLastPostId().then((postId) => {
cy.get(`#post_${postId}`).trigger('mouseover');
cy.findByTestId('post-reaction-emoji-icon').should('not.exist');
});
});
});

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

@@ -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 @enterprise @system_console @channel_moderation
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {checkBoxes} from './constants';
import {
disableAllChannelModeratedPermissions,
enableAllChannelModeratedPermissions,
saveConfigForChannel,
} from './helpers';
describe('Channel Moderation', () => {
let guestUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel}) => {
testTeam = team;
testChannel = channel;
cy.apiCreateGuestUser().then(({guest}) => {
guestUser = guest;
cy.apiAddUserToTeam(testTeam.id, guestUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, guestUser.id);
});
});
});
});
it('MM-22276 - Enable and Disable all channel moderated permissions', () => {
// # Go to system admin page and to channel configuration page of test channel
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/channels');
// # Search for the channel.
cy.get('.DataGrid_searchBar').within(() => {
cy.findByPlaceholderText('Search').type(`${testChannel.name}{enter}`);
});
cy.findByText('Edit').click();
// # Wait until the groups retrieved and show up
cy.wait(TIMEOUTS.ONE_SEC);
// # Check all the boxes currently unchecked (align with the system scheme permissions)
enableAllChannelModeratedPermissions();
// # Save if possible (if previous test ended abruptly all permissions may already be enabled)
saveConfigForChannel(testChannel.display_name);
// # Wait until the groups retrieved and show up
cy.wait(TIMEOUTS.ONE_SEC);
// * Ensure all checkboxes are checked
checkBoxes.forEach((buttonId) => {
cy.findByTestId(buttonId).should('have.class', 'checked');
});
// # Uncheck all the boxes currently checked
disableAllChannelModeratedPermissions();
// # Save the page and wait till saving is done
saveConfigForChannel(testChannel.display_name);
// # Wait until the groups retrieved and show up
cy.wait(TIMEOUTS.ONE_SEC);
// * Ensure all checkboxes have the correct unchecked state
checkBoxes.forEach((buttonId) => {
// * Ensure all checkboxes are unchecked
cy.findByTestId(buttonId).should('not.have.class', 'checked');
// * Ensure Channel Mentions are disabled due to Create Posts
if (buttonId.includes('use_channel_mentions')) {
cy.findByTestId(buttonId).should('be.disabled');
return;
}
// * Ensure all other check boxes are still enabled
cy.findByTestId(buttonId).should('not.be.disabled');
});
});
});

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

@@ -0,0 +1,87 @@
// 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 @enterprise @system_console @high_availability @not_cloud
describe('Cluster', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
// * Check if server has license
cy.apiRequireLicense();
// # Reset Experimental Gossip Encryption
cy.apiUpdateConfig({
ClusterSettings: {
Enable: null,
EnableExperimentalGossipEncryption: null,
},
});
// # Visit high availability system console page
cy.visit('/admin_console/environment/high_availability');
});
it('SC25050 - Can change Experimental Gossip Encryption', () => {
cy.findByTestId('EnableExperimentalGossipEncryption').scrollIntoView().should('be.visible').within(() => {
// * Verify that setting is visible and matches text content
cy.get('.control-label').should('be.visible').and('have.text', 'Enable Experimental Gossip encryption:');
// * Verify that the help setting is visible and matches text content
const contents = 'When true, all communication through the gossip protocol will be encrypted.';
cy.get('.help-text').should('be.visible').and('have.text', contents);
// * Verify that Experimental Gossip Encryption is set to false by default
cy.get('#EnableExperimentalGossipEncryptionfalse').should('have.attr', 'checked');
});
// # Enable Experimental Gossip Encryption
cy.apiUpdateConfig({
ClusterSettings: {
Enable: true,
EnableExperimentalGossipEncryption: true,
},
});
cy.reload();
cy.findByTestId('EnableExperimentalGossipEncryption').scrollIntoView().should('be.visible').within(() => {
// * Verify that Experimental Gossip Encryption is set to true
cy.get('#EnableExperimentalGossipEncryptiontrue').should('have.attr', 'checked');
});
});
it('Can change Gossip Compression', () => {
cy.findByTestId('EnableGossipCompression').scrollIntoView().should('be.visible').within(() => {
// * Verify that setting is visible and matches text content
cy.get('.control-label').should('be.visible').and('have.text', 'Enable Gossip compression:');
// * Verify that the help setting is visible and matches text content
const contents = 'When true, all communication through the gossip protocol will be compresssed. It is recommended to keep this flag disabled.';
cy.get('.help-text').should('be.visible').and('have.text', contents);
// * Verify that Gossip Compression is set to true by default
cy.get('#EnableGossipCompressiontrue').should('have.attr', 'checked');
});
// # Disable Gossip Compression
cy.apiUpdateConfig({
ClusterSettings: {
Enable: true,
EnableGossipCompression: false,
},
});
cy.reload();
cy.findByTestId('EnableGossipCompression').scrollIntoView().should('be.visible').within(() => {
// * Verify that Gossip Compression is set to false
cy.get('#EnableGossipCompressionfalse').should('have.attr', 'checked');
});
});
});

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

@@ -0,0 +1,144 @@
// 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 @enterprise @system_console @compliance_export
import {verifyExportedMessagesCount, editLastPost} from './helpers';
describe('Compliance Export', () => {
let teamName;
before(() => {
cy.apiRequireLicenseForFeature('Compliance');
cy.apiUpdateConfig({
MessageExportSettings: {
ExportFormat: 'csv',
DownloadExportResults: true,
},
});
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
cy.apiLogin(sysadmin);
cy.apiInitSetup().then(({team}) => {
teamName = team.name;
});
// # Go to compliance page, enable export and do initial export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport();
cy.uiExportCompliance();
});
});
it('MM-T1177_1 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
// # Visit town-square channel
cy.visit(`/${teamName}/channels/town-square`);
// # Post messages
cy.postMessage('Testing one');
cy.postMessage('Testing two');
// # Edit last post
editLastPost('This is Edit Post');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 3 messages should be exported
verifyExportedMessagesCount('3');
});
it('MM-T1177_2 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
// # Visit town-square channel
cy.visit(`/${teamName}/channels/town-square`);
// # Post a Message
cy.postMessage('Testing');
// # Edit last post
editLastPost('This is Edit One');
// # Post a Message
cy.postMessage('This is Edit Two');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 3 messages should be exported
verifyExportedMessagesCount('3');
});
it('MM-T1177_3 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
// # Navigate to a team and post a message
cy.visit(`/${teamName}/channels/town-square`);
cy.postMessage('Testing');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Editing previously exported post
cy.visit(`/${teamName}/channels/town-square`);
editLastPost('This is Edit Three');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 2 messages should be exported
verifyExportedMessagesCount('2');
});
it('MM-T1177_4 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
// # Navigate to a team and post a Message
cy.visit(`/${teamName}/channels/town-square`);
cy.postMessage('Testing');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Editing previously exported post
cy.visit(`/${teamName}/channels/town-square`);
editLastPost('This is Edit Three');
// # Post new message
cy.postMessage('This is the post');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 3 messages should be exported
verifyExportedMessagesCount('3');
});
it('MM-T1177_5 - Compliance export should include updated posts after editing multiple times, exporting multiple times', () => {
// # Visit town-square channel
cy.visit(`/${teamName}/channels/town-square`);
// # Navigate to a team and post a message
cy.postMessage('Testing');
// # Editing previously exported post
editLastPost('This is Edit Four');
editLastPost('This is Edit Five');
// # Go to compliance page and export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 3 messages should be exported
verifyExportedMessagesCount('3');
});
});

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

@@ -0,0 +1,167 @@
// 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 @enterprise @system_console @compliance_export
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {verifyExportedMessagesCount, gotoTeamAndPostImage} from './helpers';
describe('Compliance Export', () => {
let teamName;
before(() => {
cy.apiRequireLicenseForFeature('Compliance');
cy.apiUpdateConfig({
MessageExportSettings: {
ExportFormat: 'csv',
DownloadExportResults: true,
},
});
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
cy.apiLogin(sysadmin);
cy.apiInitSetup().then(({team}) => {
teamName = team.name;
});
// # Go to compliance page, enable export and do initial export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport();
cy.uiExportCompliance();
});
});
it('MM-T3435 - Download Compliance Export Files - CSV Format', () => {
// # Navigate to a team and post an attachment
cy.visit(`/${teamName}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Get the first row
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
// # Get the download link
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
const fileURL = fileAttachment.attr('href');
// * Download and verify export file properties
cy.apiDownloadFileAndVerifyContentType(fileURL);
});
});
it('MM-T3438 - Download Compliance Export Files when 0 messages exported', () => {
// # Navigate to a team and post an attachment
cy.visit(`/${teamName}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Get the first row
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
// # Get the download link
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
const fileURL = fileAttachment.attr('href');
// * Download and verify export file properties
cy.apiDownloadFileAndVerifyContentType(fileURL);
// # Export compliance again
cy.uiExportCompliance();
// * Download link should not exist this time
cy.get('.job-table__table').
find('tbody > tr:eq(0)').
findByText('Download').should('not.exist');
});
});
it('MM-T1168 - Compliance Export - Run Now, entry appears in job table', () => {
// # Navigate to a team and post an attachment
cy.visit(`/${teamName}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Get the first row
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
// * Verify table header
cy.get('@firstheader').within(() => {
cy.get('th:eq(1)').should('have.text', 'Status');
cy.get('th:eq(2)').should('have.text', 'Files');
cy.get('th:eq(3)').should('have.text', 'Finish Time');
cy.get('th:eq(4)').should('have.text', 'Run Time');
cy.get('th:eq(5)').should('have.text', 'Details');
});
// * Verify first row (last run job) data
cy.get('@firstRow').within(() => {
cy.get('td:eq(1)').should('have.text', 'Success');
cy.get('td:eq(2)').should('have.text', 'Download');
cy.get('td:eq(4)').contains('seconds');
cy.get('td:eq(5)').should('have.text', '1 messages exported.');
});
});
it('MM-T1169 - Compliance Export - CSV and Global Relay', () => {
// # Navigate to a team and post an attachment
cy.visit(`/${teamName}/channels/town-square`);
gotoTeamAndPostImage();
// # Post 9 text messages
Cypress._.times(9, (i) => {
cy.postMessage(`This is the post ${i}`);
});
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// * 10 messages should be exported
verifyExportedMessagesCount('10');
});
it('MM-T1165 - Compliance Export - Fields disabled when disabled', () => {
// # Go to compliance page and disable export
cy.uiGoToCompliancePage();
cy.findByTestId('enableComplianceExportfalse').click();
// * Verify that exported button is disabled
cy.findByRole('button', {name: /run compliance export job now/i}).should('be.disabled');
});
it('MM-T1167 - Compliance Export job can be canceled', () => {
// # Go to compliance page and enable export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport();
// # Click the export job button
cy.findByRole('button', {name: /run compliance export job now/i}).click();
// # Click X button to cancel import
cy.findByTitle(/cancel/i, {timeout: TIMEOUTS.FIVE_SEC}).should('be.visible').click();
// # Get the first row
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
// * Canceled text should be shown in the first row of the table
cy.get('@firstRow').find('td:eq(1)').should('have.text', 'Canceled');
});
});

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

@@ -0,0 +1,306 @@
// 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 @enterprise @system_console
import {
gotoGlobalPolicy,
editGlobalPolicyMessageRetention,
runDataRetentionAndVerifyPostDeleted,
verifyPostNotDeleted,
} from './helpers';
describe('Data Retention - Global and Custom Policy Only', () => {
let testTeam;
let testChannel;
let users;
let channelA;
let channelB;
let channelC;
let newTeam;
const postText = 'This is testing';
before(() => {
cy.apiRequireLicenseForFeature('DataRetention');
cy.apiUpdateConfig({
ServiceSettings: {
EnableUserAccessTokens: true,
},
});
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
users = user.id;
});
});
beforeEach(() => {
cy.apiDeleteAllCustomRetentionPolicies();
cy.intercept({
method: 'POST',
url: '/api/v4/data_retention/policies',
}).as('createCustomPolicy');
// # Go to data retention settings
cy.uiGoToDataRetentionPage();
});
it('MM-T4093 - Assign Global Policy = 10 Days & Custom Policy = None to channel', () => {
gotoGlobalPolicy();
// # Edit global policy message retention
editGlobalPolicyMessageRetention('10', '10 days');
// * Verify there is no any team and channel assigned
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
});
let testChannel2;
cy.apiCreateChannel(testTeam.id, 'test_channel', 'testChannel2').then(({channel}) => {
testChannel2 = channel;
});
// # Create 13 days older post
// # Get Epoch value
const createDate = new Date().setDate(new Date().getDate() - 13);
const createDate2 = new Date().setDate(new Date().getDate() - 7);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDate2);
// * Run the job and verify 13 days older post has been deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 7 days older post is not deleted
verifyPostNotDeleted(testTeam, testChannel2, postText);
});
});
it('MM-T4099 - Assign Global Policy = 10 Days & Custom Policy = 5 days to Channels', () => {
// # Edit Global Policy to 10 days
gotoGlobalPolicy();
editGlobalPolicyMessageRetention('10', '10 days');
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
// # Create channel-A
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel-1').then(({channel}) => {
channelA = channel;
});
// # Create channel-B
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Custom-Channel1').then(({channel}) => {
channelB = channel;
});
// # Create channel-C
cy.apiCreateChannel(testTeam.id, 'channel-test', 'Global-Channel-2').then(({channel}) => {
channelC = channel;
});
// * Verify create policy api response
cy.wait('@createCustomPolicy').then((interception) => {
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
});
});
// # Create more than 3,7, and 12 days older post
// # Get Epoch value
const createDate1 = new Date().setDate(new Date().getDate() - 7);
const createDate2 = new Date().setDate(new Date().getDate() - 3);
const createDate3 = new Date().setDate(new Date().getDate() - 12);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate2);
cy.apiPostWithCreateDate(channelC.id, postText, token, createDate3);
// * Run the job and verify 7 days older post is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 7 days older post is not deleted
verifyPostNotDeleted(testTeam, channelA, postText);
// * Verify 3 days older post is not deleted
verifyPostNotDeleted(testTeam, channelB, postText);
// * Verify 12 days older post is deleted
verifyPostNotDeleted(testTeam, channelC, postText, 1);
});
});
it('MM-T4101 - Assign Global Policy = 5 days & Custom Policy = None to Teams', () => {
// # Edit global policy to 5 days
gotoGlobalPolicy();
editGlobalPolicyMessageRetention('5', '5 days');
// * Verify there is no any team and channel assigned
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
});
// # Create new channel
let testChannel2;
cy.apiCreateChannel(testTeam.id, 'channel-test', 'OtherChannel ').then(({channel}) => {
testChannel2 = channel;
});
// # Create new Team and Channel
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
newTeam = team;
channelA = channel;
});
});
// # Create 3 and 7 days older posts
// # Get Epoch value
const createDays1 = new Date().setDate(new Date().getDate() - 7);
const createDays2 = new Date().setDate(new Date().getDate() - 3);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDays1);
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDays1);
cy.apiPostWithCreateDate(channelA.id, postText, token, createDays2);
// * Run the job and verify 7 days older posts have been deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel2, postText);
// * Verify 3 days older post was not deleted
verifyPostNotDeleted(newTeam, channelA, postText);
});
});
it('MM-T4103 - Assign Global Policy = 10 days & Custom Policy = 5 days to Team', () => {
// # Edit global policy to 5 days
gotoGlobalPolicy();
editGlobalPolicyMessageRetention('10', '10 days');
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
});
});
// # Create channel-A
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel-1').then(({channel}) => {
channelA = channel;
});
// # Create a new Team and Channel
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
newTeam = team;
cy.apiCreateChannel(newTeam.id, 'test_channel', 'Channel-A').then(({channel}) => {
channelB = channel;
});
// # Create a new channel in newTeam
cy.apiCreateChannel(newTeam.id, 'channel-test', 'Global-Channel-2').then(({channel}) => {
channelC = channel;
});
});
// # Create more than 3,7, and 12 days older posts
// # Get Epoch value
const createDate1 = new Date().setDate(new Date().getDate() - 7);
const createDate2 = new Date().setDate(new Date().getDate() - 3);
const createDate3 = new Date().setDate(new Date().getDate() - 12);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate1);
cy.apiPostWithCreateDate(channelC.id, postText, token, createDate3);
// * Run the job and verify 7 days older post is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 7 days older post is not deleted
verifyPostNotDeleted(testTeam, channelA, postText);
// * Verify 3 days older post is not deleted
verifyPostNotDeleted(newTeam, channelB, postText);
// * Verify 12 days older post is deleted
verifyPostNotDeleted(newTeam, channelC, postText, 1);
});
});
it('MM-T4096 - Assign Global Policy = 1 Year & Custom Policy = None to channel', () => {
// # Edit global policy to 1 year
gotoGlobalPolicy();
editGlobalPolicyMessageRetention('365', '1 year');
// * Verify there is no any team and channel assigned
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.get('.DataGrid_rows .DataGrid_empty').first().should('contain.text', 'No items found');
});
// # Create a new channel
cy.apiCreateChannel(testTeam.id, 'channel-test', 'GlobalChannel ').then(({channel}) => {
channelA = channel;
});
// # Create less than one year and one year older post
// # Get Epoch value
const createDate1 = new Date().setMonth(new Date().getMonth() - 14);
const createDate2 = new Date().setMonth(new Date().getMonth() - 10);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate2);
// * Run the job and verify 1 year older post has been deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify less than one year post was not deleted
verifyPostNotDeleted(testTeam, channelA, postText);
});
});
});

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

@@ -0,0 +1,350 @@
// 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 @enterprise @system_console
import {
runDataRetentionAndVerifyPostDeleted,
gotoGlobalPolicy,
editGlobalPolicyMessageRetention,
verifyPostNotDeleted,
} from './helpers';
describe('Data Retention - Custom Policy Only', () => {
let testTeam;
let testChannel;
let users;
const postText = 'This is testing';
before(() => {
cy.apiRequireLicenseForFeature('DataRetention');
cy.apiUpdateConfig({
ServiceSettings: {
EnableUserAccessTokens: true,
},
});
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
users = user.id;
});
});
beforeEach(() => {
cy.apiDeleteAllCustomRetentionPolicies();
cy.intercept({
method: 'POST',
url: '/api/v4/data_retention/policies',
}).as('createCustomPolicy');
// # Go to data retention settings page
cy.uiGoToDataRetentionPage();
});
it('MM-T4097 - Assign Global Policy = Forever & Custom Policy = 10 days to Channel', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '10');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '10 days', '0 teams, 1 channel');
});
});
// # Create new Channel
let channelB;
cy.apiCreateChannel(testTeam.id, 'test_channel', 'channelB').then(({channel}) => {
channelB = channel;
});
// # Create 12 days older posts
// # Get Epoch value
const createDate = new Date().setDate(new Date().getDate() - 12);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
// * Run the job and verify 12 days older post is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 12 days older post is not deleted
verifyPostNotDeleted(testTeam, channelB, postText);
});
});
it('MM-T4098 - Assign Global Policy = Forever & Custom Policy = 1 year to Channels', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '365');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '1 year', '0 teams, 1 channel');
});
});
// # Create new Channel
let channelB;
cy.apiCreateChannel(testTeam.id, 'test_channel', ' channelB').then(({channel}) => {
channelB = channel;
});
// # Create more than one year older posts
// # Get Epoch value
const createDate = new Date().setMonth(new Date().getMonth() - 14);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
// * Run the job and verify more than one year older post is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify more than one year older post is not deleted
verifyPostNotDeleted(testTeam, channelB, postText);
});
});
it('MM-T4105 - Assign Global Policy = Forever & Custom Policy = 1 year to Teams', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '365');
// # Add a team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '1 year', '1 team, 0 channels');
});
});
// # Create new Team and Channel
let newTeam;
let channelB;
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
cy.apiCreateChannel(team.id, 'test_channel', 'channelB').then(({channel}) => {
newTeam = team;
channelB = channel;
});
});
// # Create more than one year older posts
// # Get Epoch value
const createDate = new Date().setMonth(new Date().getMonth() - 14);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
// * Run the job and verify more than one year older post has been deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify more then one year older post is not deleted
verifyPostNotDeleted(newTeam, channelB, postText);
});
});
it('MM-T4102 - Assign Global Policy = Forever & Custom Policy = 30 days to Teams', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '30');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '30 days', '1 team, 0 channels');
});
});
// # Create new Team and Channel
let channelB;
let newTeam;
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
cy.apiCreateChannel(team.id, 'test_channel', 'channelB').then(({channel}) => {
channelB = channel;
newTeam = team;
});
});
// # Create more than one year older post
// # Get Epoch value
const createDate = new Date().setDate(new Date().getDate() - 32);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate);
// * Run the job and verify 32 days older post is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 32 days old post is not deleted
verifyPostNotDeleted(newTeam, channelB, postText);
});
});
it('MM-T4104 - Assign Global policy = Forever & Custom Policy = 5 and 10 days to Teams', () => {
// # Create a new Channel
let testChannel2;
cy.apiCreateChannel(testTeam.id, 'test_channel', 'TestChannel2').then(({channel}) => {
testChannel2 = channel;
});
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '5');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '5 days', '1 team, 0 channels');
});
});
// # Create new Team and Channels
let newTeam;
let channelA;
let channelB;
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
newTeam = team;
// # Create new Channel
cy.apiCreateChannel(team.id, 'test_channel', 'test_channelC').then(({channel}) => {
channelB = channel;
});
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
channelA = channel;
// # Create second policy
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy1', 'days', '10');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([newTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy1', '10 days', '1 team, 0 channels');
});
});
});
});
// # Create more 3,7, and 12 days older posts
// # Get Epoch values
const createDate1 = new Date().setDate(new Date().getDate() - 7);
const createDate2 = new Date().setDate(new Date().getDate() - 3);
const createDate3 = new Date().setDate(new Date().getDate() - 12);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate1);
cy.apiPostWithCreateDate(testChannel2.id, postText, token, createDate2);
cy.apiPostWithCreateDate(channelA.id, postText, token, createDate3);
cy.apiPostWithCreateDate(channelB.id, postText, token, createDate2);
// * Run the job and Verify 7 days older post in testChannel is deleted
runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText);
// * Verify 3 days older post in testChennel2 is not deleted
verifyPostNotDeleted(testTeam, testChannel2, postText);
// * Verify 12 days older post in ChannelA is deleted
cy.visit(`/${newTeam.name}/channels/${channelA.name}`);
cy.findAllByTestId('postView').should('have.length', 1);
cy.findAllByTestId('postView').should('not.contain', postText);
// * Verify 3 days older post in channelB is not deleted
verifyPostNotDeleted(newTeam, channelB, postText);
});
});
it('MM-T4019 - Global Data Retention policy', () => {
[
{input: '365', result: '1 year'},
{input: '700', result: '700 days'},
{input: '730', result: '2 years'},
{input: '600', result: '600 days'},
].forEach(({input, result}) => {
gotoGlobalPolicy();
// # Edit global policy message retention
editGlobalPolicyMessageRetention(input, result);
});
});
});

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

@@ -0,0 +1,107 @@
// 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 @enterprise @system_console
import {
runDataRetentionAndVerifyPostDeleted,
gotoGlobalPolicy,
editGlobalPolicyMessageRetention,
} from './helpers';
describe('Data Retention - Global and Custom Policy', () => {
let testTeam;
let testChannel;
let users;
const postText = 'This is testing';
before(() => {
cy.apiRequireLicenseForFeature('DataRetention');
cy.apiUpdateConfig({
ServiceSettings: {
EnableUserAccessTokens: true,
},
});
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
users = user.id;
});
});
beforeEach(() => {
cy.apiDeleteAllCustomRetentionPolicies();
cy.intercept({
method: 'POST',
url: '/api/v4/data_retention/policies',
}).as('createCustomPolicy');
// # Go to data retention settings page
cy.uiGoToDataRetentionPage();
});
it('MM-T4100 - Assign Global Policy = 5 days & Custom Policy = 10 days to channels', () => {
let newChannel;
let newTeam;
// # Edit Global Policy to 5 days
gotoGlobalPolicy();
editGlobalPolicyMessageRetention('5', '5 days');
// # Create a new team
cy.apiCreateTeam('team', 'Team1').then(({team}) => {
cy.apiCreateChannel(team.id, 'test_channel', 'Channel-A').then(({channel}) => {
newChannel = channel;
newTeam = team;
});
});
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '10');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'MyPolicy', '10 days', '0 teams, 1 channel');
});
});
// # Create more than 7 days older post
// # Get Epoch value
const createDate = new Date().setDate(new Date().getDate() - 7);
cy.apiCreateToken(users).then(({token}) => {
// # Create posts
cy.apiPostWithCreateDate(newChannel.id, postText, token, createDate);
cy.apiPostWithCreateDate(testChannel.id, postText, token, createDate);
// * Run the job and verify 7 days older post in newChannel has been deleted
runDataRetentionAndVerifyPostDeleted(newTeam, newChannel, postText);
// * Verify 7 days older post in testChannel was not deleted
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
cy.findAllByTestId('postView').should('have.length', 2);
cy.findAllByTestId('postView').should('contain', postText);
});
});
});

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

@@ -0,0 +1,561 @@
// 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 @enterprise @system_console @with_feature_flag
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
describe('Data Retention', () => {
let testTeam;
let testChannel;
before(() => {
cy.apiRequireLicenseForFeature('DataRetention');
cy.apiInitSetup().then(({team, channel}) => {
testTeam = team;
testChannel = channel;
});
});
beforeEach(() => {
cy.apiDeleteAllCustomRetentionPolicies();
cy.intercept({
method: 'POST',
url: '/api/v4/data_retention/policies',
}).as('createCustomPolicy');
// # Go to data retention settings page
cy.uiGoToDataRetentionPage();
});
describe('Custom policy creation', () => {
it('MM-T4005 - Create custom policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Add 1 channel to the policy from the modal
cy.uiAddRandomChannelToCustomPolicy(1);
// # Save policy
cy.uiGetButton('Save').click();
// * Check custom policy table is visible
cy.get('#custom_policy_table .DataGrid').should('be.visible');
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy response
cy.uiVerifyPolicyResponse(interception.response.body, 1, 1, 60, 'Policy 1');
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(interception.response.body.id, 'Policy 1', '60 days', '1 team, 1 channel');
});
});
});
it('MM-T4006 - Policies count', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 2', 'days', '160');
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 3', 'days', '100');
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// * Assert the pagination is correct
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
cy.apiGetCustomRetentionPolicies().then((result) => {
// * Assert the total policy count is 3
expect(result.body.total_count).to.equal(3);
});
});
it('MM-T4007 - show policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'days', '60');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Add 1 channel to the policy from the modal
cy.uiAddRandomChannelToCustomPolicy(1);
// # Save policy
cy.uiGetButton('Save').click();
cy.findByText('1 - 1 of 1').scrollIntoView().should('be.visible');
});
it('MM-T4008 - Update custom policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 2', 'years', '2');
// # Add team to the policy
cy.uiAddRandomTeamToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// * Check custom policy table is visible
cy.get('#custom_policy_table .DataGrid').should('be.visible');
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 1, 0, 730, 'Policy 2');
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 2', '2 years', '1 team, 0 channels');
// # Go to edit custom data retention page
cy.uiClickEditCustomPolicyRow(policyId);
});
// * Verify custom policy page header
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// # Remove team from policy
cy.get('.PolicyTeamsList .DataGrid').within(() => {
cy.findByRole('link', {name: 'Remove'}).should('be.visible').click();
});
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// * Check custom policy table is visible
cy.get('#custom_policy_table .DataGrid').should('be.visible');
// * Verify custom policy data table
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 2', '2 years', '0 teams, 1 channel');
});
// # Send GET request to verify policy updated correctly
cy.apiGetCustomRetentionPolicy(policyId).then((result) => {
// * Assert response body team_count is 0
expect(result.body.team_count).to.equal(0);
// * Assert response body channel_count is 1
expect(result.body.channel_count).to.equal(1);
// * Assert response body post_duration is 730
expect(result.body.post_duration).to.equal(730);
// * Assert response body display_name is correct
expect(result.body.display_name).to.equal('Policy 2');
});
});
});
it('MM-T4009 - Delete a custom policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Add policy name
cy.uiGetTextbox('Policy name').clear().type('Policy 3');
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
// * Check custom policy table is visible
cy.get('#custom_policy_table .DataGrid').should('be.visible');
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 0, 1, -1, 'Policy 3');
const policyId = interception.response.body.id;
cy.get('#custom_policy_table .DataGrid').within(() => {
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 3', 'Keep forever', '0 teams, 1 channel');
cy.get(`#customWrapper-${policyId}`).trigger('mouseover').click();
// # Delete a policy
cy.findByRole('button', {name: 'Delete'}).should('be.visible').click();
// # Wait for deletion
cy.wait(TIMEOUTS.ONE_SEC);
// * Assert the policy row no longer exists
cy.get(`#customDescription-${policyId}`).should('not.exist');
});
});
});
});
describe('Teams in a custom Policy', () => {
it('MM-T4010 - Show policy teams information', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 1, 0, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '1 team, 0 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// * Verify Team data table exists
cy.get('.PolicyTeamsList .DataGrid').within(() => {
cy.get(`#team-name-${testTeam.id}`).should('be.visible');
});
// * GET the team for the policy and verify it is correct
cy.apiGetCustomRetentionPolicyTeams(policyId).then((result) => {
expect(result.body.teams[0].id).to.equal(testTeam.id);
});
});
});
it('MM-T4012 - Search teams in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Add channel to the policy
cy.uiAddRandomTeamToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 2, 0, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '2 teams, 0 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
cy.get('.PolicyTeamsList .DataGrid').within(() => {
// # Find the team table search box and type in team name
cy.findByRole('textbox').should('be.visible').clear().type(testTeam.name);
cy.wait(TIMEOUTS.ONE_SEC);
// * Verify the team is visible after search
cy.get(`#team-name-${testTeam.id}`).should('be.visible').invoke('text').should('include', testTeam.display_name);
});
// * Search the team for the policy using the API and verify it is correct
cy.apiSearchCustomRetentionPolicyTeams(policyId, testTeam.display_name).then((result) => {
expect(result.body[0].id).to.equal(testTeam.id);
});
});
});
it('MM-T4018 - Number of teams in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Add channels to the policy
cy.uiAddRandomTeamToCustomPolicy(2);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 3, 0, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '3 teams, 0 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// * Verify team table pagination
cy.get('.PolicyTeamsList .DataGrid').within(() => {
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
});
// * GET the teams for the policy and verify the count is correct
cy.apiGetCustomRetentionPolicyTeams(policyId).then((result) => {
expect(result.body.teams.length).to.equal(3);
});
});
});
it('MM-T4011 - Add team in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('MyPolicy', 'days', '60');
// # Add team to the policy
cy.uiAddTeamsToCustomPolicy([testTeam.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
// * Verify team table pagination
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.get('.DataGrid_rows .DataGrid_cell').first().should('contain.text', 'MyPolicy').click();
});
cy.get('.DataGrid_row .DataGrid_cell').first().should('contain', testTeam.display_name);
});
});
describe('Channels in a custom Policy', () => {
it('MM-T4017 - Total channels in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Add 2 channels to the policy from the modal
cy.uiAddRandomChannelToCustomPolicy(2);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 0, 3, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 3 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// * Verify Channel pagination
cy.get('.PolicyChannelsList .DataGrid').within(() => {
cy.findByText('1 - 3 of 3').scrollIntoView().should('be.visible');
});
// * GET the channels for the policy and verify the count
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
expect(result.body.channels.length).to.equal(3);
});
});
});
it('MM-T4014 - Add channel in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 0, 1, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 1 channel');
// * GET the channel for the policy and verify it is correct
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
expect(result.body.channels[0].id).to.equal(testChannel.id);
});
});
});
it('MM-T4015 - Delete channel in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '1');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Add 2 channels to the policy
cy.uiAddRandomChannelToCustomPolicy(2);
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 0, 3, 365, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '1 year', '0 teams, 3 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// # Remove channel from policy
cy.get('.PolicyChannelsList .DataGrid').within(() => {
cy.findAllByRole('link', {name: 'Remove'}).first().should('exist').click();
});
// # Save policy
cy.uiGetButton('Save').click();
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '1 year', '0 teams, 2 channels');
// * GET the channel for the policy and verify the count is correct
cy.apiGetCustomRetentionPolicyChannels(policyId).then((result) => {
expect(result.body.channels.length).to.equal(2);
});
});
});
it('MM-T4016 - Search channels in policy', () => {
// # Go to create custom data retention page
cy.uiClickCreatePolicy();
// # Fill out policy details
cy.uiFillOutCustomPolicyFields('Policy 1', 'years', '2');
// # Add channel to the policy
cy.uiAddChannelsToCustomPolicy([testChannel.display_name]);
// # Add channel to the policy
cy.uiAddRandomChannelToCustomPolicy();
// # Save policy
cy.uiGetButton('Save').click();
cy.wait('@createCustomPolicy').then((interception) => {
// * Verify create policy api response
cy.uiVerifyPolicyResponse(interception.response.body, 0, 2, 730, 'Policy 1');
const policyId = interception.response.body.id;
// * Verify custom policy data table
cy.uiVerifyCustomPolicyRow(policyId, 'Policy 1', '2 years', '0 teams, 2 channels');
// # Go to edit custom data retention page
cy.get('#custom_policy_table .DataGrid').within(() => {
cy.uiClickEditCustomPolicyRow(policyId);
});
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Custom Retention Policy');
// # Scroll down the custom policy form page
cy.get('.DataRetentionSettings .admin-console__wrapper').scrollTo('bottom');
cy.get('.PolicyChannelsList .DataGrid').within(() => {
// This will not type the space for display name?
cy.findByRole('textbox').should('be.visible').clear().type(testChannel.name);
cy.wait(TIMEOUTS.ONE_SEC);
cy.get(`#channel-name-${testChannel.id}`).should('be.visible').invoke('text').should('include', testChannel.display_name);
});
cy.apiSearchCustomRetentionPolicyChannels(policyId, testChannel.display_name).then((result) => {
expect(result.body[0].id).to.equal(testChannel.id);
});
});
});
});
});

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

@@ -0,0 +1,130 @@
// 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 @enterprise @system_console @compliance_export
import {
downloadAndUnzipExportFile,
verifyActianceXMLFile,
verifyPostsCSVFile,
} from './helpers';
describe('Compliance Export', () => {
const downloadsFolder = Cypress.config('downloadsFolder');
let newTeam;
let newChannel;
let botId;
let botName;
before(() => {
cy.apiRequireLicenseForFeature('Compliance');
cy.apiUpdateConfig({
MessageExportSettings: {
ExportFormat: 'csv',
DownloadExportResults: true,
},
ServiceSettings: {
EnforceMultifactorAuthentication: false,
},
});
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
cy.apiLogin(sysadmin);
//# Create a test bot
cy.apiCreateBot().then(({bot}) => {
({user_id: botId, display_name: botName} = bot);
cy.apiPatchUserRoles(bot.user_id, ['system_admin', 'system_user']);
});
cy.apiInitSetup().then(({team, channel}) => {
newTeam = team;
newChannel = channel;
// # Do initial export
exportCompliance();
});
});
});
after(() => {
cy.shellRm('-rf', downloadsFolder);
});
it('MM-T1175_1 - UserType identifies that the message is posted by a bot', () => {
const message = `This is CSV bot message from ${botName} at ${Date.now()}`;
// # Post bot message
postBotMessage(newTeam, newChannel, botId, message);
// # Go to Compliance page and run report
exportCompliance();
// # Download and Unzip exported file
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Export file should contain bot messages
verifyPostsCSVFile(
targetFolder,
'have.string',
`${message},message,bot`,
);
});
it('MM-T1175_2 - UserType identifies that the message is posted by a bot', () => {
const message = `This is XML bot message from ${botName} at ${Date.now()}`;
// # Post bot message
postBotMessage(newTeam, newChannel, botId, message);
// # Go to Compliance and enable run export
exportCompliance('Actiance XML');
// # Download and Unzip exported File
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Export file should message from bot
verifyActianceXMLFile(
targetFolder,
'have.string',
message,
);
verifyActianceXMLFile(
targetFolder,
'have.string',
'<UserType>bot</UserType>',
);
});
});
function postBotMessage(newTeam, newChannel, botId, message) {
cy.apiCreateToken(botId).then(({token}) => {
// # Logout to allow posting as bot
cy.apiLogout();
cy.apiCreatePost(newChannel.id, message, '', {attachments: [{pretext: 'Look some text', text: 'This is text'}]}, token);
// # Re-login to validate post presence
cy.apiAdminLogin();
cy.visit(`/${newTeam.name}/channels/${newChannel.name}`);
// * Validate post was created
cy.findByText(message).should('be.visible');
});
}
function exportCompliance(type) {
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport(type);
cy.uiExportCompliance();
}

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

@@ -0,0 +1,255 @@
// 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 @enterprise @system_console @compliance_export
import {
downloadAndUnzipExportFile,
editLastPost,
gotoTeamAndPostImage,
verifyActianceXMLFile,
verifyPostsCSVFile,
} from './helpers';
describe('Compliance Export', () => {
const ExportFormatActiance = 'Actiance XML';
const downloadsFolder = Cypress.config('downloadsFolder');
let newTeam;
let newUser;
let newChannel;
let adminUser;
before(() => {
cy.apiRequireLicenseForFeature('Compliance');
cy.apiUpdateConfig({
MessageExportSettings: {
ExportFormat: 'csv',
DownloadExportResults: true,
},
});
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
adminUser = sysadmin;
cy.apiLogin(adminUser);
cy.apiInitSetup().then(({team, user, channel}) => {
newTeam = team;
newUser = user;
newChannel = channel;
});
});
});
after(() => {
cy.shellRm('-rf', downloadsFolder);
});
it('MM-T1172 - Compliance Export - Deleted file is indicated in CSV File Export', () => {
// # Go to compliance page and enable export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport();
// # Navigate to a team and post an attachment
cy.visit(`/${newTeam.name}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Deleting last post
deleteLastPost();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Download and extract export zip file
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying if export file contains delete
verifyPostsCSVFile(
targetFolder,
'have.string',
'deleted attachment',
);
});
it('MM-T1173 - Compliance Export - Deleted file is indicated in Actiance XML File Export', () => {
// # Go to compliance page and enable export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport(ExportFormatActiance);
// # Navigate to a team and post an attachment
cy.visit(`/${newTeam.name}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Delete last post
deleteLastPost();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Download and extract exported zip file
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying if export file contains deleted image
verifyActianceXMLFile(
targetFolder,
'have.string',
'delete file uploaded-image-400x400.jpg',
);
// * Verifying if image has been downloaded
cy.shellFind(targetFolder, /image-400x400.jpg/).then((files) => {
expect(files.length).not.to.equal(0);
});
});
it('MM-T1176 - Compliance export should include updated post after editing', () => {
// # Go to compliance page and enable export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport(ExportFormatActiance);
// # Navigate to a team and post a message
cy.visit(`/${newTeam.name}/channels/town-square`);
cy.postMessage('Testing');
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Visit town-square channel and edit the last post
cy.visit(`/${newTeam.name}/channels/town-square`);
editLastPost('Hello');
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Download and extract exported zip file
const targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying if export file contains edited text
verifyActianceXMLFile(
targetFolder,
'have.string',
'<Content>Hello</Content>',
);
});
it('MM-T3305 - Verify Deactivated users are displayed properly in Compliance Exports', () => {
// # Post a message by Admin
cy.postMessageAs({
sender: adminUser,
message: `@${newUser.username} : Admin 1`,
channelId: newChannel.id,
});
cy.visit(`/${newTeam.name}/channels/${newChannel.id}`);
// # Deactivate the newly created user
cy.apiDeactivateUser(newUser.id);
// # Go to compliance page and enable export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport(ExportFormatActiance);
cy.uiExportCompliance();
// # Download and extract exported zip file
let targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying if export file contains deactivated user info
verifyActianceXMLFile(
targetFolder,
'have.string',
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
);
// # Post a message by Admin
cy.postMessageAs({
sender: adminUser,
message: `@${newUser.username} : Admin2`,
channelId: newChannel.id,
});
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Download and extract exported zip file
targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying export file should not contain deactivated user name
verifyActianceXMLFile(
targetFolder,
'not.have.string',
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
);
// # Re-activate the user
cy.apiActivateUser(newUser.id);
// # Post a message by Admin
cy.postMessageAs({
sender: adminUser,
message: `@${newUser.username} : Admin3`,
channelId: newChannel.id,
});
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Download and extract exported zip file
targetFolder = `${downloadsFolder}/${Date.now().toString()}`;
downloadAndUnzipExportFile(targetFolder);
// * Verifying if export file contains deactivated user name
verifyActianceXMLFile(
targetFolder,
'have.string',
`<LoginName>${newUser.username}@sample.mattermost.com</LoginName>`,
);
});
});
function deleteLastPost() {
cy.apiGetTeamsForUser().then(({teams}) => {
const team = teams[0];
cy.visit(`/${team.name}/channels/town-square`);
cy.getLastPostId().then((lastPostId) => {
// # Click post dot menu in center.
cy.clickPostDotMenu(lastPostId);
// # Scan inside the post menu dropdown
cy.get(`#CENTER_dropdown_${lastPostId}`).should('exist').within(() => {
// # Click on the delete post button from the dropdown
cy.findByText('Delete').should('exist').click();
});
});
cy.get('.a11y__modal.modal-dialog').should('exist').and('be.visible').
within(() => {
// # Confirm click on the delete button for the post
cy.findByText('Delete').should('be.visible').click();
});
});
}

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

@@ -0,0 +1,186 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import path from 'path';
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
export function downloadAndUnzipExportFile(targetFolder = '') {
// # Get the download link
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
// # Getting export file url
const fileURL = fileAttachment.attr('href');
const targetFilePath = path.join(targetFolder);
const zipFile = targetFilePath + '.zip';
// # Download zip file
cy.request({url: fileURL, encoding: 'binary'}).then((response) => {
expect(response.status).to.equal(200);
cy.writeFile(zipFile, response.body, 'binary');
});
// # Unzip exported file then "csv_export.zip"
cy.shellUnzip(zipFile, targetFilePath);
cy.shellFind(targetFilePath, /csv_export.zip/).then((files) => {
cy.shellUnzip(files[files.length - 1], targetFilePath);
});
});
}
export function verifyPostsCSVFile(targetFolder, type, match) {
cy.readFile(`${targetFolder}/posts.csv`).
should('exist').
and(type, match);
}
export function verifyActianceXMLFile(targetFolder, type, match) {
cy.shellFind(targetFolder, /actiance_export.xml/).
then((files) => {
cy.readFile(files[files.length - 1]).
should('exist').
and(type, match);
});
}
export function verifyExportedMessagesCount(expectedNumber) {
// * Verifying number of exported messages
cy.get('@firstRow').find('td:eq(5)').should('have.text', `${expectedNumber} messages exported.`);
}
export function editLastPost(message) {
cy.getLastPostId().then(() => {
cy.uiGetPostTextBox().clear().type('{uparrow}');
// # Edit Post Input should appear
cy.get('#edit_textbox').should('be.visible');
// # Update the post message and type ENTER
cy.get('#edit_textbox').invoke('val', '').type(message).type('{enter}').wait(TIMEOUTS.HALF_SEC);
// * Edit modal should not be visible
cy.get('#edit_textbox').should('not.exist');
});
}
export function gotoTeamAndPostImage() {
cy.uiGetPostTextBox().then((createPostEl) => {
if (createPostEl.find('.file-preview__container').length === 1) {
// # Remove images from post message footer if exist
cy.waitUntil(() => cy.uiGetFileUploadPreview().then((filePreviewEl) => {
if (filePreviewEl.find('.post-image.normal').length > 0) {
cy.get('.file-preview__remove > .icon').click();
}
return filePreviewEl.find('.post-image.normal').length === 0;
}));
}
const file = {
filename: 'image-400x400.jpg',
originalSize: {width: 400, height: 400},
thumbnailSize: {width: 400, height: 400},
};
cy.get('#fileUploadInput').attachFile(file.filename);
// # Wait until the image is uploaded
cy.uiWaitForFileUploadPreview();
cy.postMessage(`file uploaded-${file.filename}`);
});
}
export function gotoGlobalPolicy() {
// # Click edit on global policy data table
cy.get('#global_policy_table .DataGrid .MenuWrapper').trigger('mouseover').click();
cy.findByRole('button', {name: /edit/i}).should('be.visible').click();
cy.get('.DataRetentionSettings .admin-console__header', {timeout: TIMEOUTS.TWO_MIN}).should('be.visible').invoke('text').should('include', 'Global Retention Policy');
}
export function editGlobalPolicyMessageRetention(input, result) {
cy.get('.DataRetentionSettings #global_direct_message_dropdown #DropdownInput_channel_message_retention').as('dropDown');
// * Checking if Global Policy is already created
cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/data_retention/policy',
method: 'GET',
}).then((response) => {
expect(response.status).to.equal(200);
if (response.body.message_deletion_enabled === true) {
// # Click message retention dropdown and select 'Keep forever' option
cy.get('@dropDown').click();
cy.get('.channel_message_retention_dropdown__menu .channel_message_retention_dropdown__option span.option_forever').should('be.visible').click();
}
});
// # Click message retention dropdown and select 'Days' option
cy.get('@dropDown').click();
cy.get('.channel_message_retention_dropdown__menu .channel_message_retention_dropdown__option span.option_days').should('be.visible').click();
// # Input retention days
cy.get('.DataRetentionSettings #global_direct_message_dropdown input#channel_message_retention_input').clear().type(input);
// # Save Global Policy
cy.findByRole('button', {name: 'Save'}).should('be.visible').click();
// * Assert global policy data table is visible
cy.get('#global_policy_table .DataGrid').should('be.visible');
// * Assert global policy message retention is correct
cy.findByTestId('global_message_retention_cell').within(() => {
cy.get('span').should('have.text', result);
});
}
export function editGlobalPolicyFileRetention(input, result) {
// # Click file retention dropdown
cy.get('.DataRetentionSettings #global_file_dropdown #DropdownInput_file_retention').should('be.visible').click();
// # Select days from file retention dropdown
cy.get('.file_retention_dropdown__menu .file_retention_dropdown__option span.option_days').should('be.visible').click();
// # Input retention days
cy.get('.DataRetentionSettings #global_file_dropdown input#file_retention_input').clear().type(input);
// # Save Global Policy
cy.findByRole('button', {name: 'Save'}).should('be.visible').click();
// * Assert global policy data table is visible
cy.get('#global_policy_table .DataGrid').should('be.visible');
// * Assert global policy file retention is correct
cy.findByTestId('global_file_retention_cell').within(() => {
cy.get('span').should('have.text', result);
});
}
export function runDataRetentionAndVerifyPostDeleted(testTeam, testChannel, postText) {
cy.uiGoToDataRetentionPage();
cy.findByRole('button', {name: 'Run Deletion Job Now'}).click();
// # Small wait to ensure new row is add
cy.wait(TIMEOUTS.FIVE_SEC);
// # Waiting for Data Retention process to finish
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
cy.get('@firstRow').within(() => {
cy.get('td:eq(1)', {timeout: TIMEOUTS.FOUR_MIN}).should('have.text', 'Success');
});
// * Verifying if post has been deleted
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
cy.reload();
cy.findAllByTestId('postView').should('have.length', 1);
cy.findAllByTestId('postView').should('not.contain', postText);
}
export function verifyPostNotDeleted(testTeam, testChannel, postText, expectedNoOfPosts = 2) {
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
cy.findAllByTestId('postView').should('have.length', expectedNoOfPosts);
if (expectedNoOfPosts === 2) {
cy.findAllByTestId('postView').should('contain', postText);
} else {
cy.findAllByTestId('postView').should('not.contain', postText);
}
}

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

@@ -0,0 +1,94 @@
// 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 @enterprise @system_console @compliance_export @not_cloud
// Requires "mattermost-minio" docker instance to be accessible at http://localhost:9000
// and a bucket named "mattermost-test". Bucket can be created manually in the UI or by:
// ``docker exec mattermost-minio sh -c 'mkdir -p /data/mattermost-test'``
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {gotoTeamAndPostImage} from './helpers';
describe('Compliance Export', () => {
let teamName;
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.apiRequireLicenseForFeature('Compliance');
cy.apiUpdateConfig({
MessageExportSettings: {
ExportFormat: 'csv',
DownloadExportResults: true,
},
});
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
cy.apiLogin(sysadmin);
cy.apiInitSetup().then(({team}) => {
teamName = team.name;
});
// # Go to compliance page, enable export and do export
cy.uiGoToCompliancePage();
cy.uiEnableComplianceExport();
cy.uiExportCompliance();
});
});
it('MM-T3439 - Download Compliance Export Files - S3 Bucket Storage', () => {
// # Go to file storage settings Page
cy.visit('/admin_console/environment/file_storage');
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').and('have.text', 'File Storage');
const {
minioAccessKey,
minioSecretKey,
minioS3Bucket,
minioS3Endpoint,
minioS3SSL,
} = Cypress.env();
// # Update S3 Storage settings
cy.findByTestId('FileSettings.DriverNamedropdown').select('amazons3');
cy.findByTestId('FileSettings.AmazonS3Bucketinput').clear().type(minioS3Bucket);
cy.findByTestId('FileSettings.AmazonS3AccessKeyIdinput').clear().type(minioAccessKey);
cy.findByTestId('FileSettings.AmazonS3SecretAccessKeyinput').clear().type(minioSecretKey);
cy.findByTestId('FileSettings.AmazonS3Endpointinput').clear().type(minioS3Endpoint);
cy.findByTestId(`FileSettings.AmazonS3SSL${minioS3SSL}`).check();
// # Save file storage settings
cy.uiSaveConfig();
// # Test connection and verify that it's successful
cy.findByRole('button', {name: 'Test Connection'}).click();
cy.findByText('Connection was successful').should('be.visible');
// # Navigate to a team and post an attachment
cy.visit(`/${teamName}/channels/town-square`);
gotoTeamAndPostImage();
// # Go to compliance page and start export
cy.uiGoToCompliancePage();
cy.uiExportCompliance();
// # Get the first row
cy.get('.job-table__table').find('tbody > tr').eq(0).as('firstRow');
// # Get the download link
cy.get('@firstRow').findByText('Download').parents('a').should('exist').then((fileAttachment) => {
const fileURL = fileAttachment.attr('href');
// * Download link should not exist this time
cy.apiDownloadFileAndVerifyContentType(fileURL);
});
});
});

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

@@ -0,0 +1,39 @@
// 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 @system_console @enterprise @not_cloud
import {FixedPublicLinks} from '../../../../utils';
describe('Edition and License', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
// * Check if server has license
cy.apiRequireLicense();
// # Go to admin console
cy.visit('/admin_console');
});
it('MM-T899 - Edition and License: Verify Privacy Policy link points to correct URL', () => {
// * Find text and verify its corresponding public link
[
{text: 'Privacy Policy', link: FixedPublicLinks.PrivacyPolicy},
{text: 'Enterprise Edition Terms of Use', link: FixedPublicLinks.TermsOfService},
].forEach(({text, link}) => {
cy.findByText(text).
scrollIntoView().
should('be.visible').
and('have.attr', 'href').
and('include', link);
});
});
});

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

@@ -0,0 +1,58 @@
// 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 @enterprise @not_cloud
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Environment', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.apiInitSetup();
});
it('MM-T994 - Fields editable when enabled, but not saveable until validated', () => {
// * Check if server has license for Elasticsearch
cy.apiRequireLicenseForFeature('Elasticsearch');
cy.visit('/admin_console/environment/elasticsearch');
// * Verify the ElasticSearch fields are disabled
cy.findByTestId('connectionUrlinput').should('be.disabled');
cy.findByTestId('skipTLSVerificationfalse').should('be.disabled');
cy.findByTestId('usernameinput').should('be.disabled');
cy.findByTestId('passwordinput').should('be.disabled');
cy.findByTestId('snifftrue').should('be.disabled');
cy.findByTestId('snifffalse').should('be.disabled');
cy.findByTestId('enableSearchingtrue').should('be.disabled');
cy.findByTestId('enableSearchingfalse').should('be.disabled');
cy.findByTestId('enableAutocompletetrue').should('be.disabled');
cy.findByTestId('enableAutocompletefalse').should('be.disabled');
cy.visit('/admin_console/environment/elasticsearch');
// # Enable Elasticsearch
cy.findByTestId('enableIndexingtrue').check();
// * Verify the ElasticSearch fields are enabled
cy.findByTestId('connectionUrlinput').should('not.be.disabled');
cy.findByTestId('skipTLSVerificationfalse').should('not.be.disabled');
cy.findByTestId('usernameinput').should('not.be.disabled');
cy.findByTestId('passwordinput').should('not.be.disabled');
cy.findByTestId('snifftrue').should('not.be.disabled');
cy.findByTestId('snifffalse').should('not.be.disabled');
cy.get('.sidebar-section').first().click();
// * Verify the behavior when Yes, Discard button in the confirmation message is clicked
cy.get('#confirmModalButton').should('be.visible').and('have.text', 'Yes, Discard').click().wait(TIMEOUTS.HALF_SEC);
cy.get('.confirmModal').should('not.exist');
});
});

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

@@ -0,0 +1,567 @@
// 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 @enterprise @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('group configuration', () => {
let groupID;
let testTeam;
let testChannel;
before(() => {
cy.apiRequireLicenseForFeature('LDAP');
cy.apiInitSetup({teamPrefix: {name: 'aaa-test', displayName: 'AAA Test'}}).then(({team, channel}) => {
testTeam = team;
testChannel = channel;
});
});
beforeEach(() => {
// # Link a group
cy.apiGetLDAPGroups().then((result) => {
cy.apiLinkGroup(result.body.groups[0].primary_key).then((linkGroupRes) => {
groupID = linkGroupRes.body.id;
// # Unlink group teams and channels
cy.apiGetGroupTeams(groupID).then((response) => {
response.body.forEach((item) => {
cy.apiUnlinkGroupTeam(groupID, item.team_id);
});
});
cy.apiGetGroupChannels(groupID).then((response) => {
response.body.forEach((item) => {
cy.apiUnlinkGroupChannel(groupID, item.channel_id);
});
});
// # Go to the group configuration view of the linked group
cy.visit(`/admin_console/user_management/groups/${groupID}`);
cy.get('#adminConsoleWrapper', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').
find('.admin-console__header').should('have.text', 'Group Configuration');
// * Check that it has no associated teams or channels
verifyNoTeamsOrChannelsIsVisible();
});
});
});
describe('adding a team', () => {
it('does not add a team without saving', () => {
addGroupSyncable('team', () => {
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team that was added dissappears
verifyNoTeamsOrChannelsIsVisible();
});
});
it('does add a team when saved', () => {
addGroupSyncable('team', (teamName) => {
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Test that the team persisted
teamOrChannelIsPresent(teamName);
// * Ensure that server error is blank
cy.get('.error-message').should('be.empty');
});
});
});
describe('adding a channel', () => {
it('shows default channels', () => {
// # Search for off-topic
cy.get('#add_team_or_channel').should('be.visible').click();
cy.get('.dropdown-menu').find('#add_channel').should('be.visible').click();
cy.get('#selectItems input').typeWithForce('off-');
// * Check that the off-topic channels are displayed
cy.get('.more-modal__details').should('have.length.greaterThan', 1);
cy.findByText(`(${testTeam.display_name})`).should('exist');
});
it('does not add a channel without saving', () => {
addGroupSyncable('channel', () => {
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel that was added dissappears
verifyNoTeamsOrChannelsIsVisible();
});
});
it('does add a channel when saved', () => {
addGroupSyncable('channel', (channelName) => {
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Test that the team persisted
teamOrChannelIsPresent(channelName);
// * Ensure that server error is blank
cy.get('.error-message').should('be.empty');
});
});
});
describe('removing a team', () => {
it('does not remove a team without saving', () => {
cy.apiGetTeamsForUser().then(({teams}) => {
// # Link a team
const team = teams[0];
cy.apiLinkGroupTeam(groupID, team.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team was added to the view
teamOrChannelIsPresent(team.display_name);
// # Click remove and confirm
removeAndConfirm(team.display_name);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team is still visible
teamOrChannelIsPresent(team.display_name);
});
});
it('does remove a team when saved', () => {
cy.apiGetTeamsForUser().then(({teams}) => {
// # Link a team
const team = teams[0];
cy.apiLinkGroupTeam(groupID, team.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team was added to the view
teamOrChannelIsPresent(team.display_name);
// # Click remove and confirm
removeAndConfirm(team.display_name);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team is no longer present
verifyNoTeamsOrChannelsIsVisible();
});
});
});
describe('removing a channel', () => {
it('does not remove a channel without saving', () => {
// # Link a channel
cy.apiLinkGroupChannel(groupID, testChannel.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel was added to the view
teamOrChannelIsPresent(testChannel.display_name);
// # Click remove
cy.findByTestId(`${testChannel.display_name}_groupsyncable_remove`).click();
cy.get('#confirmModalButton').should('be.visible').click();
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team is still visible
teamOrChannelIsPresent(testChannel.display_name);
});
it('does remove a channel when saved', () => {
// # Link a channel
cy.apiLinkGroupChannel(groupID, testChannel.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel was added to the view
teamOrChannelIsPresent(testChannel.display_name);
cy.get('.group-teams-and-channels-row', {timeout: TIMEOUTS.ONE_MIN}).not('.has-children').should('have.length', 2);
// # Click remove
cy.findByTestId(`${testChannel.display_name}_groupsyncable_remove`).click();
cy.get('#confirmModalButton').should('be.visible').click();
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel is no longer present
cy.get('.group-teams-and-channels-row', {timeout: TIMEOUTS.ONE_MIN}).scrollIntoView().should('have.length', 1);
});
});
describe('updating a team role', () => {
it('updates the role for a new team', () => {
// # Add a new team
addGroupSyncable('team', (teamName) => {
// # Update the role
const newRole = 'Team Admin';
changeRole(teamName, newRole);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(teamName, newRole);
});
});
it('updates the role for an existing team', () => {
// # Link a team
cy.apiLinkGroupTeam(groupID, testTeam.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team was added to the view
teamOrChannelIsPresent(testTeam.display_name);
// # Change the role
const newRole = 'Team Admin';
changeRole(testTeam.display_name, newRole);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(testTeam.display_name, newRole);
});
it('does not update the role if not saved', () => {
// # Link a team
cy.apiLinkGroupTeam(groupID, testTeam.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team was added to the view
teamOrChannelIsPresent(testTeam.display_name);
// # Change the role
changeRole(testTeam.display_name, 'Team Admin');
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(testTeam.display_name, 'Member');
});
it('does not update the role of a removed team', () => {
// # Link a team
cy.apiLinkGroupTeam(groupID, testTeam.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the team was added to the view
teamOrChannelIsPresent(testTeam.display_name);
// # Change the role
changeRole(testTeam.display_name, 'Team Admin');
removeAndConfirm(testTeam.display_name);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save settings
savePage();
// * Check the groupteam via the API to ensure its role wasn't updated
cy.apiGetGroupTeam(groupID, testTeam.id).then(({body}) => {
expect(body.scheme_admin).to.eq(false);
});
});
});
describe('updating a channel role', () => {
it('updates the role for a new channel', () => {
// # Add a new channel
addGroupSyncable('channel', (channelName) => {
// # Update the role
const newRole = 'Channel Admin';
changeRole(channelName, newRole);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save the settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(channelName, newRole);
});
});
it('updates the role for an existing channel', () => {
// # Link a channel
cy.apiLinkGroupChannel(groupID, testChannel.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel was added to the view
teamOrChannelIsPresent(testChannel.display_name);
// # Change the role
const newRole = 'Channel Admin';
changeRole(testChannel.display_name, newRole);
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save settings
savePage();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(testChannel.display_name, newRole);
});
it('does not update the role if not saved', () => {
// # Link a channel
cy.apiLinkGroupChannel(groupID, testChannel.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel was added to the view
teamOrChannelIsPresent(testChannel.display_name);
// # Change the role
changeRole(testChannel.display_name, 'Channel Admin');
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Ensure the new role is visible
verifyNewRoleIsVisible(testChannel.display_name, 'Member');
});
it('does not update the role of a removed channel', () => {
// # Link a channel
cy.apiLinkGroupChannel(groupID, testChannel.id);
// # Reload the page
cy.visit(`/admin_console/user_management/groups/${groupID}`);
// * Check that the channel was added to the view
teamOrChannelIsPresent(testChannel.display_name);
// # Change the role
changeRole(testChannel.display_name, 'Channel Admin');
cy.findByTestId(`${testChannel.display_name}_groupsyncable_remove`).click();
cy.get('#confirmModalButton').should('be.visible').click();
// # Click away
cy.get('.sidebar-section').first().click();
// * Ensure that discard warning appears
cy.get('.discard-changes-modal').should('be.visible');
// # Cancel navigating away
cy.get('#cancelModalButton').click();
// # Save settings
savePage();
// * Check the groupteam via the API to ensure its role wasn't updated
cy.apiGetGroupChannel(groupID, testChannel.id).then(({body}) => {
expect(body.scheme_admin).to.eq(false);
});
});
});
});
function teamOrChannelIsPresent(name) {
cy.get('.group-teams-and-channels--body', {timeout: TIMEOUTS.ONE_MIN}).scrollIntoView().should('be.visible').within(() => {
cy.findByText(name).scrollIntoView().should('be.visible');
});
}
function addGroupSyncable(type, callback) {
cy.get('#add_team_or_channel', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').click();
cy.get('.dropdown-menu').find(`#add_${type}`).should('be.visible').click();
cy.get(`.${type}-selector-modal`).should('be.visible');
cy.get('#multiSelectList').find('.more-modal__row').find(type === 'channel' ? '.channel-name' : '.title').then(($elements) => {
const name = $elements[0].innerText;
cy.get('#multiSelectList').find('.more-modal__row').first().click();
cy.get('#saveItems').click();
// * Check that the team or channel was added to the view
teamOrChannelIsPresent(name);
callback(name);
});
}
function changeRole(teamOrChannel, newRole) {
cy.findByTestId(`${teamOrChannel}_current_role`, {timeout: TIMEOUTS.ONE_MIN}).click();
cy.get('.Menu__content').should('be.visible').findByText(newRole).click();
}
function savePage() {
cy.get('#saveSetting', {timeout: TIMEOUTS.TWO_SEC}).click();
cy.get('#saveSetting', {timeout: TIMEOUTS.TWO_SEC}).should('be.disabled');
}
function removeAndConfirm(name) {
cy.findByTestId(`${name}_groupsyncable_remove`, {timeout: TIMEOUTS.ONE_MIN}).click();
cy.get('#confirmModalButton').should('be.visible').click();
verifyNoTeamsOrChannelsIsVisible();
}
function verifyNewRoleIsVisible(teamOrChannel, newRole) {
cy.findByTestId(`${teamOrChannel}_current_role`, {timeout: TIMEOUTS.ONE_MIN}).scrollIntoView().should('be.visible').findByText(newRole).should('be.visible');
}
function verifyNoTeamsOrChannelsIsVisible() {
cy.findByText('No teams or channels specified yet', {timeout: TIMEOUTS.ONE_MIN}).scrollIntoView().should('be.visible');
}

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

@@ -0,0 +1,94 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import accessRules from '../../../../fixtures/system-roles-console-access';
import disabledTests from '../../../../fixtures/console-example-inputs';
import * as TIMEOUTS from '../../../../fixtures/timeouts';
function noAccessFunc(section) {
// * If it's a no-access permission, we just need to check that the section doesn't exist in the side bar
cy.findByTestId(section).should('not.exist');
}
function readOnlyFunc(section) {
// * If it's a read only permission, we need to make sure that the section does exist in the sidebar however the inputs in that section is disabled (read only)
cy.findByTestId(section).should('exist');
checkInputsShould('be.disabled', section);
}
function readWriteFunc(section) {
// * If we have read + write (can edit) permissions, we need to make the section exists and also that the inputs are all enabled
cy.findByTestId(section).should('exist');
checkInputsShould('be.enabled', section);
}
function checkInputsShould(shouldString, section) {
const {disabledInputs} = disabledTests.find((item) => item.section === section);
Cypress._.forEach(disabledInputs, ({path, selector}) => {
if (path.length && selector.length) {
cy.visit(path, {timeout: TIMEOUTS.HALF_MIN});
cy.findByTestId(selector, {timeout: TIMEOUTS.ONE_MIN}).should(shouldString);
}
});
}
export function makeUserASystemRole(testUsers, role) {
// # Login as each new role.
cy.apiAdminLogin();
// # Go the system console.
cy.visit('/admin_console/user_management/system_roles');
cy.get('.admin-console__header').within(() => {
cy.findByText('System Roles', {timeout: TIMEOUTS.ONE_MIN}).should('exist').and('be.visible');
});
// # Click on edit for the role
cy.findByTestId(`${role}_edit`).click();
// # Click Add People button
cy.findByRole('button', {name: 'Add People'}).click().wait(TIMEOUTS.HALF_SEC);
// # Type in user name
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(`${testUsers[role].email}`);
// # Find the user and click on him
cy.get('#multiSelectList').should('be.visible').children().first().click({force: true});
// # Click add button
cy.findByRole('button', {name: 'Add'}).click().wait(TIMEOUTS.HALF_SEC);
// # Click save button
cy.findByRole('button', {name: 'Save'}).click().wait(TIMEOUTS.HALF_SEC);
}
export function forEachConsoleSection(testUsers, roleName) {
const ACCESS_NONE = 'none';
const ACCESS_READ_ONLY = 'read';
const ACCESS_READ_WRITE = 'read+write';
const user = testUsers[roleName];
// # Login as each new role.
cy.apiLogin(user);
// # Go the system console.
cy.visit('/admin_console');
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
accessRules.forEach((rule) => {
const {section} = rule;
const access = rule[roleName];
switch (access) {
case ACCESS_NONE:
noAccessFunc(section);
break;
case ACCESS_READ_ONLY:
readOnlyFunc(section);
break;
case ACCESS_READ_WRITE:
readWriteFunc(section);
break;
}
});
}

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

@@ -0,0 +1,48 @@
// 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 @enterprise @system_console @not_cloud
import {forEachConsoleSection, makeUserASystemRole} from './helpers';
describe('Limited console access', () => {
const roleNames = ['system_manager', 'system_user_manager', 'system_read_only_admin'];
const testUsers = {};
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.apiRequireLicense();
Cypress._.forEach(roleNames, (roleName) => {
cy.apiCreateUser().then(({user}) => {
testUsers[roleName] = user;
});
});
});
it('MM-T3386 - Verify the Admin Role - System Manager -- KNOWN ISSUE: MM-42573', () => {
const role = 'system_manager';
// # Make the user a System Manager
makeUserASystemRole(testUsers, role);
// * Login as the new user and verify the role permissions (ensure they really are a system manager)
forEachConsoleSection(testUsers, role);
});
it('MM-T3388 - Verify the Admin Role - System Read Only Admin -- KNOWN ISSUE: MM-42573', () => {
const role = 'system_read_only_admin';
// # Make the user a System Ready Only Manager
makeUserASystemRole(testUsers, role);
// * Login as the new user and verify the role permissions (ensure they really are a system read only manager)
forEachConsoleSection(testUsers, role);
});
});

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

@@ -0,0 +1,38 @@
// 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 @enterprise @system_console
import {forEachConsoleSection, makeUserASystemRole} from './helpers';
describe('Limited console access', () => {
const roleNames = ['system_manager', 'system_user_manager', 'system_read_only_admin'];
const testUsers = {};
before(() => {
cy.apiRequireLicense();
Cypress._.forEach(roleNames, (roleName) => {
cy.apiCreateUser().then(({user}) => {
testUsers[roleName] = user;
});
});
});
it('MM-T3387 - Verify the Admin Role - System User Manager', () => {
const role = 'system_user_manager';
// # Make the user a System User Manager
makeUserASystemRole(testUsers, role);
// * Login as the new user and verify the role permissions (ensure they really are a system user manager)
forEachConsoleSection(testUsers, role);
});
});

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

@@ -0,0 +1,52 @@
// 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 @enterprise @system_console
describe('Main menu', () => {
before(() => {
// * Check if server has license
cy.apiRequireLicense();
// # Go to admin console
cy.visit('/admin_console');
// # Open the hamburger menu
cy.get('button > span[class="menu-icon"]').click();
});
it('MM-T913 About opens About modal', () => {
// # click to open about modal
cy.findByText('About Mattermost').click();
// * Verify server link text has correct link destination and opens in a new tab
verifyLink('server', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
// * Verify link text has correct link destination and opens in a new tab
verifyLink('desktop', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
// * Verify link text has correct matches link destination and opens in a new tab
verifyLink('mobile', 'https://github.com/mattermost/mattermost-mobile/blob/master/NOTICE.txt');
// * Verify version exists in modal
cy.findByText('Mattermost Version:').should('be.visible');
// * Verify licensed to exists in modal
cy.findByText('Licensed to:').should('be.visible');
});
});
const verifyLink = (text, link) => {
// * Verify link opens in new tab
cy.get('a[href="' + link + '"]').scrollIntoView().should('have.attr', 'target', '_blank');
// * Verify link text matches correct href value
cy.get('a[href="' + link + '"]').contains(text);
};

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

@@ -0,0 +1,156 @@
// 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 @enterprise @system_console
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {hexToRgbArray, rgbArrayToString} from '../../../../../utils';
describe('System Console OpenId Connect', () => {
const FAKE_SETTING = '********************************';
const SERVICE_PROVIDER_LABEL = 'Select service provider:';
const DISCOVERY_ENDPOINT_LABEL = 'Discovery Endpoint:';
const CLIENT_ID_LABEL = 'Client ID:';
const CLIENT_SECRET_LABEL = 'Client Secret:';
const OPENID_LINK_NAME = 'OpenID Connect';
const SAVE_BUTTON_NAME = 'Save';
before(() => {
// * Check if server has license
cy.apiRequireLicense();
});
beforeEach(() => {
// # Go to the System Scheme page as System Admin
cy.apiAdminLogin();
cy.visit('/admin_console');
});
it('MM-T3623 - Set to Generic OpenId', () => {
cy.findByRole('link', {name: OPENID_LINK_NAME}).click();
// # Click the OpenId header dropdown
cy.wait(TIMEOUTS.FIVE_SEC);
cy.findByLabelText(SERVICE_PROVIDER_LABEL).select('openid').wait(TIMEOUTS.ONE_SEC);
cy.findByLabelText('Button Name:').clear().type('TestButtonTest');
cy.get('#OpenIdSettings\\.ButtonColor-inputColorValue').clear().type('#c02222');
cy.findByLabelText(DISCOVERY_ENDPOINT_LABEL).clear().type('http://test.com/.well-known/openid-configuration');
cy.findByLabelText(CLIENT_ID_LABEL).clear().type('OpenIdId');
cy.findByLabelText(CLIENT_SECRET_LABEL).clear().type('OpenIdSecret');
cy.findByRole('button', {name: SAVE_BUTTON_NAME}).click().wait(TIMEOUTS.ONE_SEC);
// * Get config from API
cy.apiGetConfig().then(({config}) => {
expect(config.OpenIdSettings.Secret).to.equal(FAKE_SETTING);
expect(config.OpenIdSettings.Id).to.equal('OpenIdId');
expect(config.OpenIdSettings.DiscoveryEndpoint).to.equal('http://test.com/.well-known/openid-configuration');
});
verifyOAuthLogin('TestButtonTest', '#c02222', Cypress.config('baseUrl') + '/oauth/openid/login');
});
it('MM-T3620 - Set to Google OpenId', () => {
cy.findByRole('link', {name: OPENID_LINK_NAME}).click();
// # Click the OpenId header dropdown
cy.wait(TIMEOUTS.FIVE_SEC);
cy.findByLabelText(SERVICE_PROVIDER_LABEL).select('google').wait(TIMEOUTS.ONE_SEC);
cy.findByLabelText(CLIENT_ID_LABEL).clear().type('GoogleId');
cy.findByLabelText(CLIENT_SECRET_LABEL).clear().type('GoogleSecret');
cy.findByRole('button', {name: SAVE_BUTTON_NAME}).click().wait(TIMEOUTS.ONE_SEC);
// * Get config from API
cy.apiGetConfig().then(({config}) => {
expect(config.GoogleSettings.Secret).to.equal(FAKE_SETTING);
expect(config.GoogleSettings.Id).to.equal('GoogleId');
expect(config.GoogleSettings.DiscoveryEndpoint).to.equal('https://accounts.google.com/.well-known/openid-configuration');
});
verifyOAuthLogin('Google', '', Cypress.config('baseUrl') + '/oauth/google/login');
});
it('MM-T3621 - Set to Gitlab OpenId', () => {
cy.findByRole('link', {name: OPENID_LINK_NAME}).click();
// # Click the OpenId header dropdown
cy.wait(TIMEOUTS.FIVE_SEC);
cy.findByLabelText(SERVICE_PROVIDER_LABEL).select('gitlab').wait(TIMEOUTS.ONE_SEC);
cy.findByLabelText('GitLab Site URL:').clear().type('https://gitlab.com');
cy.findByLabelText(CLIENT_ID_LABEL).clear().type('GitlabId');
cy.findByLabelText(CLIENT_SECRET_LABEL).clear().type('GitlabSecret');
cy.findByRole('button', {name: SAVE_BUTTON_NAME}).click().wait(TIMEOUTS.ONE_SEC);
// * Get config from API
cy.apiGetConfig().then(({config}) => {
expect(config.GitLabSettings.Secret).to.equal(FAKE_SETTING);
expect(config.GitLabSettings.Id).to.equal('GitlabId');
expect(config.GitLabSettings.DiscoveryEndpoint).to.equal('https://gitlab.com/.well-known/openid-configuration');
});
verifyOAuthLogin('GitLab', '', Cypress.config('baseUrl') + '/oauth/gitlab/login');
});
it('MM-T3622 - Set to Exchange OpenId', () => {
cy.findByRole('link', {name: OPENID_LINK_NAME}).click();
// # Click the OpenId header dropdown
cy.wait(TIMEOUTS.FIVE_SEC);
cy.findByLabelText(SERVICE_PROVIDER_LABEL).select('office365').wait(TIMEOUTS.ONE_SEC);
cy.findByLabelText('Directory (tenant) ID:').clear().type('common');
cy.findByLabelText(CLIENT_ID_LABEL).clear().type('Office365Id');
cy.findByLabelText(CLIENT_SECRET_LABEL).clear().type('Office365Secret');
cy.findByRole('button', {name: SAVE_BUTTON_NAME}).click().wait(TIMEOUTS.ONE_SEC);
// * Get config from API
cy.apiGetConfig().then(({config}) => {
expect(config.Office365Settings.Secret).to.equal(FAKE_SETTING);
expect(config.Office365Settings.Id).to.equal('Office365Id');
expect(config.Office365Settings.DiscoveryEndpoint).to.equal('https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration');
});
verifyOAuthLogin('Office 365', '', Cypress.config('baseUrl') + '/oauth/office365/login');
});
});
const verifyOAuthLogin = (text, color, href) => {
cy.uiOpenSystemConsoleMainMenu('Log Out');
cy.waitUntil(() => cy.url().then((url) => {
return url.includes('/login');
}));
cy.url().then((url) => {
const withExtra = url.includes('?extra=expired') ? '?extra=expired' : '';
// * Verify oauth login link
cy.get('.external-login-button').then((btn) => {
expect(btn.prop('href')).equal(`${href}${withExtra}`);
if (color) {
const rbgArr = hexToRgbArray(color);
expect(btn[0].style.color).equal(rgbArrayToString(rbgArr));
expect(btn[0].style.borderColor).equal(rgbArrayToString(rbgArr));
}
cy.get('.external-login-button-label').should('contain', text);
});
});
};

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

@@ -0,0 +1,194 @@
// 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 @enterprise @system_console
import * as TIMEOUTS from '../../../../../fixtures/timeouts';
import {getAdminAccount} from '../../../../../support/env';
describe('System Console > Site Statistics', () => {
let testTeam;
const statDataTestIds = [
'totalActiveUsers',
'totalTeams',
'totalChannels',
'totalPosts',
'totalSessions',
'totalCommands',
'incomingWebhooks',
'outgoingWebhooks',
'dailyActiveUsers',
'monthlyActiveUsers',
'websocketConns',
'masterDbConns',
'replicaDbConns'];
const titleTestIds = [
'totalActiveUsersTitle',
'totalTeamsTitle',
'totalChannelsTitle',
'totalPostsTitle',
'totalSessionsTitle',
'totalCommandsTitle',
'incomingWebhooksTitle',
'outgoingWebhooksTitle',
'dailyActiveUsersTitle',
'monthlyActiveUsersTitle',
'websocketConnsTitle',
'masterDbConnsTitle',
'replicaDbConnsTitle'];
before(() => {
// * Check if server has license
cy.apiRequireLicense();
});
afterEach(() => {
// # Reset locale
cy.apiPatchMe({locale: 'en'});
});
it('MM-T904 Site Statistics displays expected content categories', () => {
cy.intercept('**/api/v4/**').as('resources');
// # Visit site statistics page.
cy.visit('/admin_console/reporting/system_analytics');
cy.wait('@resources');
// * Check that the header has loaded correctly and contains the expected text.
cy.get('.admin-console__header span', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible').should('contain', 'System Statistics');
cy.wait(TIMEOUTS.ONE_SEC).waitUntil(() => cy.get('body').then((el) => {
return !el[0].innerText.includes('Loading');
}, {
timeout: TIMEOUTS.ONE_MIN,
interval: TIMEOUTS.FIVE_SEC,
errorMsg: 'Timeout error waiting "Loading..." indicator message to disappear',
}));
// * Check that the rows for the table were generated.
cy.get('.admin-console__content .row').should('have.length', 4);
// * Check that the title content for the stats is as expected.
cy.findByTestId('totalActiveUsersTitle').should('contain', 'Total Active Users');
// cy.findByTestId('seatPurchasedTitle').should('contain', 'Total paid users');
cy.findByTestId('totalTeamsTitle').should('contain', 'Total Teams');
cy.findByTestId('totalChannelsTitle').should('contain', 'Total Channels');
cy.findByTestId('totalPostsTitle').should('contain', 'Total Posts');
cy.findByTestId('totalSessionsTitle').should('contain', 'Total Sessions');
cy.findByTestId('totalCommandsTitle').should('contain', 'Total Commands');
cy.findByTestId('incomingWebhooksTitle').should('contain', 'Incoming Webhooks');
cy.findByTestId('outgoingWebhooksTitle').should('contain', 'Outgoing Webhooks');
cy.findByTestId('dailyActiveUsersTitle').should('contain', 'Daily Active Users');
cy.findByTestId('monthlyActiveUsersTitle').should('contain', 'Monthly Active Users');
cy.findByTestId('websocketConnsTitle').should('contain', 'WebSocket Conns');
cy.findByTestId('masterDbConnsTitle').should('contain', 'Master DB Conns');
cy.findByTestId('replicaDbConnsTitle').should('contain', 'Replica DB Conns');
statDataTestIds.forEach((locator) => {
cy.findByTestId(locator).invoke('text').then(parseFloat).should('be.gte', 0);
});
});
it('MM-T902 - Reporting ➜ Site statistics line graphs show same date', () => {
cy.intercept('**/api/v4/**').as('resources');
const sysadmin = getAdminAccount();
let newChannel;
// # Create and visit new channel
cy.apiInitSetup().then(({channel}) => {
newChannel = channel;
});
// # Create a bot and get userID
cy.apiCreateBot().then(({bot}) => {
const botUserId = bot.user_id;
cy.externalRequest({user: sysadmin, method: 'put', path: `users/${botUserId}/roles`, data: {roles: 'system_user system_post_all system_admin'}});
// # Get token from bots id
cy.apiAccessToken(botUserId, 'Create token').then(({token}) => {
//# Add bot to team
cy.apiAddUserToTeam(newChannel.team_id, botUserId);
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
// # Post message as bot to the new channel
cy.postBotMessage({token, channelId: newChannel.id, message: 'this is bot message', createAt: yesterday.getTime()}).then(() => {
cy.visit('/admin_console');
cy.wait('@resources');
// * Find site statistics and click it
cy.findByTestId('reporting.system_analytics', {timeout: TIMEOUTS.ONE_MIN}).click();
let totalPostsDataSet;
let totalPostsFromBots;
let activeUsersWithPosts;
// # Grab all data from the 3 charts from there data labels
cy.findByTestId('totalPostsLineChart').then((el) => {
totalPostsDataSet = el[0].dataset.labels;
cy.findByTestId('totalPostsFromBotsLineChart').then((el2) => {
totalPostsFromBots = el2[0].dataset.labels;
cy.findByTestId('activeUsersWithPostsLineChart').then((el3) => {
activeUsersWithPosts = el3[0].dataset.labels;
// * Assert that all the dates are the same
expect(totalPostsDataSet).equal(totalPostsFromBots);
expect(totalPostsDataSet).equal(activeUsersWithPosts);
expect(totalPostsFromBots).equal(activeUsersWithPosts);
});
});
});
});
});
});
});
it('MM-T905 - Site Statistics card labels in different languages', () => {
cy.apiInitSetup().then(({team}) => {
testTeam = team;
// # Login as admin and set the language to french
cy.apiAdminLogin();
cy.visit(`/${testTeam.name}/channels/off-topic`);
cy.uiOpenSettingsModal('Display').then(() => {
cy.findByText('Language').click();
cy.get('#displayLanguage').click();
cy.findByText('Français (Beta)').click();
cy.uiSave();
});
// * Once in site statistics, check and make sure the boxes are truncated or not according to image on test
cy.visit('/admin_console/reporting/system_analytics');
titleTestIds.forEach((id) => {
let expectedResult = false;
if (id === 'totalCommandsTitle' || id === 'masterDbConnsTitle' || id === 'replicaDbConnsTitle') {
expectedResult = true;
}
cy.findByTestId(id, {timeout: TIMEOUTS.ONE_MIN}).then((el) => {
const titleSpan = el[0].childNodes[0];
// * All the boxes on System Statistics page should have UNTRUNCATED titles when in french except Total Commands, Master DB Conns, and Replica DB Conns.
// * The following asserts if the they are truncated or not. If false, it means they are not truncated. If true, they are truncated.
expect(titleSpan.scrollWidth > titleSpan.clientWidth).equal(expectedResult);
});
});
});
});
});

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

@@ -0,0 +1,61 @@
// 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 @enterprise @not_cloud @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('System console', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
// * Check if server has license
cy.apiRequireLicense();
});
it('MM-T897_1 - Focus should be in System Console search box on opening System Console or refreshing pages in System Console', () => {
const pageIds = ['reporting\\/system_analytics', 'reporting\\/team_statistics', 'reporting\\/server_logs', 'user_management\\/users', 'user_management\\/teams'];
cy.visit('/admin_console');
// * Assert the ID of the element is the ID of admin sidebar filter
cy.focused().should('have.id', 'adminSidebarFilter');
cy.wait(TIMEOUTS.ONE_SEC);
pageIds.forEach((id) => {
// # Go to another page
cy.get(`#${id}`).click();
// * Ensure focus is lost
cy.focused().should('not.have.id', 'adminSidebarFilter');
// * Reload and ensure the focus is back on the search component
cy.reload();
cy.focused().should('have.id', 'adminSidebarFilter');
cy.wait(TIMEOUTS.ONE_SEC);
});
});
it('MM-T897_2 - System Console menu footer should not cut off at the bottom', () => {
cy.visit('/admin_console');
// * Scroll to the last item of the page and ensure it can be clicked
cy.findByTestId('experimental.bleve').scrollIntoView().click();
});
it('MM-T1634 - Search box should remain visible / in the header as you scroll down the settings list in the left-hand-side', () => {
cy.visit('/admin_console');
// * Scroll to bottom of left hand side
cy.findByTestId('experimental.bleve').scrollIntoView().click();
// * To check if the sidebar is in view, try to click it
cy.get('#adminSidebarFilter').should('be.visible').click();
});
});

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

@@ -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 @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Settings', () => {
before(() => {
cy.apiRequireLicense();
});
it('MM-T1181 Compliance and Auditing: Run a report, it appears in the job table', () => {
cy.visit('/admin_console/compliance/monitoring');
// # Enable compliance reporting
cy.findByTestId('ComplianceSettings.Enabletrue').click();
cy.findByTestId('saveSetting').should('be.enabled').click().wait(TIMEOUTS.HALF_SEC);
// # Fill up the boxes
cy.get('#desc').clear().type('sample report');
const now = new Date();
cy.get('#to').clear().type(now.toLocaleDateString());
now.setDate(now.getDate() - 1);
cy.get('#from').clear().type(now.toLocaleDateString());
// # Run compliance reports
cy.get('#run-button').click().wait(TIMEOUTS.HALF_SEC);
cy.findByText('Reload Completed Compliance Reports').click().wait(TIMEOUTS.HALF_SEC);
// * Ensure that reports appear
cy.get('.compliance-panel__table tbody').children().should('have.length.greaterThan', 0);
// * Ensure that the report is correct
cy.get('.compliance-panel__table tbody tr').first().should('contain.text', 'Download');
cy.get('.compliance-panel__table tbody tr').first().should('contain.text', 'sample report');
});
it('MM-T1635 Channel listing is displayed correctly with proper team name', () => {
let teamName;
cy.visit('/admin_console/user_management/channels');
// # Get the team name
cy.get('#channels .DataGrid .DataGrid_rows > :nth-child(1)').
within(() => {
cy.get('.DataGrid_cell:nth-of-type(2)').
invoke('text').
then((name) => {
teamName = name;
// # Click on the channel
return cy.get('.DataGrid_cell').first().click();
});
}).then(() => {
// * Confirm that the team name is same
cy.get('#channel_profile .channel-team').should('have.text', 'Team' + teamName);
});
});
});

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

@@ -0,0 +1,76 @@
// 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 @system_console @enterprise @cloud_only
import * as TIMEOUTS from '../../../../fixtures/timeouts';
import {adminConsoleNavigation} from '../../../../utils/admin_console';
describe('System Console - Cloud', () => {
before(() => {
// * Check if server has license for Cloud
cy.apiRequireLicenseForFeature('Cloud');
const newSettings = {
ExperimentalSettings: {
RestrictSystemAdmin: true,
},
};
cy.apiUpdateConfig(newSettings);
// # Go to system admin then verify admin console URL and header
cy.visit('/admin_console');
cy.url().should('include', '/admin_console/billing/subscription');
cy.get('.admin-console__header', {timeout: TIMEOUTS.HALF_MIN}).
should('be.visible').
and('have.text', 'Subscription');
});
const serverType = 'cloud_enterprise';
adminConsoleNavigation.forEach((testCase, index) => {
const canNavigate = testCase.type.includes(serverType);
const testTitle = `MM-T4264_${index + 1} ${canNavigate ? 'can' : 'cannot'} navigate to ${testCase.header}`;
const testFn = canNavigate ? verifyCanNavigate : verifyCannotNavigate;
it(testTitle, () => {
testFn(testCase);
});
});
});
function verifyCanNavigate(testCase) {
// # Click the link on the sidebar
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
findByText(testCase.sidebar).
scrollIntoView().
should('be.visible').
click();
// * Verify that it redirects to the URL and matches with the header
cy.url().should('include', testCase.url);
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
and(testCase.headerContains ? 'contain' : 'have.text', testCase.header);
}
function verifyCannotNavigate(testCase) {
// # Header should not exist in sidebar
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
findByText(testCase.sidebar).
should('not.exist');
// # Visit the URL directly
cy.visit(testCase.url);
// * Verify that it redirects to Subscription page
cy.url().should('include', '/admin_console/billing/subscription');
}

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

@@ -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 @enterprise @e20_only @not_cloud @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
import {adminConsoleNavigation} from '../../../../utils/admin_console';
describe('System Console - Enterprise', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
// * Check if server has license
cy.apiRequireLicense();
// # Go to system admin then verify admin console URL and header
cy.visit('/admin_console/about/license');
cy.url().should('include', '/admin_console/about/license');
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
and('have.text', 'Edition and License');
});
const serverType = 'e20';
adminConsoleNavigation.forEach((testCase, index) => {
const canNavigate = testCase.type.includes(serverType);
const testTitle = `MM-T4262_${index + 1} ${canNavigate ? 'can' : 'cannot'} navigate to ${testCase.header}`;
const testFn = canNavigate ? verifyCanNavigate : verifyCannotNavigate;
it(testTitle, () => {
testFn(testCase);
});
});
});
function verifyCanNavigate(testCase) {
// # Click the link on the sidebar
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
findByText(testCase.sidebar).
scrollIntoView().
should('be.visible').
click();
// * Verify that it redirects to the URL and matches with the header
cy.url().should('include', testCase.url);
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
and(testCase.headerContains ? 'contain' : 'have.text', testCase.header);
}
function verifyCannotNavigate(testCase) {
// # Header should not exist in sidebar
cy.get('.admin-sidebar', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
findByText(testCase.sidebar).
should('not.exist');
// # Visit the URL directly
cy.visit(testCase.url);
// * Verify that it redirects to Edition and License page
cy.url().should('include', '/admin_console/about/license');
}

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

@@ -0,0 +1,48 @@
// 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 @not_cloud @enterprise @system_console
describe('Support Packet Generation', () => {
before(() => {
cy.apiRequireLicense();
});
it('MM-T3849 - Commercial Support Dialog UI - E10/E20 License', () => {
// # Go to System Console
cy.visit('/admin_console');
goToSupportPacketGenerationModal();
cy.get('.AlertBanner__body').should('have.text', 'Before downloading the support packet, set Output Logs to File to true and set File Log Level to DEBUG here.');
});
it('MM-T3818 - Commercial Support Dialog UI - Links', () => {
// # Go to System Console
cy.visit('/admin_console');
goToSupportPacketGenerationModal();
// * Verify that the "submit a support ticket." link exist and points to Customer Support Request page
cy.findByRole('link', {name: 'submit a support ticket.'}).should('have.attr', 'href').and('include', 'https://support.mattermost.com/hc/en-us/requests/new');
// * Verify that the "here" link exist and points to Logging admin page
cy.findByRole('link', {name: 'here'}).should('have.attr', 'href').and('include', '/admin_console/environment/logging');
});
});
const goToSupportPacketGenerationModal = () => {
// # Open system menu and click Customer Support
cy.findByRole('button', {name: 'Menu Icon'}).should('exist').click();
cy.findByRole('button', {name: 'Commercial Support dialog'}).click();
// * Ensure the download support packet button exist and that text regarding setting the proper settings exist
cy.findByRole('link', {name: 'Download Support Packet'}).should('exist');
};

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

@@ -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 @enterprise @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('System Scheme', () => {
before(() => {
cy.apiRequireLicense();
});
beforeEach(() => {
cy.apiResetRoles();
// # Go to `User Management / Permissions` section
cy.visit('/admin_console/user_management/permissions');
});
it('MM-T2862 Default permissions set inherited from system scheme', () => {
// # Click on `Edit Scheme` under `System Scheme`
cy.findByTestId('systemScheme-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Make a few scheme changes
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').should('have.class', 'checked').click();
cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('have.class', 'checked').click();
cy.findByTestId('all_users-teams-invite_guest-checkbox').should('not.have.class', 'checked').click();
// # Save scheme
cy.get('#saveSetting').click().wait(TIMEOUTS.TWO_SEC);
// # Go back to the `Permission Schemes` page
cy.visit('/admin_console/user_management/permissions');
// # Click `New Team Override Scheme`
cy.findByTestId('team-override-schemes-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// * Verify scheme settings modified earlier are reflected in this section
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').should('not.have.class', 'checked');
cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('not.have.class', 'checked');
cy.findByTestId('all_users-teams_team_scope-invite_guest-checkbox').should('have.class', 'checked');
});
it('MM-T2863 Reset system scheme defaults will revert permissions to defaults', () => {
// # Click on `Edit Scheme` under `System Scheme`
cy.findByTestId('systemScheme-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Click on `Reset to defaults`
cy.findByTestId('resetPermissionsToDefault').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Confirm the dialog
cy.get('#confirmModalButton').click().wait(TIMEOUTS.TWO_SEC);
// # Make a few changes to the scheme
cy.findByTestId('guests-guest_create_private_channel-checkbox').should('not.have.class', 'checked').click();
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').should('have.class', 'checked').click();
cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('have.class', 'checked').click();
// # Save changes
cy.get('#saveSetting').click().wait(TIMEOUTS.HALF_SEC);
// # Go back to the `Permission Schemes` page
cy.visit('/admin_console/user_management/permissions');
// # Click on `Edit Scheme` under `System Scheme`
cy.findByTestId('systemScheme-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// * Verify previous scheme changes have been saved
cy.findByTestId('guests-guest_create_private_channel-checkbox').should('have.class', 'checked');
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').should('not.have.class', 'checked');
cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('not.have.class', 'checked');
// # Click on `Reset to defaults`
cy.findByTestId('resetPermissionsToDefault').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Confirm the dialog
cy.get('#confirmModalButton').click().wait(TIMEOUTS.HALF_SEC);
// # Save changes
cy.get('#saveSetting').click().wait(TIMEOUTS.TWO_SEC);
// # Reload the page
cy.reload();
// * Verify scheme settings have been reset to defaults
cy.findByTestId('guests-guest_create_private_channel-checkbox').should('not.have.class', 'checked');
cy.findByTestId('all_users-public_channel-create_public_channel-checkbox').should('have.class', 'checked');
cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('have.class', 'checked');
});
});

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

@@ -0,0 +1,261 @@
// 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 @enterprise @system_console
import {getAdminAccount} from '../../../../support/env';
describe('System Scheme Channel Mentions Permissions Test', () => {
let testUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
testUser = user;
testTeam = team;
testChannel = channel;
});
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiResetRoles();
});
it('MM-23018 - Enable and Disable Channel Mentions', () => {
checkChannelPermission(
'use_channel_mentions',
() => channelMentionsPermissionCheck(true),
() => channelMentionsPermissionCheck(false),
testUser,
testTeam,
testChannel,
);
});
it('MM-24379 - Enable and Disable Create Post', () => {
checkChannelPermission(
'create_post',
() => createPostPermissionCheck(true),
() => createPostPermissionCheck(false),
testUser,
testTeam,
testChannel,
);
});
});
const setUserTeamAndChannelMemberships = (user, team, channel, channelAdmin = false, teamAdmin = false) => {
const admin = getAdminAccount();
// # Set user as regular system user
cy.externalRequest({user: admin, method: 'put', path: `users/${user.id}/roles`, data: {roles: 'system_user'}});
// # Get team membership
cy.externalRequest({user: admin, method: 'put', path: `teams/${team.id}/members/${user.id}/schemeRoles`, data: {scheme_user: true, scheme_admin: teamAdmin}});
// # Get channel membership
cy.externalRequest({user: admin, method: 'put', path: `channels/${channel.id}/members/${user.id}/schemeRoles`, data: {scheme_user: true, scheme_admin: channelAdmin}});
};
const saveConfig = () => {
cy.get('#saveSetting').click();
cy.waitUntil(() => cy.get('#saveSetting').then((el) => {
return el[0].innerText === 'Save';
}));
};
const enablePermission = (permissionCheckBoxTestId) => {
cy.findByTestId(permissionCheckBoxTestId).then((el) => {
if (!el.hasClass('checked')) {
el.click();
}
});
};
const removePermission = (permissionCheckBoxTestId) => {
cy.findByTestId(permissionCheckBoxTestId).then((el) => {
if (el.hasClass('checked')) {
el.click();
}
});
};
// # Checks to see if user recieved a system message warning after using @here
// # If enabled is true assumes the user has the permission enabled and checks for no system message
const channelMentionsPermissionCheck = (enabled) => {
// # Type @here and post it to the channel
cy.postMessage('@here ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
if (enabled) {
// * Assert that the last message posted is not a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('not.include.text', 'Channel notifications are disabled');
} else {
cy.uiWaitUntilMessagePostedIncludes('Channel notifications are disabled');
// * Assert that the last message posted is the system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', 'Channel notifications are disabled');
}
});
};
// # Checks to see if the post input is enabled or disalbed and that the API
// accepts or rejects the create post request.
const createPostPermissionCheck = (enabled) => {
if (enabled) {
// # Try post it to the channel
cy.uiGetPostTextBox().and('not.be.disabled');
cy.postMessage('test');
} else {
// # Ensure the input is disabled
cy.uiGetPostTextBox().and('be.disabled');
}
// # Get last post message text
cy.getLastPostId().then((postId) => {
if (enabled) {
// * Assert that the last message posted is not a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', 'test');
}
});
};
const resetPermissionsToDefault = () => {
// # Login as sysadmin and navigate to system scheme page
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
// # Click reset to defaults and confirm
cy.findByTestId('resetPermissionsToDefault').click();
cy.get('#confirmModalButton').click();
// # Save
saveConfig();
};
const checkChannelPermission = (permissionName, hasChannelPermissionCheckFunc, notHasChannelPermissionCheckFunc, testUser, testTeam, testChannel) => {
const guestsTestId = `guests-guest_${permissionName}-checkbox`;
const usersTestId = `all_users-posts-${permissionName}-checkbox`;
const channelTestId = `channel_admin-posts-${permissionName}-checkbox`;
const teamTestId = `team_admin-posts-${permissionName}-checkbox`;
const testIds = [guestsTestId, usersTestId, channelTestId, teamTestId];
const channelUrl = `/${testTeam.name}/channels/${testChannel.name}`;
// # Setup user as a regular channel member and team member
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel);
// * Ensure user can use channel mentions by default
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Go to system permissions scheme page as sysadmin
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
// * Ensure permission is enabled at each scope by default
testIds.forEach((testId) => {
cy.findByTestId(testId).should('have.class', 'checked');
});
// # Remove permission from guests and save
removePermission(guestsTestId);
saveConfig();
// * Ensure that the permission removed is now removed
cy.findByTestId(guestsTestId).should('not.have.class', 'checked');
// # Remove permission from all users and save
removePermission(usersTestId);
saveConfig();
// * Ensure that the permission is not removed from all roles except All Members
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
cy.findByTestId(channelTestId).should('have.class', 'checked');
cy.findByTestId(teamTestId).should('have.class', 'checked');
// # Remove permission for channel admins and save
removePermission(channelTestId);
saveConfig();
// * Ensure that the permission is removed from all roles except team admins
cy.findByTestId(teamTestId).should('have.class', 'checked');
cy.findByTestId(channelTestId).should('not.have.class', 'checked');
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
// # Enable permission for channel admins and save
enablePermission(channelTestId);
saveConfig();
// * Ensure that the permission is only removed from regular users
cy.findByTestId(teamTestId).should('have.class', 'checked');
cy.findByTestId(channelTestId).should('have.class', 'checked');
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
// # Setup user as a regular channel member
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel);
// * Ensure user cannot use channel mentions
cy.apiLogin(testUser);
cy.visit(channelUrl);
notHasChannelPermissionCheckFunc();
// # Setup user as a channel admin
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel, true, false);
// * Ensure user can use channel mentions as channel admin
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Navigate back to system scheme as sysadmin and remove permission from channel admins
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
removePermission(channelTestId);
saveConfig();
// # Log back in as regular user
cy.apiLogin(testUser);
cy.visit(channelUrl);
// * Ensure user cannot use channel mentions as channel admin
notHasChannelPermissionCheckFunc();
// # Setup user as a team admin
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel, true, true);
// * Ensure user can use channel mentions as team admin
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Navigate back to system scheme as sysadmin and remove permission from team admins
cy.apiAdminLogin();
cy.visit('/admin_console/user_management/permissions/system_scheme');
removePermission(teamTestId);
saveConfig();
// # Log back in as regular user
cy.apiLogin(testUser);
cy.visit(channelUrl);
// * Ensure user cannot use channel mentions as team admin
notHasChannelPermissionCheckFunc();
// # Reset permissions back to defaults
resetPermissionsToDefault();
};

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

@@ -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 @enterprise @system_console
import {getRandomId} from '../../../../utils';
import * as TIMEOUTS from '../../../../fixtures/timeouts';
const permissions = ['create_private_channel', 'edit_post', 'delete_post', 'reactions', 'use_channel_mentions', 'use_group_mentions'];
const getButtonId = (permission) => {
return 'guests-guest_' + permission + '-checkbox';
};
const disableAllGuestPermissions = () => {
permissions.forEach((permission) => {
cy.findByTestId(getButtonId(permission)).then((btn) => {
if (btn.hasClass('checked')) {
btn.click();
}
});
});
};
const enableAllGuestPermissions = () => {
permissions.forEach((permission) => {
cy.findByTestId(getButtonId(permission)).then((btn) => {
if (!btn.hasClass('checked')) {
btn.click();
}
});
});
};
const verifyAllGuestPermissions = (selected) => {
permissions.forEach((permission) => {
if (selected) {
cy.findByTestId(getButtonId(permission)).should('have.class', 'checked');
} else {
cy.findByTestId(getButtonId(permission)).should('not.have.class', 'checked');
}
});
};
describe('Team Scheme Guest Permissions Test', () => {
before(() => {
// * Check if server has license
cy.apiRequireLicense();
});
it('MM- - Enable and Disable all guest permission', () => {
// # Go to team override scheme.
cy.visit('/admin_console/user_management/permissions/team_override_scheme');
// # create unique scheme name
const randomId = getRandomId();
cy.get('#scheme-name').type(`TestScheme-${randomId}{enter}`);
// // # Wait until the groups retrieved and show up
cy.wait(TIMEOUTS.HALF_SEC); //eslint-disable-line cypress/no-unnecessary-waiting
// # Check all the boxes currently unchecked
enableAllGuestPermissions();
// # Save if possible (if previous test ended abruptly all permissions may already be enabled)
cy.get('#saveSetting').click().wait(TIMEOUTS.HALF_SEC);
// # Reload the team scheme.
cy.findByText(`TestScheme-${randomId}`).siblings('.actions').children('.edit-button').click().wait(TIMEOUTS.HALF_SEC);
// * Ensure all checkboxes are checked
verifyAllGuestPermissions(true);
// # Uncheck all the boxes currently checked
disableAllGuestPermissions();
// # Save the page
cy.get('#saveSetting').click().wait(TIMEOUTS.HALF_SEC);
// #Reload the team scheme.
cy.findByText(`TestScheme-${randomId}`).siblings('.actions').children('.edit-button').click().wait(TIMEOUTS.HALF_SEC);
// * Ensure all checkboxes have the correct unchecked state
verifyAllGuestPermissions(false);
cy.get('.cancel-button').click();
//Clean up - Delete scheme
cy.findByText(`TestScheme-${randomId}`).siblings('.actions').children('.delete-button').click().wait(TIMEOUTS.HALF_SEC);
cy.get('#confirmModalButton').click();
});
});

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

@@ -0,0 +1,202 @@
// 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 @enterprise
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Team members test', () => {
let testTeam;
let user1;
let user2;
let sysadmin;
before(() => {
// # Login as sysadmin
cy.apiAdminLogin().then((res) => {
sysadmin = res.user;
});
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
user1 = user;
testTeam = team;
cy.apiCreateUser().then(({user: otherUser}) => {
user2 = otherUser;
cy.apiAddUserToTeam(testTeam.id, user2.id).then(() => {
cy.apiAddUserToChannel(channel.id, user2.id);
});
});
});
});
it('MM-23938 - Team members block is only visible when team is not group synced', () => {
// # Visit the team page
cy.visit(`/admin_console/user_management/teams/${testTeam.id}`);
// * Assert that the members block is visible on non group synced team
cy.get('#teamMembers').scrollIntoView().should('be.visible');
// # Click the sync group members switch
cy.findByTestId('syncGroupSwitch').
scrollIntoView().
findByRole('button').
click({force: true});
// * Assert that the members block is no longer visible
cy.get('#teamMembers').should('not.exist');
});
it('MM-23938 - Team members block can search for users, remove users, add users and modify their roles', () => {
// # Visit the team page
cy.visit(`/admin_console/user_management/teams/${testTeam.id}`);
// * Assert that the members block is visible on non group synced team
cy.get('#teamMembers').scrollIntoView().should('be.visible');
// # Search for user1 that we know is in the team
searchFor(user1.email);
// # Wait till loading complete and then remove the only visible user
cy.get('#teamMembers .DataGrid_loading').should('not.exist');
cy.get('#teamMembers .UserGrid_removeRow a').should('be.visible').click();
// # Attempt to save
cy.get('#saveSetting').click();
// * Assert that confirmation modal contains the right message
cy.get('#confirmModalBody').should('be.visible').and('contain', '1 user will be removed.').and('contain', 'Are you sure you wish to remove this user?');
// # Cancel
cy.get('#cancelModalButton').click();
// # Search for user2 that we know is in the team
searchFor(user2.email);
// # Wait till loading complete and then remove the only visible user
cy.get('#teamMembers .DataGrid_loading').should('not.exist');
cy.get('#teamMembers .UserGrid_removeRow a').should('be.visible').click();
// # Attempt to save
cy.get('#saveSetting').click();
// * Assert that confirmation modal contains the right message
cy.get('#confirmModalBody').should('be.visible').and('contain', '2 users will be removed.').and('contain', 'Are you sure you wish to remove these users?');
// # Confirm Save
cy.get('#confirmModalButton').click();
// # Check that the members block is no longer visible meaning that the save has succeeded and we were redirected out
cy.get('#teamMembers').should('not.exist');
// # Visit the team page
cy.visit(`/admin_console/user_management/teams/${testTeam.id}`);
// # Search for user1 that we know is no longer in the team
searchFor(user1.email);
// * Assert that no matching users found
cy.get('#teamMembers .DataGrid_rows').should('contain', 'No users found');
// # Search for user2 that we know is no longer in the team
searchFor(user2.email);
// * Assert that no matching users found
cy.get('#teamMembers .DataGrid_rows').should('contain', 'No users found');
// # Open the add members modal
cy.get('#addTeamMembers').click();
// # Enter user1 and user2 emails
cy.get('#addUsersToTeamModal input').typeWithForce(`${user1.email}{enter}${user2.email}{enter}`);
// # Confirm add the users
cy.get('#addUsersToTeamModal #saveItems').click();
// # Search for user1
searchFor(user1.email);
// * Assert that the user is now added to the members block and contains text denoting that they are New
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', user1.email).and('contain', 'New');
// # Open the user role dropdown menu
cy.get(`#userGridRoleDropdown_${user1.username}`).click();
// * Verify that the menu is opened
cy.get('.Menu__content').should('be.visible').within(() => {
// # Make the user an admin
cy.findByText('Make Team Admin').should('be.visible').click();
});
// # Search for user2
searchFor(user2.email);
// * Assert that the user is now added to the members block and contains text denoting that they are New
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', user2.email).and('contain', 'New');
// # Search for sysadmin
searchFor(sysadmin.email);
// * Assert that searching for users after adding users returns only relevant search results
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', sysadmin.email);
// # Attempt to save
saveConfig();
// # Visit the team page
cy.visit(`/admin_console/user_management/teams/${testTeam.id}`);
// # Search user1 that we know is now in the team again
searchFor(user1.email);
cy.get('#teamMembers .DataGrid_loading').should('not.exist');
// * Assert that the user is now saved as an admin
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', user1.email).and('not.contain', 'New').and('contain', 'Team Admin');
// # Open the user role dropdown menu
cy.get(`#userGridRoleDropdown_${user1.username}`).click();
// * Verify that the menu is opened
cy.get('.Menu__content').should('be.visible').within(() => {
// # Make the user a regular member again
cy.findByText('Make Team Member').should('be.visible').click();
});
// * Assert user1 is now back to being a regular member
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', user1.email).and('not.contain', 'New').and('contain', 'Member');
// # Search user2 that we know is now in the team again
searchFor(user2.email);
cy.get('#teamMembers .DataGrid_loading').should('not.exist');
// * Assert user2 is now saved as a regular member
cy.get('#teamMembers .DataGrid_rows').children(0).should('contain', user2.email).and('not.contain', 'New').and('contain', 'Member');
// # Attempt to save
saveConfig();
});
});
function searchFor(searchTerm) {
cy.get('#teamMembers .DataGrid_search input[type="text"]').scrollIntoView().clear().type(searchTerm);
cy.wait(TIMEOUTS.HALF_SEC); // Timeout required to wait for timeout that happens when search input changes
}
function saveConfig() {
// # Click save
cy.get('#saveSetting').click();
// # Check that the members block is no longer visible meaning that the save has succeeded and we were redirected out
cy.get('#teamMembers').should('not.exist');
}

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

@@ -0,0 +1,100 @@
// 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 @enterprise @system_console
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Team Scheme', () => {
let testTeam;
const schemeName = 'Test Team Scheme';
before(() => {
cy.apiRequireLicense();
cy.apiCreateTeam('team-scheme-test', 'Scheme Test').then(({team}) => {
testTeam = team;
});
deleteExistingTeamOverrideSchemes();
});
beforeEach(() => {
// # Go to `User Management / Permissions` section
cy.visit('/admin_console/user_management/permissions');
});
it('MM-T2855 Create a Team Override Scheme', () => {
// # Click `New Team Override Scheme`
cy.findByTestId('team-override-schemes-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Type Name and Description
cy.get('#scheme-name').should('be.visible').type(schemeName);
cy.get('#scheme-description').type('Description');
// # Click `Add Teams`
cy.findByTestId('add-teams').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Find and select testTeam
cy.get('#selectItems input').typeWithForce(testTeam.display_name).wait(TIMEOUTS.HALF_SEC);
cy.get('#multiSelectList div.more-modal__row.clickable').eq(0).click().wait(TIMEOUTS.HALF_SEC);
// # Save scheme
cy.get('#saveItems').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// # Modify the permissions scheme
const checkId = 'all_users-public_channel-create_public_channel-checkbox';
cy.findByTestId(checkId).click();
// # Save scheme
cy.get('#saveSetting').click().wait(TIMEOUTS.TWO_SEC);
// * Verify user is returned to the `Permission Schemes` page
cy.url().should('include', '/admin_console/user_management/permissions');
// * Verify the newly created scheme is visible
cy.findByTestId('permissions-scheme-summary').within(() => {
cy.get('.permissions-scheme-summary--header').should('include.text', schemeName);
cy.get('.permissions-scheme-summary--teams').should('include.text', testTeam.display_name);
});
// * Verify permission got changed as expected
cy.findByTestId(schemeName + '-edit').click().wait(TIMEOUTS.HALF_SEC);
cy.findByTestId(checkId).should('not.have.class', 'checked');
});
it('MM-T2857 Delete Scheme', () => {
// # Click `Delete` for the scheme created above
cy.findByTestId(schemeName + '-delete').click().wait(TIMEOUTS.HALF_SEC);
// # Click `Cancel` on the confirmation dialog
cy.get('#cancelModalButton').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the scheme is still visibile
cy.findByTestId('permissions-scheme-summary').within(() => {
cy.get('.permissions-scheme-summary--header').should('include.text', schemeName);
cy.get('.permissions-scheme-summary--teams').should('include.text', testTeam.display_name);
});
// # Click `Delete` for the scheme created above
cy.findByTestId(schemeName + '-delete').click().wait(TIMEOUTS.HALF_SEC);
// # Click `Yes, Delete` on the confirmation dialog
cy.get('#confirmModalButton').should('be.visible').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the scheme is not visibile anymore
cy.findByTestId('permissions-scheme-summary').should('not.exist');
});
});
const deleteExistingTeamOverrideSchemes = () => {
cy.apiGetSchemes('team').then(({schemes}) => {
schemes.forEach((scheme) => {
cy.apiDeleteScheme(scheme.id);
});
});
};

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

@@ -0,0 +1,292 @@
// 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 @enterprise @system_console
import {getAdminAccount} from '../../../../support/env';
describe('Team Scheme Channel Mentions Permissions Test', () => {
let testUser;
let testTeam;
let testChannel;
before(() => {
// * Check if server has license
cy.apiRequireLicense();
cy.apiInitSetup().then(({team, channel, user}) => {
testUser = user;
testTeam = team;
testChannel = channel;
});
// Delete any existing team override schemes
deleteExistingTeamOverrideSchemes();
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiResetRoles();
});
it('MM-23018 - Create a team override scheme', () => {
// # Visit the permissions page
cy.visit('/admin_console/user_management/permissions/team_override_scheme');
// # Give the new team scheme a name
cy.get('#scheme-name').type('Test Team Scheme');
// # Assign the new team scheme to the test team using the add teams modal
cy.findByTestId('add-teams').click();
cy.get('#selectItems input').typeWithForce(testTeam.display_name);
cy.get('.team-info-block').then((el) => {
el.click();
});
cy.get('#saveItems').click();
// # Save config
cy.get('#saveSetting').click();
// * Ensure that the team scheme was created and assigned to the team
cy.findByTestId('permissions-scheme-summary').within(() => {
cy.get('.permissions-scheme-summary--header').should('include.text', 'Test Team Scheme');
cy.get('.permissions-scheme-summary--teams').should('include.text', testTeam.display_name);
});
});
it('MM-23018 - Enable and Disable Channel Mentions for team scheme', () => {
checkChannelPermission(
'use_channel_mentions',
() => channelMentionsPermissionCheck(true),
() => channelMentionsPermissionCheck(false),
testUser,
testTeam,
testChannel,
);
});
it('MM-24379 - Enable and Disable Create Post for team scheme -- KNOWN ISSUE:MM-42020', () => {
checkChannelPermission(
'create_post',
() => createPostPermissionCheck(true),
() => createPostPermissionCheck(false),
testUser,
testTeam,
testChannel,
);
});
});
const setUserTeamAndChannelMemberships = (user, team, channel, channelAdmin = false, teamAdmin = false) => {
const admin = getAdminAccount();
// # Set user as regular system user
cy.externalRequest({user: admin, method: 'put', path: `users/${user.id}/roles`, data: {roles: 'system_user'}});
// # Get team membership
cy.externalRequest({user: admin, method: 'put', path: `teams/${team.id}/members/${user.id}/schemeRoles`, data: {scheme_user: true, scheme_admin: teamAdmin}});
// # Get channel membership
cy.externalRequest({user: admin, method: 'put', path: `channels/${channel.id}/members/${user.id}/schemeRoles`, data: {scheme_user: true, scheme_admin: channelAdmin}});
};
const saveConfig = () => {
cy.get('#saveSetting').click();
cy.url().should('equal', `${Cypress.config('baseUrl')}/admin_console/user_management/permissions`);
};
const enablePermission = (permissionCheckBoxTestId) => {
cy.findByTestId(permissionCheckBoxTestId).then((el) => {
if (!el.hasClass('checked')) {
el.click();
}
});
};
const removePermission = (permissionCheckBoxTestId) => {
cy.findByTestId(permissionCheckBoxTestId).then((el) => {
if (el.hasClass('checked')) {
el.click();
}
});
};
const deleteExistingTeamOverrideSchemes = () => {
cy.apiGetSchemes('team').then(({schemes}) => {
schemes.forEach((scheme) => {
cy.apiDeleteScheme(scheme.id);
});
});
};
// # Checks to see if user recieved a system message warning after using @here
// # If enabled is true assumes the user has the permission enabled and checks for no system message
const channelMentionsPermissionCheck = (enabled) => {
// # Type @here and post it to the channel
cy.postMessage('@here ');
// # Get last post message text
cy.getLastPostId().then((postId) => {
if (enabled) {
// * Assert that the last message posted is not a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('not.include.text', 'Channel notifications are disabled');
} else {
cy.uiWaitUntilMessagePostedIncludes('Channel notifications are disabled');
// * Assert that the last message posted is the system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', 'Channel notifications are disabled');
}
});
};
// # Checks to see if the post input is enabled or disalbed and that the API
// accepts or rejects the create post request.
const createPostPermissionCheck = (enabled) => {
if (enabled) {
// # Try post it to the channel
cy.uiGetPostTextBox().should('not.be.disabled');
cy.postMessage('test');
} else {
// # Ensure the input is disabled
cy.uiGetPostTextBox().should('be.disabled');
}
// # Get last post message text
cy.getLastPostId().then((postId) => {
if (enabled) {
// * Assert that the last message posted is not a system message informing us we are not allowed to use channel mentions
cy.get(`#postMessageText_${postId}`).should('include.text', 'test');
}
});
};
const checkChannelPermission = (permissionName, hasChannelPermissionCheckFunc, notHasChannelPermissionCheckFunc, testUser, testTeam, testChannel) => {
const channelUrl = `/${testTeam.name}/channels/${testChannel.name}`;
// # Setup user as a regular channel member
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel);
// * Ensure user can use channel mentions by default
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Login as sysadmin again
cy.apiAdminLogin();
// # Get team scheme URL
cy.apiGetSchemes('team').then(({schemes}) => {
const teamScheme = schemes[0];
const url = `admin_console/user_management/permissions/team_override_scheme/${teamScheme.id}`;
// todo: add checks for guests once mattermost-webapp/pull/5061 is merged
const usersTestId = `all_users-posts-${permissionName}-checkbox`;
const channelTestId = `${teamScheme.default_channel_admin_role}-posts-${permissionName}-checkbox`;
const teamTestId = `${teamScheme.default_team_admin_role}-posts-${permissionName}-checkbox`;
const testIds = [usersTestId, channelTestId, teamTestId];
// # Visit the scheme page
cy.visit(url);
// * Ensure permission is enabled at each scope by default
testIds.forEach((testId) => {
cy.findByTestId(testId).should('have.class', 'checked');
});
// # Remove permission from all users and save
removePermission(usersTestId);
saveConfig();
cy.visit(url);
// * Ensure that the permission is not removed for channel admins and team admins
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
cy.findByTestId(channelTestId).should('have.class', 'checked');
cy.findByTestId(teamTestId).should('have.class', 'checked');
// # Remove permission for channel admins and save
removePermission(channelTestId);
saveConfig();
cy.visit(url);
// * Ensure that the permission is removed from all roles except team admins
cy.findByTestId(teamTestId).should('have.class', 'checked');
cy.findByTestId(channelTestId).should('not.have.class', 'checked');
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
// # Enable permission for channel admins and save
enablePermission(channelTestId);
saveConfig();
cy.visit(url);
// * Ensure that the permission is only removed from all users
cy.findByTestId(teamTestId).should('have.class', 'checked');
cy.findByTestId(channelTestId).should('have.class', 'checked');
cy.findByTestId(usersTestId).should('not.have.class', 'checked');
// # Setup user as a regular channel member
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel);
// * Ensure user cannot use channel mentions
cy.apiLogin(testUser);
cy.visit(channelUrl);
notHasChannelPermissionCheckFunc();
// # Setup user as a channel admin
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel, true, false);
// * Ensure user can use channel mentions as channel admin
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Navigate back to team scheme as sysadmin
cy.apiAdminLogin();
cy.visit(url);
// # Remove permission from channel admins and save
removePermission(channelTestId);
saveConfig();
cy.visit(url);
// # Log back in as regular user
cy.apiLogin(testUser);
cy.visit(channelUrl);
// * Ensure user cannot use channel mentions as channel admin
notHasChannelPermissionCheckFunc();
// # Setup user as a team admin
setUserTeamAndChannelMemberships(testUser, testTeam, testChannel, true, true);
// * Ensure user can use channel mentions as team admin
cy.apiLogin(testUser);
cy.visit(channelUrl);
hasChannelPermissionCheckFunc();
// # Navigate back to system scheme as sysadmin
cy.apiAdminLogin();
cy.visit(url);
// # Remove permission from team admins and save
removePermission(teamTestId);
saveConfig();
cy.visit(url);
// # Log back in as regular user
cy.apiLogin(testUser);
cy.visit(channelUrl);
// * Ensure user cannot use channel mentions as team admin
notHasChannelPermissionCheckFunc();
});
};

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

@@ -0,0 +1,137 @@
// 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 @enterprise @system_console
describe('System Console', () => {
before(() => {
// * Check if server has license for ID Loaded Push Notifications
cy.apiRequireLicenseForFeature('IDLoadedPushNotifications');
// # Update to default config
cy.apiUpdateConfig({
EmailSettings: {
PushNotificationContents: 'full',
FeedbackName: 'Mattermost Test Team',
FeedbackEmail: 'feedback@mattertest.com',
},
SupportSettings: {
SupportEmail: 'support@mattertest.com',
},
});
// # Visit Notifications admin console page
cy.visit('/admin_console/environment/notifications');
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Notifications');
});
it('Push Notification Contents', () => {
// * Verify that setting is visible and matches text content
cy.findByTestId('EmailSettings.PushNotificationContents').
scrollIntoView().should('be.visible').
find('label').should('be.visible').and('have.text', 'Push Notification Contents:');
// * Verify that the help text is visible and matches text content
cy.findByTestId('EmailSettings.PushNotificationContentshelp-text').should('be.visible').within((el) => {
const contents = [
'Generic description with only sender name',
' - Includes only the name of the person who sent the message in push notifications, with no information about channel name or message contents. ',
'Generic description with sender and channel names',
' - Includes the name of the person who sent the message and the channel it was sent in, but not the message contents. ',
'Full message content sent in the notification payload',
' - Includes the message contents in the push notification payload that is relayed through Apple\'s Push Notification Service (APNS) or Google\'s Firebase Cloud Messaging (FCM). It is ',
'highly recommended',
' this option only be used with an "https" protocol to encrypt the connection and protect confidential information sent in messages.',
'Full message content fetched from the server on receipt',
' - The notification payload relayed through APNS or FCM contains no message content, instead it contains a unique message ID used to fetch message content from the server when a push notification is received by a device. If the server cannot be reached, a generic notification will be displayed.',
];
cy.wrap(el).should('have.text', contents.join(''));
cy.get('strong').eq(0).should('have.text', contents[0]);
cy.get('strong').eq(1).should('have.text', contents[2]);
cy.get('strong').eq(2).should('have.text', contents[4]);
cy.get('strong').eq(3).should('have.text', contents[6]);
cy.get('strong').eq(4).should('have.text', contents[8]);
});
// * Verify that the option/dropdown is visible and has default value
cy.findByTestId('EmailSettings.PushNotificationContentsdropdown').
should('be.visible').
and('have.value', 'full');
const options = [
{label: 'Generic description with only sender name', value: 'generic_no_channel'},
{label: 'Generic description with sender and channel names', value: 'generic'},
{label: 'Full message content sent in the notification payload', value: 'full'},
{label: 'Full message content fetched from the server on receipt', value: 'id_loaded'},
];
// # Select each value and save
// * Verify that the config is correctly saved in the server
options.forEach((option) => {
cy.findByTestId('EmailSettings.PushNotificationContentsdropdown').
select(option.label).
and('have.value', option.value);
cy.get('#saveSetting').click();
cy.apiGetConfig().then(({config}) => {
expect(config.EmailSettings.PushNotificationContents).to.equal(option.value);
});
});
});
it('MM-T1210+MM-41671 Can change Support Email setting', () => {
// # Scroll Support Email section into view and verify that it's visible
cy.findByTestId('SupportSettings.SupportEmail').scrollIntoView().should('be.visible');
// * Verify that setting label is visible and matches text content
cy.findByTestId('SupportSettings.SupportEmaillabel').should('be.visible').and('have.text', 'Support Email Address:');
// * Verify that the help text is visible and matches text content
cy.findByTestId('SupportSettings.SupportEmailhelp-text').find('span').should('be.visible').and('have.text', 'Email address displayed on support emails.');
const newEmail = 'changed_for_test_support@example.com';
// * Verify that set value is visible and matches text
cy.findByTestId('SupportSettings.SupportEmail').find('input').clear().type(newEmail).should('have.value', newEmail);
// # Save setting
cy.get('#saveSetting').click();
// * Verify that the config is correctly saved in the server
cy.apiGetConfig().then(({config}) => {
expect(config.SupportSettings.SupportEmail).to.equal(newEmail);
});
});
describe('MM-41671 cannot save the notifications page if mandatory fields are missing', () => {
const tests = [
{name: 'Support Email cannot be empty', field: 'SupportSettings.SupportEmail'},
{name: 'Notification Display Name cannot be empty', field: 'EmailSettings.FeedbackName'},
{name: 'Notification Email Address cannot be empty', field: 'SupportSettings.SupportEmail'},
];
tests.forEach((test) => {
it(test.name, () => {
// # Clear the field
cy.findByTestId(test.field).find('input').clear();
// * Ensures the save button is disabled
cy.get('#saveSetting').should('be.disabled');
// # Insert something in the field
cy.findByTestId(test.field).find('input').type(test.field);
// * Ensures the save button is disabled
cy.get('#saveSetting').should('be.not.disabled');
});
});
});
});