From 70a42ffd5fd8c8b701d2917949294d8aa8e1f30c Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Mon, 26 May 2025 15:44:32 -0300 Subject: [PATCH] Reject mysql for enterprise advanced (#31164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * reject MySQL with the enterprise advanced license If a user attempts to set an Enterprise Advanced License while configured with MySQL, reject the license. This SKU is not compatible with MYSQL. * fix trial typo * suppress trial banner if MySQL * Update server/channels/app/platform/license_test.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix types * suppress mysql from show start trial modal * Skip MySQL-incompatible tests for access control and channel banner features Skip the following tests when running with MySQL database: - Access control policy tests (create, get, delete, check/test expressions, search, assign/unassign, get channels) - Channel banner tests in TestPatchChannel and TestCanEditChannelBanner These features are not supported on MySQL and the tests would fail. Tests will continue to run normally on PostgreSQL. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Skip TestSearchChannelsForAccessControlPolicy subtest for MySQL Add MySQL skip logic to the "SearchChannelsForAccessControlPolicy with regular user" subtest as this access control feature is not supported on MySQL. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * reject trial license requests for MySQL * return false on sku + mysql match, even if logger is nil * Fix MySQL trial license tests to skip appropriately based on database driver 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude --- server/channels/api4/access_control_test.go | 40 +++++++++++ server/channels/api4/channel_test.go | 16 +++++ server/channels/api4/license.go | 6 ++ server/channels/api4/license_test.go | 70 +++++++++++++++++++ server/channels/app/platform/license.go | 11 +++ server/channels/app/platform/license_test.go | 44 ++++++++++++ server/i18n/en.json | 8 +++ .../admin_console/license_settings/index.ts | 1 + .../license_settings.test.tsx | 1 + .../license_settings/license_settings.tsx | 4 +- .../trial_banner/trial_banner.tsx | 2 +- .../show_start_trial_modal.test.tsx | 38 ++++++++++ .../show_start_trial_modal.tsx | 6 +- webapp/channels/src/i18n/en.json | 2 +- 14 files changed, 244 insertions(+), 5 deletions(-) diff --git a/server/channels/api4/access_control_test.go b/server/channels/api4/access_control_test.go index 1727ec39d3..04fd4bfe7d 100644 --- a/server/channels/api4/access_control_test.go +++ b/server/channels/api4/access_control_test.go @@ -22,6 +22,10 @@ func TestCreateAccessControlPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicy := &model.AccessControlPolicy{ Type: model.AccessControlPolicyTypeChannel, Version: model.AccessControlPolicyVersionV0_1, @@ -89,6 +93,10 @@ func TestGetAccessControlPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicy := &model.AccessControlPolicy{ ID: model.NewId(), Type: model.AccessControlPolicyTypeChannel, @@ -152,6 +160,10 @@ func TestDeleteAccessControlPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicyID := model.NewId() t.Run("DeleteAccessControlPolicy without license", func(t *testing.T) { @@ -202,6 +214,10 @@ func TestCheckExpression(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + t.Run("CheckExpression without license", func(t *testing.T) { _, resp, err := th.SystemAdminClient.CheckExpression(context.Background(), "true") require.Error(t, err) @@ -275,6 +291,10 @@ func TestTestExpression(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + t.Run("TestExpression without license", func(t *testing.T) { _, resp, err := th.SystemAdminClient.TestExpression(context.Background(), model.QueryExpressionParams{}) require.Error(t, err) @@ -327,6 +347,10 @@ func TestSearchAccessControlPolicies(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + t.Run("SearchAccessControlPolicies without license", func(t *testing.T) { _, resp, err := th.SystemAdminClient.SearchAccessControlPolicies(context.Background(), model.AccessControlPolicySearch{}) require.Error(t, err) @@ -381,6 +405,10 @@ func TestAssignAccessPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicy := &model.AccessControlPolicy{ ID: model.NewId(), Type: model.AccessControlPolicyTypeParent, @@ -448,6 +476,10 @@ func TestUnassignAccessPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicy := &model.AccessControlPolicy{ ID: model.NewId(), Type: model.AccessControlPolicyTypeParent, @@ -519,6 +551,10 @@ func TestGetChannelsForAccessControlPolicy(t *testing.T) { os.Unsetenv("MM_FEATUREFLAGS_ATTRIBUTEBASEDACCESSCONTROL") }) + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + samplePolicy := &model.AccessControlPolicy{ ID: model.NewId(), Type: model.AccessControlPolicyTypeParent, @@ -596,6 +632,10 @@ func TestSearchChannelsForAccessControlPolicy(t *testing.T) { } t.Run("SearchChannelsForAccessControlPolicy with regular user", func(t *testing.T) { + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Access control tests are not supported on MySQL") + } + ok := th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)) require.True(t, ok, "SetLicense should return true") diff --git a/server/channels/api4/channel_test.go b/server/channels/api4/channel_test.go index 17428d12a0..54c71b9c69 100644 --- a/server/channels/api4/channel_test.go +++ b/server/channels/api4/channel_test.go @@ -810,6 +810,10 @@ func TestPatchChannel(t *testing.T) { }) t.Run("Should be able to configure channel banner on a channel", func(t *testing.T) { + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Channel banner tests are not supported on MySQL") + } + client.Logout(context.Background()) th.LoginBasic() th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)) @@ -866,6 +870,10 @@ func TestPatchChannel(t *testing.T) { }) t.Run("Should be able to configure channel banner as a team admin", func(t *testing.T) { + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Channel banner tests are not supported on MySQL") + } + client.Logout(context.Background()) th.LoginTeamAdmin() th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)) @@ -891,6 +899,10 @@ func TestPatchChannel(t *testing.T) { }) t.Run("Cannot enable channel banner without configuring it", func(t *testing.T) { + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Channel banner tests are not supported on MySQL") + } + client.Logout(context.Background()) th.LoginBasic() th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)) @@ -1010,6 +1022,10 @@ func TestCanEditChannelBanner(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() + if *mainHelper.GetSQLSettings().DriverName == model.DatabaseDriverMysql { + t.Skip("Channel banner tests are not supported on MySQL") + } + t.Run("when license is nil", func(t *testing.T) { channel := &model.Channel{ Type: model.ChannelTypeOpen, diff --git a/server/channels/api4/license.go b/server/channels/api4/license.go index 08257c492e..a113b97b2f 100644 --- a/server/channels/api4/license.go +++ b/server/channels/api4/license.go @@ -186,6 +186,12 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) { return } + // MySQL is not supported for trial licenses + if c.App.Config().SqlSettings.DriverName != nil && *c.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + c.Err = model.NewAppError("requestTrialLicense", "api.license.request-trial.mysql.app_error", nil, "mysql is not supported for trial licenses", http.StatusBadRequest) + return + } + if c.App.Srv().Platform().LicenseManager() == nil { c.Err = model.NewAppError("requestTrialLicense", "api.license.upgrade_needed.app_error", nil, "", http.StatusForbidden) return diff --git a/server/channels/api4/license_test.go b/server/channels/api4/license_test.go index 693cf08fac..a8d9bbf5d8 100644 --- a/server/channels/api4/license_test.go +++ b/server/channels/api4/license_test.go @@ -258,7 +258,27 @@ func TestRequestTrialLicenseWithExtraFields(t *testing.T) { CheckForbiddenStatus(t, resp) }) + t.Run("mysql database not supported", func(t *testing.T) { + // Skip this test unless running with MySQL driver + if *th.App.Config().SqlSettings.DriverName != model.DatabaseDriverMysql { + t.Skip("Skipping test - only runs with MySQL driver") + } + + licenseManagerMock := &mocks.LicenseInterface{} + licenseManagerMock.On("CanStartTrial").Return(true, nil).Once() + th.App.Srv().Platform().SetLicenseManager(licenseManagerMock) + + resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(context.Background(), validTrialRequest) + CheckErrorID(t, err, "api.license.request-trial.mysql.app_error") + CheckBadRequestStatus(t, resp) + }) + t.Run("trial license user count less than current users", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + license := model.NewTestLicense() license.Features.Users = model.NewPointer(nUsers) licenseJSON, jsonErr := json.Marshal(license) @@ -295,6 +315,11 @@ func TestRequestTrialLicenseWithExtraFields(t *testing.T) { }) t.Run("returns status 451 when it receives status 451", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + license := model.NewTestLicense() license.Features.Users = model.NewPointer(nUsers) licenseJSON, jsonErr := json.Marshal(license) @@ -325,6 +350,11 @@ func TestRequestTrialLicenseWithExtraFields(t *testing.T) { }) t.Run("returns status 400 if request is a mix of legacy and new fields", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + validTrialRequest.CompanyCountry = "" validTrialRequest.Users = 100 defer func() { validTrialRequest.CompanyCountry = "US" }() @@ -365,6 +395,11 @@ func TestRequestTrialLicenseWithExtraFields(t *testing.T) { th.App.Srv().Platform().SetLicenseManager(nil) t.Run("trial license should fail if LicenseManager is nil", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(context.Background(), validTrialRequest) CheckErrorID(t, err, "api.license.upgrade_needed.app_error") CheckForbiddenStatus(t, resp) @@ -387,7 +422,27 @@ func TestRequestTrialLicense(t *testing.T) { CheckForbiddenStatus(t, resp) }) + t.Run("mysql database not supported", func(t *testing.T) { + // Skip this test unless running with MySQL driver + if *th.App.Config().SqlSettings.DriverName != model.DatabaseDriverMysql { + t.Skip("Skipping test - only runs with MySQL driver") + } + + licenseManagerMock := &mocks.LicenseInterface{} + licenseManagerMock.On("CanStartTrial").Return(true, nil).Once() + th.App.Srv().Platform().SetLicenseManager(licenseManagerMock) + + resp, err := th.SystemAdminClient.RequestTrialLicense(context.Background(), 1000) + CheckErrorID(t, err, "api.license.request-trial.mysql.app_error") + CheckBadRequestStatus(t, resp) + }) + t.Run("trial license invalid JSON", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + // the JSON is invalid because it is missing a closing brace licenseManagerMock := &mocks.LicenseInterface{} @@ -400,6 +455,11 @@ func TestRequestTrialLicense(t *testing.T) { }) t.Run("trial license user count less than current users", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + nUsers := 1 license := model.NewTestLicense() license.Features.Users = model.NewPointer(nUsers) @@ -435,6 +495,11 @@ func TestRequestTrialLicense(t *testing.T) { }) t.Run("returns status 451 when it receives status 451", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + nUsers := 1 license := model.NewTestLicense() license.Features.Users = model.NewPointer(nUsers) @@ -467,6 +532,11 @@ func TestRequestTrialLicense(t *testing.T) { th.App.Srv().Platform().SetLicenseManager(nil) t.Run("trial license should fail if LicenseManager is nil", func(t *testing.T) { + // Skip this test when MySQL is configured as it hits the MySQL check first + if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + t.Skip("Skipping test - MySQL does not support trial licenses") + } + resp, err := th.SystemAdminClient.RequestTrialLicense(context.Background(), 1) CheckErrorID(t, err, "api.license.upgrade_needed.app_error") CheckForbiddenStatus(t, resp) diff --git a/server/channels/app/platform/license.go b/server/channels/app/platform/license.go index 87bb48ad1e..f516eb35f6 100644 --- a/server/channels/app/platform/license.go +++ b/server/channels/app/platform/license.go @@ -134,6 +134,10 @@ func (ps *PlatformService) SaveLicense(licenseBytes []byte) (*model.License, *mo return nil, model.NewAppError("addLicense", "api.license.add_license.invalid.app_error", nil, "", http.StatusBadRequest).Wrap(errors.New("license.Features.Users is nil")) } + if license.SkuShortName == model.LicenseShortSkuEnterpriseAdvanced && *ps.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + return nil, model.NewAppError("addLicense", "api.license.add_license.mysql.app_error", nil, "", http.StatusBadRequest).Wrap(errors.New("mysql is not supported for this license")) + } + uniqueUserCount, err := ps.Store.User().Count(model.UserCountOptions{}) if err != nil { return nil, model.NewAppError("addLicense", "api.license.add_license.invalid_count.app_error", nil, "", http.StatusBadRequest).Wrap(err) @@ -225,6 +229,13 @@ func (ps *PlatformService) SaveLicense(licenseBytes []byte) (*model.License, *mo } func (ps *PlatformService) SetLicense(license *model.License) bool { + if license != nil && license.SkuShortName == model.LicenseShortSkuEnterpriseAdvanced && *ps.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + if ps.logger != nil { + ps.logger.Error("MySQL is not supported for this license", mlog.String("sku_short_name", license.SkuShortName)) + } + return false + } + oldLicense := ps.licenseValue.Load() defer func() { diff --git a/server/channels/app/platform/license_test.go b/server/channels/app/platform/license_test.go index 6df2a84bfe..13d5ed3ced 100644 --- a/server/channels/app/platform/license_test.go +++ b/server/channels/app/platform/license_test.go @@ -4,12 +4,17 @@ package platform import ( + "encoding/json" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/mattermost/mattermost/server/public/model" + "github.com/mattermost/mattermost/server/public/plugin/plugintest/mock" + "github.com/mattermost/mattermost/server/v8/channels/utils" + mocks2 "github.com/mattermost/mattermost/server/v8/channels/utils/mocks" + "github.com/mattermost/mattermost/server/v8/channels/utils/testutils" ) func TestLoadLicense(t *testing.T) { @@ -30,6 +35,45 @@ func TestSaveLicense(t *testing.T) { require.NotNil(t, err, "shouldn't have saved license") } +func TestSaveEnterpriseAdvancedLicense(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + defer testutils.ResetLicenseValidator() + mockLicenseValidator := mocks2.LicenseValidatorIface{} + + license := &model.License{ + Id: model.NewId(), + Features: &model.Features{ + Users: model.NewPointer(100), + }, + Customer: &model.Customer{ + Name: "TestName", + Email: "test@example.com", + }, + SkuName: "SKU NAME", + SkuShortName: model.LicenseShortSkuEnterpriseAdvanced, + StartsAt: model.GetMillis() - 1000, + ExpiresAt: model.GetMillis() + 100000, + } + + mockLicenseValidator.On("LicenseFromBytes", mock.Anything).Return(license, nil).Once() + licenseBytes, err := json.Marshal(license) + require.NoError(t, err) + + mockLicenseValidator.On("ValidateLicense", mock.Anything).Return(string(licenseBytes), nil) + utils.LicenseValidator = &mockLicenseValidator + + _, appErr := th.Service.SaveLicense(licenseBytes) + + if *th.Service.Config().SqlSettings.DriverName == model.DatabaseDriverMysql { + require.NotNil(t, appErr, "shouldn't have saved license") + require.Equal(t, "addLicense: api.license.add_license.mysql.app_error, mysql is not supported for this license", appErr.Error()) + } else { + require.Nil(t, appErr, "should have saved license") + } +} + func TestRemoveLicense(t *testing.T) { th := Setup(t) defer th.TearDown() diff --git a/server/i18n/en.json b/server/i18n/en.json index 0852408f8a..dd3713e705 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -2316,6 +2316,10 @@ "id": "api.license.add_license.invalid_count.app_error", "translation": "Unable to count total unique users." }, + { + "id": "api.license.add_license.mysql.app_error", + "translation": "This license does not support MySQL." + }, { "id": "api.license.add_license.no_file.app_error", "translation": "No file under 'license' in request." @@ -2368,6 +2372,10 @@ "id": "api.license.request-trial.can-start-trial.not-allowed", "translation": "Failed to apply new trial license as your workspace has already applied a trial license. If you would like to extend your trial period please [contact our sales team](https://mattermost.com/contact-us/)." }, + { + "id": "api.license.request-trial.mysql.app_error", + "translation": "Trial licenses are not supported for MySQL databases. Please use PostgreSQL to access trial features." + }, { "id": "api.license.request_trial_license.app_error", "translation": "Unable to get a trial license, please try again or contact with support@mattermost.com." diff --git a/webapp/channels/src/components/admin_console/license_settings/index.ts b/webapp/channels/src/components/admin_console/license_settings/index.ts index 8a080fde60..f80dbda713 100644 --- a/webapp/channels/src/components/admin_console/license_settings/index.ts +++ b/webapp/channels/src/components/admin_console/license_settings/index.ts @@ -26,6 +26,7 @@ function mapStateToProps(state: GlobalState) { totalUsers: selectFilteredUserStats(state)?.total_users_count || 0, upgradedFromTE: config.UpgradedFromTE === 'true', prevTrialLicense: state.entities.admin.prevTrialLicense, + isMySql: config.SQLDriverName === 'mysql', }; } diff --git a/webapp/channels/src/components/admin_console/license_settings/license_settings.test.tsx b/webapp/channels/src/components/admin_console/license_settings/license_settings.test.tsx index 20e3dc4574..29a25a1cab 100644 --- a/webapp/channels/src/components/admin_console/license_settings/license_settings.test.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/license_settings.test.tsx @@ -42,6 +42,7 @@ describe('components/admin_console/license_settings/LicenseSettings', () => { upgradedFromTE: false, enterpriseReady: true, totalUsers: 10, + isMySql: false, actions: { getLicenseConfig: jest.fn(), uploadLicense: jest.fn(), diff --git a/webapp/channels/src/components/admin_console/license_settings/license_settings.tsx b/webapp/channels/src/components/admin_console/license_settings/license_settings.tsx index 0a8e228953..abb846e797 100644 --- a/webapp/channels/src/components/admin_console/license_settings/license_settings.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/license_settings.tsx @@ -45,6 +45,7 @@ type Props = { totalUsers: number; isDisabled: boolean; prevTrialLicense: ClientLicense; + isMySql: boolean; actions: { getLicenseConfig: () => void; uploadLicense: (file: File) => Promise; @@ -280,7 +281,7 @@ export default class LicenseSettings extends React.PureComponent { ); render() { - const {license, upgradedFromTE, isDisabled} = this.props; + const {license, upgradedFromTE, isDisabled, isMySql} = this.props; let leftPanel = null; let rightPanel = null; @@ -362,6 +363,7 @@ export default class LicenseSettings extends React.PureComponent { /> {!this.state.clickNormalUpgradeBtn && license.IsLicensed !== 'true' && this.props.prevTrialLicense?.IsLicensed !== 'true' && + !isMySql && } message={ diff --git a/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.test.tsx b/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.test.tsx index f3960cfbd7..03d883a14f 100644 --- a/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.test.tsx +++ b/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.test.tsx @@ -266,6 +266,43 @@ describe('components/sidebar/show_start_trial_modal', () => { expect(mockDispatch).toHaveBeenCalledTimes(0); }); + test('should NOT dispatch the modal when database is MySQL', () => { + const isAdminUser = { + currentUserId: 'current_user_id', + profiles: { + current_user_id: {roles: 'system_admin system_user'}, + }, + }; + + const moreThan10Users = 11; + jest.spyOn(getTotalUsersHook, 'default').mockImplementation(() => moreThan10Users); + + const notPreviouslyLicensed = { + prevTrialLicense: { + IsLicensed: 'false', + }, + }; + + const moreThan6HoursWithMySQL = { + config: { + + // installation date is set to be 10 hours before current time + InstallationDate: new Date().getTime() - ((10 * 60 * 60) * 1000), + SQLDriverName: 'mysql', + }, + license: { + IsLicensed: 'false', + }, + }; + + mockState = {...mockState, entities: {...mockState.entities, users: isAdminUser, admin: notPreviouslyLicensed, general: moreThan6HoursWithMySQL}}; + + mount( + , + ); + expect(mockDispatch).toHaveBeenCalledTimes(0); + }); + test('should dispatch the modal when there are more than 10 users', () => { const isAdminUser = { currentUserId: 'current_user_id', @@ -288,6 +325,7 @@ describe('components/sidebar/show_start_trial_modal', () => { // installation date is set to be 10 hours before current time InstallationDate: new Date().getTime() - ((10 * 60 * 60) * 1000), + SQLDriverName: 'postgres', }, license: { IsLicensed: 'false', diff --git a/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.tsx b/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.tsx index a865628739..881bd95066 100644 --- a/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.tsx +++ b/webapp/channels/src/components/announcement_bar/show_start_trial_modal/show_start_trial_modal.tsx @@ -35,7 +35,9 @@ const ShowStartTrialModal = () => { const isBenefitsModalOpened = useSelector((state: GlobalState) => isModalOpen(state, ModalIdentifiers.TRIAL_BENEFITS_MODAL)); - const installationDate = useSelector((state: GlobalState) => getConfig(state).InstallationDate); + const config = useSelector((state: GlobalState) => getConfig(state)); + const installationDate = config.InstallationDate; + const isMySql = config.SQLDriverName === 'mysql'; const currentUser = useSelector((state: GlobalState) => getCurrentUser(state)); const hadAdminDismissedModal = useSelector((state: GlobalState) => getBool(state, Preferences.START_TRIAL_MODAL, Constants.TRIAL_MODAL_AUTO_SHOWN)); @@ -74,7 +76,7 @@ const ShowStartTrialModal = () => { const now = new Date().getTime(); const hasEnvMoreThan6Hours = now > installationDatePlus6Hours; const hasEnvMoreThan10Users = Number(totalUsers) > userThreshold; - if (isUserAdmin && !isBenefitsModalOpened && hasEnvMoreThan10Users && hasEnvMoreThan6Hours && !hadAdminDismissedModal && !isLicensedOrPreviousLicensed) { + if (isUserAdmin && !isMySql && !isBenefitsModalOpened && hasEnvMoreThan10Users && hasEnvMoreThan6Hours && !hadAdminDismissedModal && !isLicensedOrPreviousLicensed) { openStartTrialFormModal({trackingLocation: 'show_start_trial_modal'}, handleOnClose); trackEvent( TELEMETRY_CATEGORIES.SELF_HOSTED_START_TRIAL_AUTO_MODAL, diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 12fb9ee252..4e91743ed2 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -4471,7 +4471,7 @@ "leave_team_modal.no": "No", "leave_team_modal.title": "Leave the team?", "leave_team_modal.yes": "Yes", - "licensingPage.infoBanner.startTrialTitle": "Start a free 30-day tral of Mattermost Enterprise Advanced", + "licensingPage.infoBanner.startTrialTitle": "Start a free 30-day trial of Mattermost Enterprise Advanced", "licensingPage.overageUsersBanner.cta": "Contact Sales", "licensingPage.overageUsersBanner.noticeDescription": "Notify your Customer Success Manager on your next true-up check. ", "licensingPage.overageUsersBanner.noticeTitle": "Your workspace user count has exceeded your licensed seat count by {seats, number} {seats, plural, one {seat} other {seats}}",