snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-16 00:29:55 +05:00
commit 240db4e2a7
15309 changed files with 2173406 additions and 0 deletions

View File

@@ -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.
// ***************************************************************
// Group: @channels @system_console
import * as MESSAGES from '@/fixtures/messages';
describe('System Console > User Management > Deactivation', () => {
let team1;
let otherAdmin;
before(() => {
// # Do initial setup
cy.apiInitSetup().then(({team}) => {
team1 = team;
});
// # Create other sysadmin
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
otherAdmin = sysadmin;
});
});
beforeEach(() => {
// # Login as other admin.
cy.apiLogin(otherAdmin);
// # Visit town-square
cy.visit(`/${team1.name}`);
});
it('MM-T951 Reopened DM shows archived icon in LHS No status indicator in channel header Message box replaced with "You are viewing an archived channel with a deactivated user." in center and RHS - KNOWN ISSUE: MM-42529', () => {
// # Create other user
cy.apiCreateUser({prefix: 'other'}).then(({user}) => {
// # Send a DM to the other user
cy.sendDirectMessageToUser(user, MESSAGES.SMALL);
// # Open RHS
cy.clickPostCommentIcon();
// * Verify status indicator is shown in channel header
cy.get('#channelHeaderDescription .status').should('be.visible');
// # Deactivate other user
cy.apiDeactivateUser(user.id);
// * Verify center channel message box is replace with warning
cy.get('.channel-archived__message').contains('You are viewing an archived channel with a deactivated user. New messages cannot be posted.');
// * Verify RHS message box is replace with warning
cy.get('#rhsContainer .post-create-message').contains('You are viewing an archived channel with a deactivated user. New messages cannot be posted.');
// * Verify status indicator is not shown in channel header
cy.get('#channelHeaderDescription .status').should('not.exist');
// * Verify archived icon is shown in LHS
cy.uiGetLhsSection('DIRECT MESSAGES').
find('.active').should('be.visible').
find('.icon-archive-outline').should('be.visible');
});
});
});

View File

@@ -0,0 +1,62 @@
// 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 @not_cloud
import * as TIMEOUTS from '@/fixtures/timeouts';
describe('System Console > User Management > Deactivation', () => {
let testUser;
before(() => {
cy.shouldNotRunOnCloudEdition();
// # Do initial setup
cy.apiInitSetup().then(({user}) => {
testUser = user;
});
// # Visit the system console.
cy.visit('/admin_console');
});
it('MM-T947 When deactivating users in the System Console, email address should not disappear', () => {
// # Go to User management / Users tab
cy.findByTestId('user_management.system_users').should('be.visible').click();
// # Search the newly created user in the search box
cy.findByPlaceholderText('Search users').should('be.visible').clear().type(testUser.email).wait(TIMEOUTS.HALF_SEC);
// * Verify that user is listed
cy.findByText(`${testUser.username}`).should('be.visible');
// * Verify before deactivation email is visible
cy.get('#systemUsersTable-cell-0_emailColumn').should('be.visible').should('have.text', testUser.email);
// # Open the actions menu.
cy.get('#actionMenuButton-systemUsersTable-0').should('have.text', 'Member').click().wait(TIMEOUTS.HALF_SEC);
// # Click on deactivate menu button
cy.get('#actionMenuItem-systemUsersTable-0-deactivate').should('have.text', 'Deactivate').click();
// # Click confirm deactivate in the modal
cy.get('.a11y__modal').should('exist').and('be.visible').within(() => {
cy.findByText('Deactivate').should('be.visible').click();
});
cy.get('#actionMenuButton-systemUsersTable-0').should('have.text', 'Deactivated').should('be.visible');
// * Verify once again if email is visible
cy.findByText(testUser.email).should('be.visible');
// * Verify once again if email is visible
cy.get('#systemUsersTable-cell-0_emailColumn').should('be.visible').should('have.text', testUser.email);
});
});

View File

