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 Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
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 Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
// 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
|
||||
|
||||
import {promoteToChannelOrTeamAdmin} from '../channel_moderation/helpers.ts';
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
import {getAdminAccount} from '@/support/env';
|
||||
|
||||
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 Advanced for Enterprise licenses', () => {
|
||||
cy.visit('/admin_console/about/license');
|
||||
cy.get('.admin-console__header').
|
||||
should('be.visible').
|
||||
and('have.text', 'Edition and License');
|
||||
|
||||
// Validate Enterprise to Enterprise Advanced upgrade content
|
||||
cy.get('.EnterpriseEditionRightPannel').
|
||||
should('be.visible').
|
||||
within(() => {
|
||||
// Check the title
|
||||
cy.get('.upgrade-title').should('have.text', 'Upgrade to Enterprise Advanced');
|
||||
|
||||
// Check the advantages list
|
||||
cy.findByText('Dynamic attribute-based access controls');
|
||||
cy.findByText('Data spillage handling');
|
||||
cy.findByText('Burn-on-read messages');
|
||||
cy.findByText('Mobile biometrics & advanced security');
|
||||
cy.findByText('Automatic channel translations');
|
||||
cy.findByText('Channel banners');
|
||||
cy.findByText('And more...');
|
||||
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');
|
||||
|
||||
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('#channelHeaderTitle', {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,270 @@
|
||||
// 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
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
// These specs exercise the license upload preview/diff flow added in MM-67113.
|
||||
// The upload and preview endpoints require real, signed license bytes that are
|
||||
// not available to the e2e environment, so the network is stubbed via
|
||||
// cy.intercept and a tiny dummy file is fed into the hidden file input. The
|
||||
// stubs are crafted to reproduce the two issues reported during QA:
|
||||
// 1. After uploading a new license, the success screen showed the previous
|
||||
// tier and the System Console license page did not refresh.
|
||||
// 2. Re-uploading the currently applied license was not handled gracefully.
|
||||
|
||||
const OLD_LICENSE_ID = 'old-license-id-0000000000000';
|
||||
|
||||
// Current (already applied) license, as returned by GET /license/client.
|
||||
const currentClientLicense = buildClientLicense({
|
||||
id: OLD_LICENSE_ID,
|
||||
skuName: 'Professional',
|
||||
skuShortName: 'professional',
|
||||
users: '100',
|
||||
});
|
||||
|
||||
// New license returned by the preview/upload endpoints (an upgrade to Enterprise).
|
||||
const newLicense = buildLicense({
|
||||
id: 'new-license-id-0000000000000',
|
||||
skuName: 'Enterprise',
|
||||
skuShortName: 'enterprise',
|
||||
users: 500,
|
||||
});
|
||||
|
||||
describe('System console - License preview/diff view', () => {
|
||||
before(() => {
|
||||
cy.apiAdminLogin();
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
|
||||
// * Ensure the server is licensed so the System Console renders the
|
||||
// enterprise license page (the displayed license is stubbed below).
|
||||
cy.apiRequireLicense();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('MM-67113 - Shows the newly uploaded license tier on success and refreshes the page after closing', () => {
|
||||
// # The displayed license starts as Professional. It is served from a
|
||||
// mutable holder so we can simulate the server only reporting the new
|
||||
// license once propagation completes (by the time the modal closes).
|
||||
const clientLicenseHolder = {body: currentClientLicense};
|
||||
cy.intercept('GET', '**/api/v4/license/client', (req) => {
|
||||
req.reply({statusCode: 200, body: clientLicenseHolder.body});
|
||||
}).as('getClientLicense');
|
||||
|
||||
// # Preview and upload both return the new Enterprise license
|
||||
cy.intercept('POST', '**/api/v4/license/preview', {statusCode: 200, body: newLicense}).as('previewLicense');
|
||||
cy.intercept('POST', '**/api/v4/license', {statusCode: 200, body: newLicense}).as('uploadLicense');
|
||||
|
||||
cy.visit('/admin_console/about/license');
|
||||
cy.wait('@getClientLicense');
|
||||
|
||||
// * The page initially shows the current (Professional) license
|
||||
cy.get('.EnterpriseEditionLeftPanel__Title', {timeout: TIMEOUTS.TEN_SEC}).
|
||||
should('contain.text', 'Mattermost Professional');
|
||||
|
||||
// # Select a license file to open the upload modal
|
||||
selectLicenseFile();
|
||||
|
||||
// # Wait for the preview request and the diff view to render
|
||||
cy.wait('@previewLicense');
|
||||
cy.get('#UploadLicenseModal').should('be.visible').within(() => {
|
||||
// * The diff view compares the current and new license tiers
|
||||
cy.findByText('Review License Changes').should('be.visible');
|
||||
cy.get('.diff-current').should('contain.text', 'Professional');
|
||||
cy.get('.diff-new').should('contain.text', 'Enterprise');
|
||||
|
||||
// # Apply the new license
|
||||
cy.get('#confirm-button').click();
|
||||
});
|
||||
cy.wait('@uploadLicense');
|
||||
|
||||
// * The success screen reflects the NEWLY uploaded tier (Enterprise),
|
||||
// not the previously applied tier (Professional). This is the core of
|
||||
// the "uploaded Enterprise, got Professional" report.
|
||||
cy.get('#UploadLicenseModal').should('be.visible').within(() => {
|
||||
cy.findByText('New license successfully applied').should('be.visible');
|
||||
cy.get('.subtitle').
|
||||
should('contain.text', 'Enterprise').
|
||||
and('not.contain.text', 'Professional');
|
||||
});
|
||||
|
||||
// # By the time the admin closes the modal, the server reports the new
|
||||
// license. Closing must trigger a refresh that picks this up.
|
||||
cy.then(() => {
|
||||
clientLicenseHolder.body = buildClientLicense({
|
||||
id: newLicense.id,
|
||||
skuName: 'Enterprise',
|
||||
skuShortName: 'enterprise',
|
||||
users: '500',
|
||||
});
|
||||
});
|
||||
cy.get('#UploadLicenseModal').within(() => {
|
||||
cy.get('#done-button').click();
|
||||
});
|
||||
cy.get('#UploadLicenseModal').should('not.exist');
|
||||
|
||||
// * The System Console license page refreshes to show the new license
|
||||
// without requiring a manual page reload.
|
||||
cy.get('.EnterpriseEditionLeftPanel__Title', {timeout: TIMEOUTS.TEN_SEC}).
|
||||
should('contain.text', 'Mattermost Enterprise');
|
||||
});
|
||||
|
||||
it('MM-67113 - Warns when re-uploading the currently applied license and leaves it unchanged', () => {
|
||||
// # The displayed license stays Professional throughout this flow
|
||||
cy.intercept('GET', '**/api/v4/license/client', {
|
||||
statusCode: 200,
|
||||
body: currentClientLicense,
|
||||
}).as('getClientLicense');
|
||||
|
||||
// # Preview and upload return the SAME license that is currently applied
|
||||
// (same id), so the diff view should detect an unchanged license.
|
||||
const sameLicense = buildLicense({
|
||||
id: OLD_LICENSE_ID,
|
||||
skuName: 'Professional',
|
||||
skuShortName: 'professional',
|
||||
users: 100,
|
||||
});
|
||||
cy.intercept('POST', '**/api/v4/license/preview', {statusCode: 200, body: sameLicense}).as('previewLicense');
|
||||
cy.intercept('POST', '**/api/v4/license', {statusCode: 200, body: sameLicense}).as('uploadLicense');
|
||||
|
||||
cy.visit('/admin_console/about/license');
|
||||
cy.wait('@getClientLicense');
|
||||
cy.get('.EnterpriseEditionLeftPanel__Title', {timeout: TIMEOUTS.TEN_SEC}).
|
||||
should('contain.text', 'Mattermost Professional');
|
||||
|
||||
// # Select the same license file to open the upload modal
|
||||
selectLicenseFile();
|
||||
cy.wait('@previewLicense');
|
||||
|
||||
// * The diff view warns that the license is already active
|
||||
cy.get('#UploadLicenseModal').should('be.visible').within(() => {
|
||||
cy.findByText('This license is already active').should('be.visible');
|
||||
|
||||
// # The admin can still apply it; doing so must not break the flow
|
||||
cy.get('#confirm-button').click();
|
||||
});
|
||||
cy.wait('@uploadLicense');
|
||||
|
||||
// * The flow completes successfully and the modal can be closed
|
||||
cy.get('#UploadLicenseModal').should('be.visible').within(() => {
|
||||
cy.findByText('New license successfully applied').should('be.visible');
|
||||
cy.get('#done-button').click();
|
||||
});
|
||||
cy.get('#UploadLicenseModal').should('not.exist');
|
||||
|
||||
// * The applied license is unchanged and the page remains functional
|
||||
cy.get('.EnterpriseEditionLeftPanel__Title', {timeout: TIMEOUTS.TEN_SEC}).
|
||||
should('contain.text', 'Mattermost Professional');
|
||||
});
|
||||
});
|
||||
|
||||
// Feed a small dummy file into the hidden license file input. The actual bytes
|
||||
// are irrelevant because the preview/upload endpoints are stubbed.
|
||||
function selectLicenseFile() {
|
||||
cy.get('[data-testid="EnterpriseEditionLeftPanel"] input[type="file"]').
|
||||
selectFile({
|
||||
contents: Cypress.Buffer.from('dummy-license-content'),
|
||||
fileName: 'test-license.mattermost-license',
|
||||
}, {force: true});
|
||||
}
|
||||
|
||||
// Build a License object matching the shape returned by POST /license/preview
|
||||
// and POST /license (server model.License serialized to JSON).
|
||||
function buildLicense({id, skuName, skuShortName, users}) {
|
||||
const now = Date.now();
|
||||
return {
|
||||
id,
|
||||
issued_at: now,
|
||||
starts_at: now,
|
||||
expires_at: now + (365 * 24 * 60 * 60 * 1000),
|
||||
customer: {
|
||||
id: 'customer-id',
|
||||
name: 'Test Customer',
|
||||
email: 'test@example.com',
|
||||
company: 'Test Company',
|
||||
},
|
||||
features: {
|
||||
users,
|
||||
ldap: true,
|
||||
ldap_groups: true,
|
||||
mfa: true,
|
||||
google_oauth: true,
|
||||
office365_oauth: true,
|
||||
compliance: true,
|
||||
cluster: true,
|
||||
metrics: true,
|
||||
mhpns: true,
|
||||
saml: true,
|
||||
elastic_search: true,
|
||||
announcement: true,
|
||||
theme_management: true,
|
||||
email_notification_contents: true,
|
||||
data_retention: true,
|
||||
message_export: true,
|
||||
custom_permissions_schemes: true,
|
||||
custom_terms_of_service: true,
|
||||
guest_accounts: true,
|
||||
guest_accounts_permissions: true,
|
||||
},
|
||||
sku_name: skuName,
|
||||
sku_short_name: skuShortName,
|
||||
is_gov_sku: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Build a ClientLicense object (old format) matching GET /license/client.
|
||||
// All values are strings, as produced by the server.
|
||||
function buildClientLicense({id, skuName, skuShortName, users}) {
|
||||
const now = Date.now();
|
||||
return {
|
||||
IsLicensed: 'true',
|
||||
IsTrial: 'false',
|
||||
Id: id,
|
||||
SkuName: skuName,
|
||||
SkuShortName: skuShortName,
|
||||
Users: users,
|
||||
IssuedAt: String(now),
|
||||
StartsAt: String(now),
|
||||
ExpiresAt: String(now + (365 * 24 * 60 * 60 * 1000)),
|
||||
Name: 'Test Customer',
|
||||
Email: 'test@example.com',
|
||||
Company: 'Test Company',
|
||||
IsGovSku: 'false',
|
||||
LDAP: 'true',
|
||||
LDAPGroups: 'true',
|
||||
MFA: 'true',
|
||||
SAML: 'true',
|
||||
Cluster: 'true',
|
||||
Metrics: 'true',
|
||||
GoogleOAuth: 'true',
|
||||
Office365OAuth: 'true',
|
||||
OpenId: 'true',
|
||||
Compliance: 'true',
|
||||
MHPNS: 'true',
|
||||
Announcement: 'true',
|
||||
Elasticsearch: 'true',
|
||||
DataRetention: 'true',
|
||||
IDLoadedPushNotifications: 'true',
|
||||
EmailNotificationContents: 'true',
|
||||
MessageExport: 'true',
|
||||
CustomPermissionsSchemes: 'true',
|
||||
GuestAccounts: 'true',
|
||||
GuestAccountsPermissions: 'true',
|
||||
CustomTermsOfService: 'true',
|
||||
LockTeammateNameDisplay: 'true',
|
||||
Cloud: 'false',
|
||||
SharedChannels: 'true',
|
||||
RemoteClusterService: 'true',
|
||||
OutgoingOAuthConnections: 'true',
|
||||
};
|
||||
}
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user