mattermost/e2e-tests/cypress/tests/support/api/system.js

349 lines
12 KiB
JavaScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import merge from 'deepmerge';
import {Constants} from '../../utils';
import onPremDefaultConfig from './on_prem_default_config.json';
import cloudDefaultConfig from './cloud_default_config.json';
// *****************************************************************************
// System
// https://api.mattermost.com/#tag/system
// *****************************************************************************
function hasLicenseForFeature(license, key) {
let hasLicense = false;
for (const [k, v] of Object.entries(license)) {
if (k === key && v === 'true') {
hasLicense = true;
break;
}
}
return hasLicense;
}
Cypress.Commands.add('apiGetClientLicense', () => {
return cy.request('/api/v4/license/client?format=old').then((response) => {
expect(response.status).to.equal(200);
const license = response.body;
const isLicensed = license.IsLicensed === 'true';
const isCloudLicensed = hasLicenseForFeature(license, 'Cloud');
return cy.wrap({
license: response.body,
isLicensed,
isCloudLicensed,
});
});
});
Cypress.Commands.add('apiRequireLicenseForFeature', (...keys) => {
Cypress.log({name: 'EE License', message: `Checking if server has license for feature: __${Object.values(keys).join(', ')}__.`});
return uploadLicenseIfNotExist().then((data) => {
const {license, isLicensed} = data;
const hasLicenseMessage = `Server ${isLicensed ? 'has' : 'has no'} EE license.`;
expect(isLicensed, hasLicenseMessage).to.equal(true);
Object.values(keys).forEach((key) => {
const hasLicenseKey = hasLicenseForFeature(license, key);
const hasLicenseKeyMessage = `Server ${hasLicenseKey ? 'has' : 'has no'} EE license for feature: __${key}__`;
expect(hasLicenseKey, hasLicenseKeyMessage).to.equal(true);
});
return cy.wrap(data);
});
});
Cypress.Commands.add('apiRequireLicense', () => {
Cypress.log({name: 'EE License', message: 'Checking if server has license.'});
return uploadLicenseIfNotExist().then((data) => {
const hasLicenseMessage = `Server ${data.isLicensed ? 'has' : 'has no'} EE license.`;
expect(data.isLicensed, hasLicenseMessage).to.equal(true);
return cy.wrap(data);
});
});
Cypress.Commands.add('apiUploadLicense', (filePath) => {
cy.apiUploadFile('license', filePath, {url: '/api/v4/license', method: 'POST', successStatus: 200});
});
Cypress.Commands.add('apiInstallTrialLicense', () => {
return cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/trial-license',
method: 'POST',
body: {
receive_emails_accepted: true,
terms_accepted: true,
users: Cypress.env('numberOfTrialUsers'),
// Enriched fields required for trial license as of v10.7
company_country: 'US',
company_name: 'mattermost',
contact_email: 'test@mattermost.com',
company_size: '1-10',
contact_name: 'John Doe',
},
}).then((response) => {
expect(response.status).to.equal(200);
return cy.wrap(response.body);
});
});
Cypress.Commands.add('apiDeleteLicense', () => {
return cy.request({
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: '/api/v4/license',
method: 'DELETE',
}).then((response) => {
expect(response.status).to.equal(200);
return cy.wrap({response});
});
});
export const getDefaultConfig = () => {
const cypressEnv = Cypress.env();
const fromCypressEnv = {
ElasticsearchSettings: {
ConnectionURL: cypressEnv.elasticsearchConnectionURL,
},
EmailSettings: {
PushNotificationServer: cypressEnv.pushNotificationServer,
},
LdapSettings: {
LdapServer: cypressEnv.ldapServer,
LdapPort: cypressEnv.ldapPort,
},
ServiceSettings: {
AllowedUntrustedInternalConnections: cypressEnv.allowedUntrustedInternalConnections,
SiteURL: Cypress.config('baseUrl'),
},
};
const isCloud = cypressEnv.serverEdition === Constants.ServerEdition.CLOUD;
if (isCloud) {
fromCypressEnv.CloudSettings = {
CWSURL: cypressEnv.cwsURL,
CWSAPIURL: cypressEnv.cwsAPIURL,
};
}
const defaultConfig = isCloud ? cloudDefaultConfig : onPremDefaultConfig;
return merge(defaultConfig, fromCypressEnv);
};
const expectConfigToBeUpdatable = (currentConfig, newConfig) => {
function errorMessage(name) {
return `${name} is restricted or not available to update. You may check user/sysadmin access, license requirement, server version or edition (on-prem/cloud) compatibility.`;
}
Object.entries(newConfig).forEach(([newMainKey, newSubSetting]) => {
const setting = currentConfig[newMainKey];
if (setting) {
Object.keys(newSubSetting).forEach((newSubKey) => {
const isAvailable = Object.hasOwn(setting, newSubKey);
const name = `${newMainKey}.${newSubKey}`;
expect(isAvailable, isAvailable ? `${name} setting can be updated.` : errorMessage(name)).to.equal(true);
});
} else {
const withSetting = Boolean(setting);
expect(withSetting, withSetting ? `${newMainKey} setting can be updated.` : errorMessage(newMainKey)).to.equal(true);
}
});
};
Cypress.Commands.add('apiUpdateConfig', (newConfig = {}) => {
// # Get current config
return cy.apiGetConfig().then(({config: currentConfig}) => {
// * Check if config can be updated
expectConfigToBeUpdatable(currentConfig, newConfig);
const config = merge.all([currentConfig, getDefaultConfig(), newConfig]);
// # Set the modified config
return cy.getCookie('MMCSRF').then((csrfCookie) => {
let headers;
if (csrfCookie?.value) {
headers = {'X-CSRF-Token': csrfCookie.value};
}
return cy.request({
url: '/api/v4/config',
method: 'PUT',
body: config,
headers,
}).then((updateResponse) => {
expect(updateResponse.status).to.equal(200);
return cy.apiGetConfig();
});
});
});
});
Cypress.Commands.add('apiReloadConfig', () => {
// # Reload the config
return cy.request({
url: '/api/v4/config/reload',
headers: {'X-Requested-With': 'XMLHttpRequest'},
method: 'POST',
}).then((reloadResponse) => {
expect(reloadResponse.status).to.equal(200);
return cy.apiGetConfig();
});
});
Cypress.Commands.add('apiGetConfig', (old = false) => {
// # Get current settings
return cy.request(`/api/v4/config${old ? '/client?format=old' : ''}`).then((response) => {
expect(response.status).to.equal(200);
return cy.wrap({config: response.body});
});
});
Cypress.Commands.add('apiEnsureFeatureFlag', (key, value) => {
cy.apiGetConfig().then(({config}) => {
cy.log(JSON.stringify(config.PluginSettings.Plugins.playbooks));
const currentValue = config.PluginSettings.Plugins.playbooks[key];
if (currentValue !== value) {
cy.apiUpdateConfig({
PluginSettings: {Plugins: {playbooks: {[key]: value}}},
}).then(() => {
return cy.wrap({prevValue: currentValue, value});
});
}
return cy.wrap({prevValue: currentValue, value});
});
});
Cypress.Commands.add('apiGetAnalytics', () => {
cy.apiAdminLogin();
return cy.request('/api/v4/analytics/old').then((response) => {
expect(response.status).to.equal(200);
return cy.wrap({analytics: response.body});
});
});
Cypress.Commands.add('apiInvalidateCache', () => {
return cy.request({
url: '/api/v4/caches/invalidate',
headers: {'X-Requested-With': 'XMLHttpRequest'},
method: 'POST',
}).then((response) => {
expect(response.status).to.equal(200);
return cy.wrap(response);
});
});
function isCloudEdition() {
return cy.apiGetClientLicense().then(({isCloudLicensed}) => {
return cy.wrap(isCloudLicensed);
});
}
Cypress.Commands.add('shouldNotRunOnCloudEdition', () => {
isCloudEdition().then((isCloud) => {
expect(isCloud, isCloud ? 'Should not run on Cloud server' : '').to.equal(false);
});
});
function isTeamEdition() {
return cy.apiGetClientLicense().then(({isLicensed}) => {
return cy.wrap(!isLicensed);
});
}
Cypress.Commands.add('shouldRunOnTeamEdition', () => {
isTeamEdition().then((isTeam) => {
expect(isTeam, isTeam ? '' : 'Should run on Team edition only').to.equal(true);
});
});
function isElasticsearchEnabled() {
return cy.apiGetConfig().then(({config}) => {
let isEnabled = false;
if (config.ElasticsearchSettings) {
const {EnableAutocomplete, EnableIndexing, EnableSearching} = config.ElasticsearchSettings;
isEnabled = EnableAutocomplete && EnableIndexing && EnableSearching;
}
return cy.wrap(isEnabled);
});
}
Cypress.Commands.add('shouldHaveElasticsearchDisabled', () => {
isElasticsearchEnabled().then((data) => {
expect(data, data ? 'Should have Elasticsearch disabled' : '').to.equal(false);
});
});
Cypress.Commands.add('shouldHavePluginUploadEnabled', () => {
return cy.apiGetConfig().then(({config}) => {
const isUploadEnabled = config.PluginSettings.EnableUploads;
expect(isUploadEnabled, isUploadEnabled ? '' : 'Should have Plugin upload enabled').to.equal(true);
});
});
Cypress.Commands.add('shouldHaveClusterEnabled', () => {
return cy.apiGetConfig().then(({config}) => {
const {Enable, ClusterName} = config.ClusterSettings;
expect(Enable, Enable ? '' : 'Should have cluster enabled').to.equal(true);
const sameClusterName = ClusterName === Cypress.env('serverClusterName');
expect(sameClusterName, sameClusterName ? '' : `Should have cluster name set and as expected. Got "${ClusterName}" but expected "${Cypress.env('serverClusterName')}"`).to.equal(true);
});
});
Cypress.Commands.add('shouldRunWithSubpath', () => {
return cy.apiGetConfig().then(({config}) => {
const isSubpath = Boolean(config.ServiceSettings.SiteURL.replace(/^https?:\/\//, '').split('/')[1]);
expect(isSubpath, isSubpath ? '' : 'Should run on server running with subpath only').to.equal(true);
});
});
Cypress.Commands.add('shouldHaveFeatureFlag', (key, expectedValue) => {
return cy.apiGetConfig().then(({config}) => {
const actualValue = config.FeatureFlags[key];
const message = actualValue === expectedValue ?
`Matches feature flag - "${key}: ${expectedValue}"` :
`Expected feature flag "${key}" to be "${expectedValue}", but was "${actualValue}"`;
expect(actualValue, message).to.equal(expectedValue);
});
});
Cypress.Commands.add('shouldHaveEmailEnabled', () => {
return cy.apiGetConfig().then(({config}) => {
if (!config.ExperimentalSettings.RestrictSystemAdmin) {
cy.apiEmailTest();
}
});
});
/**
* Upload a license if it does not exist.
*/
function uploadLicenseIfNotExist() {
return cy.apiGetClientLicense().then((data) => {
if (data.isLicensed) {
return cy.wrap(data);
}
return cy.apiInstallTrialLicense().then(() => {
return cy.apiGetClientLicense();
});
});
}