Files
team/server/public/model/feature_flags_test.go
845b674d4c [release-11.9] [MM-69528] Enable feature flags for ranked attributes, permission policies and masking by default (#37306)
* [MM-69528] Enable feature flags for ranked attributes, permission policies and masking by default (#37265)

* [MM-69528] Enable feature flags for ranked attributes, permission policies and masking

Change the default value to true for AttributeValueMasking,
PermissionPolicies, ChannelPermissionPolicies, PolicySimulation and
PropertyFieldRank, and update the unit tests and a stale comment that
pinned the old defaults.

Co-authored-by: mattermost-code <[email protected]>

* Fix access control tests for feature flags enabled by default

Tests that assumed AttributeValueMasking, PermissionPolicies, and
PolicySimulation were off by default now explicitly disable those flags
in setup or use SetReadOnlyFF(false) before runtime UpdateConfig calls.

Co-authored-by: mattermost-code <[email protected]>

* Add regression test for PropertyFieldRank default

Co-authored-by: mattermost-code <[email protected]>

* Disable masking in store-mock tests that assume flag off

Co-authored-by: mattermost-code <[email protected]>

* Fix store-mock masking helper without UpdateConfig

UpdateConfig triggers config persistence listeners that call
Store.Post() on the mock store. Mutate feature flags in place instead.

Co-authored-by: mattermost-code <[email protected]>

* Fix masking-off deactivation test for new flag default

Co-authored-by: mattermost-code <[email protected]>

* Fix Setup/InitBasic compile errors in access control tests

Pass testing.TB to Setup and InitBasic after removing redundant
feature-flag SetupConfig wrappers.

Co-authored-by: mattermost-code <[email protected]>

* Restore ABAC feature-flag defaults in test cleanup

Defer blocks in access_control_test.go were resetting PermissionPolicies,
ChannelPermissionPolicies, and PolicySimulation to false after subtests,
leaving the shared TestHelper in a partially-disabled state. With these
flags now defaulting to true, cleanup should restore the default-enabled
baseline instead.

Co-authored-by: mattermost-code <[email protected]>

---------

Co-authored-by: mattermost-code <[email protected]>

* Fix flaky LDAP concurrency test mock setup race

Register DoLogin mock expectations before launching goroutines.
Concurrent mock.On calls inside goroutines caused testify panics
(no return value specified for DoLogin) and aborted shard 0 CI.

Co-authored-by: mattermost-code <[email protected]>

* Revert "Fix flaky LDAP concurrency test mock setup race"

This reverts commit ad31a81ea0e0d709b426cdc3227ac1b50580a0f0.

---------

Co-authored-by: mattermost-code <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-01 08:19:16 +03:00

142 lines
4.3 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestFeatureFlagsSetDefaults(t *testing.T) {
f := &FeatureFlags{}
f.SetDefaults()
t.Run("ClassificationMarkings should default to true", func(t *testing.T) {
require.True(t, f.ClassificationMarkings)
})
t.Run("ClassificationMarkings should serialize correctly", func(t *testing.T) {
m := f.ToMap()
require.Equal(t, "true", m["ClassificationMarkings"])
f.ClassificationMarkings = false
m = f.ToMap()
require.Equal(t, "false", m["ClassificationMarkings"])
})
}
func TestFeatureFlagsToMap(t *testing.T) {
for name, tc := range map[string]struct {
Flags FeatureFlags
TestFeatureValue string
}{
"empty": {
TestFeatureValue: "",
Flags: FeatureFlags{},
},
"simple value": {
TestFeatureValue: "expectedvalue",
Flags: FeatureFlags{TestFeature: "expectedvalue"},
},
"empty value": {
TestFeatureValue: "",
Flags: FeatureFlags{TestFeature: ""},
},
} {
t.Run(name, func(t *testing.T) {
require.Equal(t, tc.TestFeatureValue, tc.Flags.ToMap()["TestFeature"])
})
}
}
func TestFeatureFlagsSetDefaults_AttributeValueMasking(t *testing.T) {
var flags FeatureFlags
flags.SetDefaults()
require.True(t, flags.AttributeValueMasking, "AttributeValueMasking should default to true")
require.Equal(t, "true", flags.ToMap()["AttributeValueMasking"])
}
func TestFeatureFlagsSetDefaults_PropertyFieldRank(t *testing.T) {
var flags FeatureFlags
flags.SetDefaults()
require.True(t, flags.PropertyFieldRank, "PropertyFieldRank should default to true")
require.Equal(t, "true", flags.ToMap()["PropertyFieldRank"])
}
// TestFeatureFlagsPermissionPoliciesDependencies pins down the
// "sub-flag is gated by the umbrella PermissionPolicies flag"
// contract for both ChannelPermissionPolicies and PolicySimulation.
// Centralizing this in helper methods means future changes to the
// dependency (additional gates, new sub-flags) only have to update
// one place and existing call sites stay correct.
func TestFeatureFlagsPermissionPoliciesDependencies(t *testing.T) {
t.Run("both helpers are on when defaults are applied", func(t *testing.T) {
var f FeatureFlags
f.SetDefaults()
require.True(t, f.IsChannelPermissionPoliciesEnabled())
require.True(t, f.IsPolicySimulationEnabled())
})
t.Run("sub-flag alone is not enough — the umbrella must be on too", func(t *testing.T) {
f := FeatureFlags{
PermissionPolicies: false,
ChannelPermissionPolicies: true,
PolicySimulation: true,
}
require.False(t, f.IsChannelPermissionPoliciesEnabled(),
"ChannelPermissionPolicies sub-flag must be ignored when the PermissionPolicies umbrella is off")
require.False(t, f.IsPolicySimulationEnabled(),
"PolicySimulation sub-flag must be ignored when the PermissionPolicies umbrella is off")
})
t.Run("umbrella alone is not enough — the sub-flag must be on too", func(t *testing.T) {
f := FeatureFlags{
PermissionPolicies: true,
ChannelPermissionPolicies: false,
PolicySimulation: false,
}
require.False(t, f.IsChannelPermissionPoliciesEnabled())
require.False(t, f.IsPolicySimulationEnabled())
})
t.Run("both flags on enables each sub-feature independently", func(t *testing.T) {
f := FeatureFlags{
PermissionPolicies: true,
ChannelPermissionPolicies: true,
PolicySimulation: false,
}
require.True(t, f.IsChannelPermissionPoliciesEnabled())
require.False(t, f.IsPolicySimulationEnabled(), "sub-flags are independent — enabling one must not enable the other")
f.ChannelPermissionPolicies = false
f.PolicySimulation = true
require.False(t, f.IsChannelPermissionPoliciesEnabled())
require.True(t, f.IsPolicySimulationEnabled())
})
}
func TestFeatureFlagsToMapBool(t *testing.T) {
for name, tc := range map[string]struct {
Flags FeatureFlags
TestFeatureValue string
}{
"false": {
TestFeatureValue: "false",
Flags: FeatureFlags{},
},
"true": {
TestFeatureValue: "true",
Flags: FeatureFlags{TestBoolFeature: true},
},
} {
t.Run(name, func(t *testing.T) {
require.Equal(t, tc.TestFeatureValue, tc.Flags.ToMap()["TestBoolFeature"])
})
}
}