@@ -0,0 +1,145 @@
// 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';
import * as MESSAGES from '@/fixtures/messages';
describe('System Console > User Management > Deactivation', () => {
let team1;
let otherAdmin;
before(() => {
// # Do initial setup
cy.apiInitSetup().then(({team}) => {
team1 = team;
});
// # Create other sysadmin
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
otherAdmin = sysadmin;
});
});
beforeEach(() => {
// # Login as other admin.
cy.apiLogin(otherAdmin);
// # Visit town-square
cy.visit(`/${team1.name}`);
});
// # Create two users
it('MM-T946 GM: User deactivated in System Console still displays', () => {
cy.apiCreateUser({prefix: 'first'}).then(({user: user1}) => {
cy.apiCreateUser({prefix: 'second'}).then(({user: user2}) => {
const message = MESSAGES.SMALL;
// # Send a GM to them
cy.sendDirectMessageToUsers([user1, user2], message);
// * Verify names on the LHS are still ordered alphabetically
cy.uiGetLhsSection('DIRECT MESSAGES').find('.active').should('contain', user1.username + ', ' + user2.username);
// # Deactivate user 1
cy.apiDeactivateUser(user1.id);
// * Verify names on the LHS are still ordered alphabetically
cy.uiGetLhsSection('DIRECT MESSAGES').find('.active').should('contain', user1.username + ', ' + user2.username);
// # Search for the message send in the GM
cy.uiSearchPosts(message);
// * Verify GM message is returned in RHS
cy.findAllByTestId('search-item-container').
should('be.visible').and('have.length', 1).
eq(0).should('contain', message);
});
});
});
it('MM-T948 DM posts searchable in DM More... and channel switcher DM channel re-openable', () => {
cy.apiCreateUser({prefix: 'other'}).then(({user: other}) => {
// # Open DM
cy.sendDirectMessageToUser(other, MESSAGES.SMALL);
// # Close DM
cy.get('#channelHeaderTitle').click();
cy.findByText('Close Direct Message').click();
// # Deactivate the user
cy.apiDeactivateUser(other.id);
// # Open Find Channels
cy.uiOpenFindChannels();
// # Type the user name on Channel switcher input
cy.get('#quickSwitchInput').type(other.username).wait(TIMEOUTS.HALF_SEC);
// * Verify user is marked as deactivated
cy.get('[data-testid="' + other.username + '"]').contains('Deactivated');
// # Close Channel Switcher
cy.uiClose();
// # Open DM Modal
cy.uiAddDirectMessage().click().wait(TIMEOUTS.ONE_SEC);
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
// # Start typing part of a username that matches previously created users
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(other.username).
wait(TIMEOUTS.ONE_SEC);
// * Verify user is marked as deactivated
cy.get('#displayedUserName' + other.username).parent().contains('Deactivated');
// # Click on the user
cy.get('#displayedUserName' + other.username).click();
// * Confirm DM More... Modal is closed
cy.get('#moreDmModal').should('not.exist');
});
});
it('MM-T949 If an active user is selected in DM More... or channel switcher, deactivated users should be shown in the DM more or channel switcher', () => {
// # Create two users
cy.apiCreateUser({prefix: 'first'}).then(({user: user1}) => {
cy.apiCreateUser({prefix: 'second_'}).then(({user: user2}) => {
// # Send a DM to user1 so they show up in the DM modal
cy.sendDirectMessageToUser(user1, MESSAGES.SMALL);
// # Send a DM to user2 so they show up in the DM modal
cy.sendDirectMessageToUser(user2, MESSAGES.SMALL);
// # Deactivate user 2
cy.apiDeactivateUser(user2.id);
// # Open DM Modal
cy.uiAddDirectMessage().click().wait(TIMEOUTS.HALF_SEC);
// # Type the user name of user1 on Channel switcher input
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(user1.username).
wait(TIMEOUTS.ONE_SEC);
// # Click on the user
cy.get('#displayedUserName' + user1.username).click();
// # Type the user name of user2 on Channel switcher input
cy.get('.more-direct-channels #selectItems input').typeWithForce(user2.username).wait(TIMEOUTS.HALF_SEC);
// * Confirm user2 can't be added to the DM
cy.get('#displayedUserName' + user2.username).should('be.visible');
});
});
});
});

