diff --git a/model/feature/flag.go b/model/feature/flag.go index fae8036be21..ce442032739 100644 --- a/model/feature/flag.go +++ b/model/feature/flag.go @@ -71,6 +71,38 @@ func (f *Flags) UnmarshalJSON(bytes []byte) error { return nil } +func (f *Flags) GetList(name string) ([]interface{}, error) { + if f.M[name] == nil { + return []interface{}{}, nil + } + + value, ok := f.M[name].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("Flag %s is not a list flag", name) + } + + list, ok := value["list"].([]interface{}) + if !ok { + return nil, fmt.Errorf("Flag %s is not a list flag", name) + } + + return list, nil +} + +func (f *Flags) HasListItem(name, item string) (bool, error) { + list, err := f.GetList(name) + if err != nil { + return false, err + } + + for _, i := range list { + if i == item { + return true, nil + } + } + return false, nil +} + // GetFlags returns the list of feature flags for the given instance. func GetFlags(inst *instance.Instance) (*Flags, error) { sources := make([]*Flags, 0) diff --git a/model/feature/flag_test.go b/model/feature/flag_test.go index 9bf41183463..1e0f83f1c8f 100644 --- a/model/feature/flag_test.go +++ b/model/feature/flag_test.go @@ -8,6 +8,7 @@ import ( "github.com/cozy/cozy-stack/model/instance" "github.com/gofrs/uuid/v5" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func uuidv7() string { @@ -38,3 +39,40 @@ func TestFeatureFlagRatio(t *testing.T) { assert.InDelta(t, 4000, results[float64(4)], 100) assert.InDelta(t, 3000, results[nil], 100) } + +func TestFeatureFlagList(t *testing.T) { + var flags Flags + err := json.Unmarshal( + []byte(`{ + "flag1": { "list": ["other", "val"] }, + "flag2": { "list": ["other"] }, + "flag3": { "list": [] }, + "flag4": ["val"], + "flag5": "val" + }`), + &flags, + ) + require.NoError(t, err) + + // GetList + list, err := flags.GetList("flag1") + require.NoError(t, err) + assert.EqualValues(t, []interface{}{"other", "val"}, list) + _, err = flags.GetList("flag4") + assert.Error(t, err) + _, err = flags.GetList("flag5") + assert.Error(t, err) + + // HasListItem + hasVal, err := flags.HasListItem("flag1", "val") + require.NoError(t, err) + assert.True(t, hasVal) + hasVal, _ = flags.HasListItem("flag2", "val") + assert.False(t, hasVal) + hasVal, _ = flags.HasListItem("flag3", "val") + assert.False(t, hasVal) + _, err = flags.HasListItem("flag4", "val") + assert.Error(t, err) + _, err = flags.HasListItem("flag5", "val") + assert.Error(t, err) +}