[MM-51233] Updates for Trial Requests (#22620)

* Add new trial form to enrich trial requests with more customer info

* Update snapshots

* One more addition

* Fixes from PR feedback

* Fix types, i18n, update e2e tests

* Fix linter

* Fix i18n?

* Fix blank translation

* update snapshot

* Update snapshot properly

* Remove inapplicable test

* Fix business email validation only happening once

* UX Feedback

* Fix linter

* Fix linter again, not working locally

* FIX LINTER

* Move isvalid check until after some fields are set

* Fix for overlapping modals

* Fix linter

* UX feedback

* UX Feedback

* Fix typo in error modal

* [MM-51551] Add new Trial Form to Playbooks trial requests (#22650)

* Playbooks start trial entrypoints opens new trial form modal

* Fix style

---------

Co-authored-by: Mattermost Build <build@mattermost.com>

* [MM-51347] Trial form error modal for embargoed and air gapped entities (#22656)

* Playbooks start trial entrypoints opens new trial form modal

* Add support for air gapped environments when making trial requests

* Add specific handling for embargoed entities

* undo some code

* Fix linter

* Fix types

* Fix style

* Updates because TE has to upgrade to E0 before it can activate a trial

---------

Co-authored-by: Mattermost Build <build@mattermost.com>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Nick Misasi
2023-03-30 14:57:07 -04:00
коммит произвёл GitHub
родитель e09d5690a7
Коммит 957f999266
51 изменённых файлов: 2575 добавлений и 970 удалений

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

@@ -246,16 +246,6 @@ func validateBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.Channels().License().IsCloud() {
c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.license_error", nil, "", http.StatusForbidden)
return
}
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteBilling) {
c.SetPermissionError(model.PermissionSysconsoleWriteBilling)
return
}
user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if appErr != nil {
c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusForbidden).Wrap(appErr)

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

@@ -328,30 +328,6 @@ func Test_requestTrial(t *testing.T) {
}
func Test_validateBusinessEmail(t *testing.T) {
t.Run("Returns forbidden for non admin executors", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.Client.Login(th.BasicUser.Email, th.BasicUser.Password)
invalidEmail := model.ValidateBusinessEmailRequest{Email: "invalid@gmail.com"}
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
cloud := mocks.CloudInterface{}
cloud.Mock.On("ValidateBusinessEmail", th.SystemAdminUser.Id, invalidEmail.Email).Return(errors.New("invalid email"))
cloudImpl := th.App.Srv().Cloud
defer func() {
th.App.Srv().Cloud = cloudImpl
}()
th.App.Srv().Cloud = &cloud
res, err := th.Client.ValidateBusinessEmail(&invalidEmail)
require.Error(t, err)
require.Equal(t, http.StatusForbidden, res.StatusCode, "403")
})
t.Run("Returns forbidden for invalid business email", func(t *testing.T) {
th := Setup(t).InitBasic()

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

@@ -210,11 +210,7 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
var trialRequest struct {
Users int `json:"users"`
TermsAccepted bool `json:"terms_accepted"`
ReceiveEmailsAccepted bool `json:"receive_emails_accepted"`
}
var trialRequest *model.TrialLicenseRequest
b, readErr := io.ReadAll(r.Body)
if readErr != nil {
@@ -223,8 +219,16 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
}
json.Unmarshal(b, &trialRequest)
if err := c.App.Channels().RequestTrialLicense(c.AppContext.Session().UserId, trialRequest.Users, trialRequest.TermsAccepted, trialRequest.ReceiveEmailsAccepted); err != nil {
c.Err = err
var appErr *model.AppError
// If any of the newly supported trial request fields are set (ie, not a legacy request), process this as a new trial request (requiring the new fields) otherwise fall back on the old method.
if !trialRequest.IsLegacy() {
appErr = c.App.Channels().RequestTrialLicenseWithExtraFields(c.AppContext.Session().UserId, trialRequest)
} else {
appErr = c.App.Channels().RequestTrialLicense(c.AppContext.Session().UserId, trialRequest.Users, trialRequest.TermsAccepted, trialRequest.ReceiveEmailsAccepted)
}
if appErr != nil {
c.Err = appErr
return
}

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

@@ -223,6 +223,154 @@ func TestRemoveLicenseFile(t *testing.T) {
})
}
func TestRequestTrialLicenseWithExtraFields(t *testing.T) {
th := Setup(t)
defer th.TearDown()
licenseManagerMock := &mocks.LicenseInterface{}
licenseManagerMock.On("CanStartTrial").Return(true, nil)
th.App.Srv().Platform().SetLicenseManager(licenseManagerMock)
cloud := mocks.CloudInterface{}
cloudImpl := th.App.Srv().Cloud
defer func() {
th.App.Srv().Cloud = cloudImpl
}()
th.App.Srv().Cloud = &cloud
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SiteURL = "http://localhost:8065/" })
nUsers := 1
validTrialRequest := &model.TrialLicenseRequest{
Email: "test@mattermost.com",
Users: nUsers,
TermsAccepted: true,
CompanyCountry: "US",
CompanyName: "mattermost",
CompanySize: "1-10",
ContactName: "Matter Most",
}
t.Run("permission denied", func(t *testing.T) {
resp, err := th.Client.RequestTrialLicenseWithExtraFields(&model.TrialLicenseRequest{})
require.Error(t, err)
CheckForbiddenStatus(t, resp)
})
t.Run("trial license user count less than current users", func(t *testing.T) {
license := model.NewTestLicense()
license.Features.Users = model.NewInt(nUsers)
licenseJSON, jsonErr := json.Marshal(license)
require.NoError(t, jsonErr)
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)
response := map[string]string{
"license": string(licenseJSON),
}
err := json.NewEncoder(res).Encode(response)
require.NoError(t, err)
}))
defer testServer.Close()
mockLicenseValidator := mocks2.LicenseValidatorIface{}
defer testutils.ResetLicenseValidator()
mockLicenseValidator.On("ValidateLicense", mock.Anything).Return(true, string(licenseJSON))
utils.LicenseValidator = &mockLicenseValidator
licenseManagerMock := &mocks.LicenseInterface{}
licenseManagerMock.On("CanStartTrial").Return(true, nil).Once()
th.App.Srv().Platform().SetLicenseManager(licenseManagerMock)
originalCwsUrl := *th.App.Srv().Config().CloudSettings.CWSURL
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = testServer.URL })
defer func(requestTrialURL string) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = requestTrialURL })
}(originalCwsUrl)
cloud.On("ValidateBusinessEmail", mock.Anything, mock.Anything).Return(nil)
resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(validTrialRequest)
CheckErrorID(t, err, "api.license.add_license.unique_users.app_error")
CheckBadRequestStatus(t, resp)
})
t.Run("returns status 451 when it receives status 451", func(t *testing.T) {
license := model.NewTestLicense()
license.Features.Users = model.NewInt(nUsers)
licenseJSON, jsonErr := json.Marshal(license)
require.NoError(t, jsonErr)
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusUnavailableForLegalReasons)
}))
defer testServer.Close()
mockLicenseValidator := mocks2.LicenseValidatorIface{}
defer testutils.ResetLicenseValidator()
mockLicenseValidator.On("ValidateLicense", mock.Anything).Return(true, string(licenseJSON))
utils.LicenseValidator = &mockLicenseValidator
licenseManagerMock := &mocks.LicenseInterface{}
licenseManagerMock.On("CanStartTrial").Return(true, nil).Once()
th.App.Srv().Platform().SetLicenseManager(licenseManagerMock)
originalCwsUrl := *th.App.Srv().Config().CloudSettings.CWSURL
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = testServer.URL })
defer func(requestTrialURL string) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = requestTrialURL })
}(originalCwsUrl)
resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(validTrialRequest)
require.Error(t, err)
require.Equal(t, resp.StatusCode, 451)
})
t.Run("returns status 400 if request is a mix of legacy and new fields", func(t *testing.T) {
validTrialRequest.CompanyCountry = ""
validTrialRequest.Users = 100
defer func() { validTrialRequest.CompanyCountry = "US" }()
license := model.NewTestLicense()
license.Features.Users = model.NewInt(nUsers)
licenseJSON, jsonErr := json.Marshal(license)
require.NoError(t, jsonErr)
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)
response := map[string]string{
"license": string(licenseJSON),
}
err := json.NewEncoder(res).Encode(response)
require.NoError(t, err)
}))
defer testServer.Close()
mockLicenseValidator := mocks2.LicenseValidatorIface{}
defer testutils.ResetLicenseValidator()
mockLicenseValidator.On("ValidateLicense", mock.Anything).Return(true, string(licenseJSON))
utils.LicenseValidator = &mockLicenseValidator
licenseManagerMock := &mocks.LicenseInterface{}
licenseManagerMock.On("CanStartTrial").Return(true, nil).Once()
th.App.Srv().Platform().SetLicenseManager(licenseManagerMock)
originalCwsUrl := *th.App.Srv().Config().CloudSettings.CWSURL
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = testServer.URL })
defer func(requestTrialURL string) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.CloudSettings.CWSURL = requestTrialURL })
}(originalCwsUrl)
cloud.On("ValidateBusinessEmail", mock.Anything, mock.Anything).Return(nil)
resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(validTrialRequest)
CheckErrorID(t, err, "api.license.request-trial.bad-request")
CheckBadRequestStatus(t, resp)
})
th.App.Srv().Platform().SetLicenseManager(nil)
t.Run("trial license should fail if LicenseManager is nil", func(t *testing.T) {
resp, err := th.SystemAdminClient.RequestTrialLicenseWithExtraFields(validTrialRequest)
CheckErrorID(t, err, "api.license.upgrade_needed.app_error")
CheckForbiddenStatus(t, resp)
})
}
func TestRequestTrialLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()