View File

@@ -0,0 +1,75 @@
// 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 @system_console
import * as TIMEOUTS from '@/fixtures/timeouts';
import * as MESSAGES from '@/fixtures/messages';
import {getRandomId} from '@/utils';
describe('System Console > User Management > Reactivation', () => {
let teamName;
before(() => {
cy.shouldNotRunOnCloudEdition();
// # Do initial setup
cy.apiInitSetup().then(({team}) => {
teamName = team.name;
});
});
it('MM-T952 Reactivating a user results in them showing up in the normal spot in the list, without the `Deactivated` label.', () => {
// # Visit town-square
cy.visit(`/${teamName}`);
// # Create two users with same random prefix
const id = getRandomId();
cy.apiCreateUser({prefix: id + '_a_'}).then(({user: user1}) => {
cy.apiCreateUser({prefix: id + '_b_'}).then(({user: user2}) => {
// # Send a DM to user1 so they show up in the DM modal
cy.sendDirectMessageToUser(user1, MESSAGES.SMALL);
// # Send a DM to user2 so they show up in the DM modal
cy.sendDirectMessageToUser(user2, MESSAGES.SMALL);
// # Open DM More... Modal
cy.uiAddDirectMessage().click().wait(TIMEOUTS.HALF_SEC);
// # Type the user name of the other user on Channel switcher input
cy.get('.more-direct-channels #selectItems input').typeWithForce(id).wait(TIMEOUTS.HALF_SEC);
// * Verify user 1 is shown first and doesn't have deactivated text
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user1.username).parent().should('not.contain', 'Deactivated');
// * Verify user 2 is shown second
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user2.username);
// # Deactivate user1
cy.apiDeactivateUser(user1.id).then(() => {
// * Verify user 1 is shown second and does have deactivated text
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user1.username).parent().should('contain', 'Deactivated');
// * Verify user 2 is shown first
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user2.username);
// # Reactivate user1
cy.apiActivateUser(user1.id).then(() => {
// * Verify user 1 is shown first and doesn't have deactivated text
cy.get('#moreDmModal .more-modal__row').siblings().its(0).get('#displayedUserName' + user1.username).parent().should('not.contain', 'Deactivated');
// * Verify user 2 is shown second
cy.get('#moreDmModal .more-modal__row').siblings().its(1).get('#displayedUserName' + user2.username);
});
});
});
});
});
});

View File

