mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* Refactor property system with app layer routing and access control separation Establish the app layer as the primary entry point for property operations with intelligent routing based on group type. This architecture separates access-controlled operations (CPA groups) from standard operations, improving performance and code clarity. Architecture Changes: - App layer now routes operations based on group type: - CPA groups -> PropertyAccessService (enforces access control) - Non-CPA groups -> PropertyService (direct, no access control) - PropertyAccessService simplified to handle only CPA operations - Eliminated redundant group type checks throughout the codebase * Move access control routing into PropertyService This change makes the PropertyService the main entrypoint for property related operations, and adds a routing mechanism to decide if extra behaviors or checks should run for each operation, in this case, the property access service logic. To add specific payloads that pluggable checks and operations may need, we use the request context. When the request comes from the API, the endpoints are in charge of adding the caller ID to the payload, and in the case of the plugin API, on receiving a request, the server automatically tags the context with the plugin ID so the property service can react accordingly. Finally, the new design enforces all these checks migrating the actual property logic to internal, non-exposed methods, so any caller from the App layer needs to go through the service checks that decide if pluggable logic is needed, avoiding any possibility of a bypass. * Fix i18n * Fix bad error string * Added nil guards to property methods * Add check for multiple group IDs on value operations * Add nil guard to the plugin checker * Fix build error * Update value tests * Fix linter * Adds early return when content flaggin a thread with no replies * Fix mocks * Clean the state of plugin property tests before each run * Do not wrap appErr on API response and fix i18n * Fix create property field test * Remove the need to cache cpaGroupID as part of the property service * Split the property.go file into multiple * Not found group doesn't bypass access control check * Unexport SetPluginCheckerForTests * Rename plugin context getter to be more PSA specific --------- Co-authored-by: Miguel de la Cruz <[email protected]>
569 lines
17 KiB
Go
569 lines
17 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package commands
|
|
|
|
import (
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
|
|
)
|
|
|
|
// cleanCPAFields removes all existing CPA fields to ensure clean test state
|
|
func (s *MmctlE2ETestSuite) cleanCPAFields() {
|
|
existingFields, appErr := s.th.App.ListCPAFields(nil)
|
|
s.Require().Nil(appErr)
|
|
for _, field := range existingFields {
|
|
appErr := s.th.App.DeleteCPAField(nil, field.ID)
|
|
s.Require().Nil(appErr)
|
|
}
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestCPAFieldListCmd() {
|
|
s.SetupEnterpriseTestHelper().InitBasic(s.T())
|
|
s.th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
|
|
|
s.RunForSystemAdminAndLocal("List CPA fields with no entries", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
err := cpaFieldListCmdF(c, &cobra.Command{}, []string{})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 0) // No fields should be present initially
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("List CPA fields with entries", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// Create a couple of test CPA fields
|
|
textField := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Department",
|
|
Type: model.PropertyFieldTypeText,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Managed: "admin",
|
|
},
|
|
}
|
|
|
|
selectField := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Level",
|
|
Type: model.PropertyFieldTypeSelect,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Managed: "",
|
|
Options: []*model.CustomProfileAttributesSelectOption{
|
|
{ID: model.NewId(), Name: "Junior"},
|
|
{ID: model.NewId(), Name: "Senior"},
|
|
},
|
|
},
|
|
}
|
|
|
|
createdTextField, appErr := s.th.App.CreateCPAField(nil, textField)
|
|
s.Require().Nil(appErr)
|
|
s.Require().NotNil(createdTextField)
|
|
|
|
createdSelectField, appErr := s.th.App.CreateCPAField(nil, selectField)
|
|
s.Require().Nil(appErr)
|
|
s.Require().NotNil(createdSelectField)
|
|
|
|
// Now test the list command
|
|
err := cpaFieldListCmdF(c, &cobra.Command{}, []string{})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 2) // Should have 2 fields now
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the output contains our created fields
|
|
lines := printer.GetLines()
|
|
s.Require().Len(lines, 2, "Should have exactly 2 output lines for 2 fields")
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestCPAFieldCreateCmd() {
|
|
s.SetupEnterpriseTestHelper().InitBasic(s.T())
|
|
s.th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
|
|
|
s.RunForSystemAdminAndLocal("Create managed text field", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// Create command with arguments and managed flag
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
// Set the managed flag to true
|
|
err := cmd.Flags().Set("managed", "true")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldCreateCmdF(c, cmd, []string{"Department", "text"})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Field Department correctly created")
|
|
|
|
// Verify field was actually created in the database
|
|
fields, appErr := s.th.App.ListCPAFields(nil)
|
|
s.Require().Nil(appErr)
|
|
s.Require().Len(fields, 1)
|
|
s.Require().Equal("Department", fields[0].Name)
|
|
s.Require().Equal(model.PropertyFieldTypeText, fields[0].Type)
|
|
s.Require().Equal("admin", fields[0].Attrs.Managed)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Create multiselect field with options", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// Create command with arguments and option flags
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
// Set the option flags
|
|
err := cmd.Flags().Set("option", "Go")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "React")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "Python")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldCreateCmdF(c, cmd, []string{"Skills", "multiselect"})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Field Skills correctly created")
|
|
|
|
// Verify field was actually created in the database with correct options
|
|
fields, appErr := s.th.App.ListCPAFields(nil)
|
|
s.Require().Nil(appErr)
|
|
s.Require().Len(fields, 1)
|
|
s.Require().Equal("Skills", fields[0].Name)
|
|
s.Require().Equal(model.PropertyFieldTypeMultiselect, fields[0].Type)
|
|
|
|
// Verify the options were created
|
|
s.Require().Len(fields[0].Attrs.Options, 3)
|
|
|
|
// Extract option names to verify they match what we set
|
|
var optionNames []string
|
|
for _, option := range fields[0].Attrs.Options {
|
|
optionNames = append(optionNames, option.Name)
|
|
}
|
|
s.Require().Contains(optionNames, "Go")
|
|
s.Require().Contains(optionNames, "React")
|
|
s.Require().Contains(optionNames, "Python")
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestCPAFieldEditCmd() {
|
|
s.SetupEnterpriseTestHelper().InitBasic(s.T())
|
|
s.th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
|
|
|
s.RunForSystemAdminAndLocal("Edit nonexistent field should fail", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("name", "", "")
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
err := cmd.Flags().Set("name", "New Name")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldEditCmdF(c, cmd, []string{"nonexistent-field-id"})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), "failed to get field for \"nonexistent-field-id\"")
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Edit field using --name and --option flags", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a field to edit
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Skills",
|
|
Type: model.PropertyFieldTypeSelect,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Options: []*model.CustomProfileAttributesSelectOption{
|
|
{ID: model.NewId(), Name: "Go"},
|
|
},
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Now edit the field
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("name", "", "")
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
err := cmd.Flags().Set("name", "Programming Languages")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "Go")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "Python")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldEditCmdF(c, cmd, []string{createdField.ID})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Field Programming Languages successfully updated")
|
|
|
|
// Verify field was actually updated
|
|
updatedField, appErr := s.th.App.GetCPAField(nil, createdField.ID)
|
|
s.Require().Nil(appErr)
|
|
s.Require().Equal("Programming Languages", updatedField.Name)
|
|
|
|
// Check options
|
|
s.Require().Len(updatedField.Attrs.Options, 2)
|
|
|
|
var optionNames []string
|
|
for _, option := range updatedField.Attrs.Options {
|
|
optionNames = append(optionNames, option.Name)
|
|
}
|
|
s.Require().Contains(optionNames, "Go")
|
|
s.Require().Contains(optionNames, "Python")
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Edit field using --managed flag", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a field to edit
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Department",
|
|
Type: model.PropertyFieldTypeText,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Managed: "",
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Now edit the field with --managed flag
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("name", "", "")
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
err := cmd.Flags().Set("managed", "true")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldEditCmdF(c, cmd, []string{createdField.ID})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify field was actually updated
|
|
updatedField, appErr := s.th.App.GetCPAField(nil, createdField.ID)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Verify that managed flag was set correctly
|
|
s.Require().Equal("admin", updatedField.Attrs.Managed)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Edit field by name", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a field to edit
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Department",
|
|
Type: model.PropertyFieldTypeText,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Managed: "",
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Now edit the field using its name instead of ID
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("name", "", "")
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
err := cmd.Flags().Set("name", "Team")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("managed", "true")
|
|
s.Require().Nil(err)
|
|
|
|
// Edit using field name "Department" instead of the field ID
|
|
err = cpaFieldEditCmdF(c, cmd, []string{"Department"})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Field Team successfully updated")
|
|
|
|
// Verify field was actually updated by retrieving it
|
|
updatedField, appErr := s.th.App.GetCPAField(nil, createdField.ID)
|
|
s.Require().Nil(appErr)
|
|
s.Require().Equal("Team", updatedField.Name)
|
|
|
|
// Check managed status
|
|
s.Require().Equal("admin", updatedField.Attrs.Managed)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Edit multiselect field with option preservation", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a multiselect field with two options
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Programming Languages",
|
|
Type: model.PropertyFieldTypeMultiselect,
|
|
TargetType: "user",
|
|
},
|
|
Attrs: model.CPAAttrs{
|
|
Options: []*model.CustomProfileAttributesSelectOption{
|
|
{ID: model.NewId(), Name: "Go"},
|
|
{ID: model.NewId(), Name: "Python"},
|
|
},
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Get the original option IDs to verify they are preserved
|
|
s.Require().Len(createdField.Attrs.Options, 2)
|
|
|
|
originalGoID := ""
|
|
originalPythonID := ""
|
|
for _, option := range createdField.Attrs.Options {
|
|
switch option.Name {
|
|
case "Go":
|
|
originalGoID = option.ID
|
|
case "Python":
|
|
originalPythonID = option.ID
|
|
}
|
|
}
|
|
s.Require().NotEmpty(originalGoID)
|
|
s.Require().NotEmpty(originalPythonID)
|
|
|
|
// Now edit the field to add a third option while preserving the first two
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("name", "", "")
|
|
cmd.Flags().Bool("managed", false, "")
|
|
cmd.Flags().String("attrs", "", "")
|
|
cmd.Flags().StringSlice("option", []string{}, "")
|
|
|
|
err := cmd.Flags().Set("option", "Go")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "Python")
|
|
s.Require().Nil(err)
|
|
err = cmd.Flags().Set("option", "React")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldEditCmdF(c, cmd, []string{createdField.ID})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Field Programming Languages successfully updated")
|
|
|
|
// Verify field was actually updated and options are preserved correctly
|
|
updatedField, appErr := s.th.App.GetCPAField(nil, createdField.ID)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Check options
|
|
s.Require().Len(updatedField.Attrs.Options, 3)
|
|
|
|
// Verify the first two options preserved their original IDs and the third is new
|
|
foundGo := false
|
|
foundPython := false
|
|
foundReact := false
|
|
|
|
for _, option := range updatedField.Attrs.Options {
|
|
switch option.Name {
|
|
case "Go":
|
|
s.Require().Equal(originalGoID, option.ID, "Go option should preserve its original ID")
|
|
foundGo = true
|
|
case "Python":
|
|
s.Require().Equal(originalPythonID, option.ID, "Python option should preserve its original ID")
|
|
foundPython = true
|
|
case "React":
|
|
s.Require().NotEmpty(option.ID, "React option should have a valid ID")
|
|
s.Require().NotEqual(originalGoID, option.ID, "React option should have a different ID than Go")
|
|
s.Require().NotEqual(originalPythonID, option.ID, "React option should have a different ID than Python")
|
|
foundReact = true
|
|
}
|
|
}
|
|
|
|
s.Require().True(foundGo, "Go option should be present")
|
|
s.Require().True(foundPython, "Python option should be present")
|
|
s.Require().True(foundReact, "React option should be present")
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestCPAFieldDeleteCmd() {
|
|
s.SetupEnterpriseTestHelper().InitBasic(s.T())
|
|
s.th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
|
|
|
s.RunForSystemAdminAndLocal("Delete existing field", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a field to delete
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Department",
|
|
Type: model.PropertyFieldTypeText,
|
|
TargetType: "user",
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("confirm", false, "")
|
|
|
|
err := cmd.Flags().Set("confirm", "true")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldDeleteCmdF(c, cmd, []string{createdField.ID})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Successfully deleted CPA field")
|
|
|
|
// Verify field was actually deleted by checking if it exists in the list
|
|
fields, appErr := s.th.App.ListCPAFields(nil)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Field should not be in the list anymore
|
|
fieldExists := false
|
|
for _, field := range fields {
|
|
if field.ID == createdField.ID {
|
|
fieldExists = true
|
|
break
|
|
}
|
|
}
|
|
s.Require().False(fieldExists, "Field should have been deleted but still exists in the list")
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Delete existing field by name", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
// First create a field to delete
|
|
field := &model.CPAField{
|
|
PropertyField: model.PropertyField{
|
|
Name: "Department",
|
|
Type: model.PropertyFieldTypeText,
|
|
TargetType: "user",
|
|
},
|
|
}
|
|
|
|
createdField, appErr := s.th.App.CreateCPAField(nil, field)
|
|
s.Require().Nil(appErr)
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("confirm", false, "")
|
|
|
|
err := cmd.Flags().Set("confirm", "true")
|
|
s.Require().Nil(err)
|
|
|
|
// Delete using field name instead of ID
|
|
err = cpaFieldDeleteCmdF(c, cmd, []string{"Department"})
|
|
s.Require().Nil(err)
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Len(printer.GetErrorLines(), 0)
|
|
|
|
// Verify the success message
|
|
output := printer.GetLines()[0].(string)
|
|
s.Require().Contains(output, "Successfully deleted CPA field: Department")
|
|
|
|
// Verify field was actually deleted by checking if it exists in the list
|
|
fields, appErr := s.th.App.ListCPAFields(nil)
|
|
s.Require().Nil(appErr)
|
|
|
|
// Field should not be in the list anymore
|
|
fieldExists := false
|
|
for _, field := range fields {
|
|
if field.ID == createdField.ID {
|
|
fieldExists = true
|
|
break
|
|
}
|
|
}
|
|
s.Require().False(fieldExists, "Field should have been deleted but still exists in the list")
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Delete nonexistent field", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("confirm", false, "")
|
|
|
|
err := cmd.Flags().Set("confirm", "true")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldDeleteCmdF(c, cmd, []string{"nonexistent-field-id"})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), `failed to get field for "nonexistent-field-id"`)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("Delete nonexistent field by name", func(c client.Client) {
|
|
printer.Clean()
|
|
s.cleanCPAFields()
|
|
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().Bool("confirm", false, "")
|
|
|
|
err := cmd.Flags().Set("confirm", "true")
|
|
s.Require().Nil(err)
|
|
|
|
err = cpaFieldDeleteCmdF(c, cmd, []string{"NonexistentField"})
|
|
s.Require().NotNil(err)
|
|
s.Require().Contains(err.Error(), `failed to get field for "NonexistentField"`)
|
|
})
|
|
}
|