@@ -0,0 +1,206 @@
// 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('System Console > User Management > Users', () => {
let testUser;
let otherAdmin;
before(() => {
cy.apiInitSetup().then(({user}) => {
testUser = user;
});
// # Create other sysadmin
cy.apiCreateCustomAdmin().then(({sysadmin}) => {
otherAdmin = sysadmin;
});
});
beforeEach(() => {
// # Login as other admin.
cy.apiLogin(otherAdmin);
// # Visit the system console.
cy.visit('/admin_console');
// # Go to the User management/Users section.
cy.findByTestId('user_management.system_users').
click().
wait(TIMEOUTS.ONE_SEC);
});
it('MM-T925 Users - Profile image on User Configuration page is round', () => {
// # Find the created user by entering in the search
cy.findByPlaceholderText('Search users').
should('be.visible').
clear().
type(testUser.email).
wait(TIMEOUTS.HALF_SEC);
// # Click on the searched user name
cy.findByText(`${testUser.username}`).
should('be.visible').
click({force: true});
// * Verify we landed on the user configuration page
cy.location('pathname').should(
'equal',
`/admin_console/user_management/user/${testUser.id}`,
);
// * Verify that user profile image is round
cy.findByAltText('user profile image').
should('be.visible').
and('have.css', 'border-radius', '50%');
});
it('MM-T932 Users - Change a user\'s password', () => {
searchUserAndOpenResetPassword(testUser.email, testUser.email);
// # Type new password and submit.
cy.get('input[type=password]').type('new' + testUser.password);
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// # Log out.
cy.apiLogout();
// * Verify that logging in with old password returns an error.
apiLogin(testUser.username, testUser.password).then((response) => {
expect(response.status).to.equal(401);
// * Verify that logging in with the updated password works.
testUser.password = 'new' + testUser.password;
cy.apiLogin(testUser);
// # Log out.
cy.apiLogout();
});
});
it('MM-T933 Users - System admin changes own password - Cancel out of changes', () => {
searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email);
// # Type current password and a new password.
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
// # Click the 'Cancel' button.
cy.get('.modal-footer > .btn-tertiary').should('contain', 'Cancel').click().wait(TIMEOUTS.HALF_SEC);
// # Log out.
cy.apiLogout();
// * Verify that logging in with the old password works.
cy.apiLogin(otherAdmin);
});
it('MM-T934 Users - System admin changes own password - Incorrect old password', () => {
searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email);
// # Type wrong current password and a new password.
cy.get('input[type=password]').eq(0).type('wrong' + otherAdmin.password);
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
// # Click the 'Reset' button.
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the appropriate error is returned (current password error shows in modal header area).
cy.get('.genericModalError .error').should('be.visible').
and('contain', 'The "Current Password" you entered is incorrect. Please check that Caps Lock is off and try again.');
});
it('MM-T935 Users - System admin changes own password - Invalid new password', () => {
searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email);
// # Type current password and a new too short password.
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
cy.get('input[type=password]').eq(1).type('new');
// # Click the 'Reset' button.
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the appropriate error is returned (new password error shows under the input).
cy.get('.Input___error').should('be.visible').and('contain', 'characters long');
});
it('MM-T936 Users - System admin changes own password - Blank fields', () => {
searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email);
// # Click the 'Reset' button.
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the appropriate error is returned (current password missing).
cy.get('.genericModalError .error').should('be.visible').
and('contain', 'Please enter your current password.');
// # Type current password, leave new password blank.
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
// # Click the 'Reset' button.
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// * Verify the appropriate error is returned (new password error shows under the input).
cy.get('.Input___error').should('be.visible').and('contain', 'characters long');
});
it('MM-T937 Users - System admin changes own password - Successfully changed', () => {
searchUserAndOpenResetPassword(otherAdmin.username, otherAdmin.email);
// # Type current and new passwords..
cy.get('input[type=password]').eq(0).type(otherAdmin.password);
cy.get('input[type=password]').eq(1).type('new' + otherAdmin.password);
// # Click the 'Reset' button.
cy.get('button.btn-primary.confirm').should('contain', 'Reset').click().wait(TIMEOUTS.HALF_SEC);
// # Log out.
cy.apiLogout();
// * Verify that logging in with old password returns an error.
apiLogin(otherAdmin.username, otherAdmin.password).then((response) => {
expect(response.status).to.equal(401);
// * Verify that logging in with new password works.
otherAdmin.password = 'new' + otherAdmin.password;
cy.apiLogin(otherAdmin);
// # Reset admin's password to the original.
cy.apiResetPassword('me', otherAdmin.password, otherAdmin.password.substr(3));
});
});
});
function searchUserAndOpenResetPassword(query, email) {
// # Search for the user.
cy.findByPlaceholderText('Search users').should('be.visible').clear().type(query);
// * Verify the matching email is in the first row
cy.get('#systemUsersTable-cell-0_emailColumn').should('be.visible').and('contain', email);
// # Open the actions menu.
cy.get('#actionMenuButton-systemUsersTable-0').should('be.visible').click();
// # Click the Reset Password menu option.
cy.get('#actionMenuItem-systemUsersTable-0-resetPassword').should('be.visible').click();
}
function apiLogin(username, password) {
return cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/users/login',
method: 'POST',
body: {login_id: username, password},
failOnStatusCode: false,
});
}