Loading project_feature_flags.go +15 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,11 @@ type ProjectFeatureFlag struct { type ProjectFeatureFlagScope struct { ID int64 `json:"id"` EnvironmentScope string `json:"environment_scope"` // Destroy removes the scope identified by ID when set to true. Used // during UpdateProjectFeatureFlag to delete a scope that is no longer // wanted. Destroy *bool `json:"_destroy,omitempty"` } // ProjectFeatureFlagStrategy defines the strategy used for a feature flag Loading @@ -75,6 +80,7 @@ type ProjectFeatureFlagStrategy struct { Name string `json:"name"` Parameters *ProjectFeatureFlagStrategyParameter `json:"parameters"` Scopes []*ProjectFeatureFlagScope `json:"scopes"` UserList *FeatureFlagUserList `json:"user_list,omitempty"` } // ProjectFeatureFlagStrategyParameter is used in updating and creating feature flags Loading Loading @@ -143,6 +149,15 @@ type FeatureFlagStrategyOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Parameters *ProjectFeatureFlagStrategyParameter `url:"parameters,omitempty" json:"parameters,omitempty"` Scopes *[]*ProjectFeatureFlagScope `url:"scopes,omitempty" json:"scopes,omitempty"` // UserListID sets the feature flag user list bound to the strategy. Only // used when Name is "gitlabUserList". UserListID *int64 `url:"user_list_id,omitempty" json:"user_list_id,omitempty"` // Destroy removes the strategy identified by ID when set to true. Used // during UpdateProjectFeatureFlag to delete a strategy that is no longer // wanted. Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` } // ProjectFeatureFlagScopeOptions represents the available feature flag scope Loading project_feature_flags_test.go +123 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,129 @@ func TestUpdateProjectFeatureFlag(t *testing.T) { assert.Equal(t, expected, actual) } func TestUpdateProjectFeatureFlag_GitLabUserListAndDestroy(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc("/api/v4/projects/1/feature_flags/testing", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPut) testBodyJSON(t, r, map[string]any{ "strategies": []any{ map[string]any{ "name": "gitlabUserList", "user_list_id": float64(7), }, map[string]any{ "id": float64(38), "_destroy": true, }, }, }) mustWriteHTTPResponse(t, w, "testdata/update_project_feature_flag_gitlab_user_list.json") }) opt := &UpdateProjectFeatureFlagOptions{ Strategies: &[]*FeatureFlagStrategyOptions{ { Name: Ptr("gitlabUserList"), UserListID: Ptr(int64(7)), }, { ID: Ptr(int64(38)), Destroy: Ptr(true), }, }, } actual, _, err := client.ProjectFeatureFlags.UpdateProjectFeatureFlag(1, "testing", opt) require.NoError(t, err) expected := &ProjectFeatureFlag{ Name: "awesome_feature", Active: true, Version: "new_version_flag", CreatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), UpdatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), Scopes: []*ProjectFeatureFlagScope{}, Strategies: []*ProjectFeatureFlagStrategy{ { ID: 39, Name: "gitlabUserList", Parameters: &ProjectFeatureFlagStrategyParameter{}, Scopes: []*ProjectFeatureFlagScope{}, UserList: &FeatureFlagUserList{ ID: 7, IID: 1, Name: "my_user_list", UserXIDs: "user1,user2,user3", }, }, }, } assert.Equal(t, expected, actual) } func TestUpdateProjectFeatureFlag_ScopeDestroy(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc("/api/v4/projects/1/feature_flags/testing", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPut) testBodyJSON(t, r, map[string]any{ "strategies": []any{ map[string]any{ "id": float64(36), "scopes": []any{ map[string]any{ "id": float64(37), "environment_scope": "", "_destroy": true, }, }, }, }, }) mustWriteHTTPResponse(t, w, "testdata/update_project_feature_flag_scope_destroy.json") }) opt := &UpdateProjectFeatureFlagOptions{ Strategies: &[]*FeatureFlagStrategyOptions{ { ID: Ptr(int64(36)), Scopes: &[]*ProjectFeatureFlagScope{ { ID: 37, Destroy: Ptr(true), }, }, }, }, } actual, _, err := client.ProjectFeatureFlags.UpdateProjectFeatureFlag(1, "testing", opt) require.NoError(t, err) expected := &ProjectFeatureFlag{ Name: "awesome_feature", Active: true, Version: "new_version_flag", CreatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), UpdatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), Scopes: []*ProjectFeatureFlagScope{}, Strategies: []*ProjectFeatureFlagStrategy{ { ID: 36, Name: "default", Parameters: &ProjectFeatureFlagStrategyParameter{}, Scopes: []*ProjectFeatureFlagScope{}, }, }, } assert.Equal(t, expected, actual) } func TestDeleteProjectFeatureFlag(t *testing.T) { t.Parallel() mux, client := setup(t) Loading testdata/update_project_feature_flag_gitlab_user_list.json 0 → 100644 +23 −0 Original line number Diff line number Diff line { "name": "awesome_feature", "description": null, "active": true, "version": "new_version_flag", "created_at": "2020-05-13T20:10:32Z", "updated_at": "2020-05-13T20:10:32Z", "scopes": [], "strategies": [ { "id": 39, "name": "gitlabUserList", "parameters": {}, "scopes": [], "user_list": { "id": 7, "iid": 1, "name": "my_user_list", "user_xids": "user1,user2,user3" } } ] } testdata/update_project_feature_flag_scope_destroy.json 0 → 100644 +17 −0 Original line number Diff line number Diff line { "name": "awesome_feature", "description": null, "active": true, "version": "new_version_flag", "created_at": "2020-05-13T20:10:32Z", "updated_at": "2020-05-13T20:10:32Z", "scopes": [], "strategies": [ { "id": 36, "name": "default", "parameters": {}, "scopes": [] } ] } Loading
project_feature_flags.go +15 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,11 @@ type ProjectFeatureFlag struct { type ProjectFeatureFlagScope struct { ID int64 `json:"id"` EnvironmentScope string `json:"environment_scope"` // Destroy removes the scope identified by ID when set to true. Used // during UpdateProjectFeatureFlag to delete a scope that is no longer // wanted. Destroy *bool `json:"_destroy,omitempty"` } // ProjectFeatureFlagStrategy defines the strategy used for a feature flag Loading @@ -75,6 +80,7 @@ type ProjectFeatureFlagStrategy struct { Name string `json:"name"` Parameters *ProjectFeatureFlagStrategyParameter `json:"parameters"` Scopes []*ProjectFeatureFlagScope `json:"scopes"` UserList *FeatureFlagUserList `json:"user_list,omitempty"` } // ProjectFeatureFlagStrategyParameter is used in updating and creating feature flags Loading Loading @@ -143,6 +149,15 @@ type FeatureFlagStrategyOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Parameters *ProjectFeatureFlagStrategyParameter `url:"parameters,omitempty" json:"parameters,omitempty"` Scopes *[]*ProjectFeatureFlagScope `url:"scopes,omitempty" json:"scopes,omitempty"` // UserListID sets the feature flag user list bound to the strategy. Only // used when Name is "gitlabUserList". UserListID *int64 `url:"user_list_id,omitempty" json:"user_list_id,omitempty"` // Destroy removes the strategy identified by ID when set to true. Used // during UpdateProjectFeatureFlag to delete a strategy that is no longer // wanted. Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` } // ProjectFeatureFlagScopeOptions represents the available feature flag scope Loading
project_feature_flags_test.go +123 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,129 @@ func TestUpdateProjectFeatureFlag(t *testing.T) { assert.Equal(t, expected, actual) } func TestUpdateProjectFeatureFlag_GitLabUserListAndDestroy(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc("/api/v4/projects/1/feature_flags/testing", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPut) testBodyJSON(t, r, map[string]any{ "strategies": []any{ map[string]any{ "name": "gitlabUserList", "user_list_id": float64(7), }, map[string]any{ "id": float64(38), "_destroy": true, }, }, }) mustWriteHTTPResponse(t, w, "testdata/update_project_feature_flag_gitlab_user_list.json") }) opt := &UpdateProjectFeatureFlagOptions{ Strategies: &[]*FeatureFlagStrategyOptions{ { Name: Ptr("gitlabUserList"), UserListID: Ptr(int64(7)), }, { ID: Ptr(int64(38)), Destroy: Ptr(true), }, }, } actual, _, err := client.ProjectFeatureFlags.UpdateProjectFeatureFlag(1, "testing", opt) require.NoError(t, err) expected := &ProjectFeatureFlag{ Name: "awesome_feature", Active: true, Version: "new_version_flag", CreatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), UpdatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), Scopes: []*ProjectFeatureFlagScope{}, Strategies: []*ProjectFeatureFlagStrategy{ { ID: 39, Name: "gitlabUserList", Parameters: &ProjectFeatureFlagStrategyParameter{}, Scopes: []*ProjectFeatureFlagScope{}, UserList: &FeatureFlagUserList{ ID: 7, IID: 1, Name: "my_user_list", UserXIDs: "user1,user2,user3", }, }, }, } assert.Equal(t, expected, actual) } func TestUpdateProjectFeatureFlag_ScopeDestroy(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc("/api/v4/projects/1/feature_flags/testing", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPut) testBodyJSON(t, r, map[string]any{ "strategies": []any{ map[string]any{ "id": float64(36), "scopes": []any{ map[string]any{ "id": float64(37), "environment_scope": "", "_destroy": true, }, }, }, }, }) mustWriteHTTPResponse(t, w, "testdata/update_project_feature_flag_scope_destroy.json") }) opt := &UpdateProjectFeatureFlagOptions{ Strategies: &[]*FeatureFlagStrategyOptions{ { ID: Ptr(int64(36)), Scopes: &[]*ProjectFeatureFlagScope{ { ID: 37, Destroy: Ptr(true), }, }, }, }, } actual, _, err := client.ProjectFeatureFlags.UpdateProjectFeatureFlag(1, "testing", opt) require.NoError(t, err) expected := &ProjectFeatureFlag{ Name: "awesome_feature", Active: true, Version: "new_version_flag", CreatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), UpdatedAt: Ptr(time.Date(2020, time.May, 13, 20, 10, 32, 0, time.UTC)), Scopes: []*ProjectFeatureFlagScope{}, Strategies: []*ProjectFeatureFlagStrategy{ { ID: 36, Name: "default", Parameters: &ProjectFeatureFlagStrategyParameter{}, Scopes: []*ProjectFeatureFlagScope{}, }, }, } assert.Equal(t, expected, actual) } func TestDeleteProjectFeatureFlag(t *testing.T) { t.Parallel() mux, client := setup(t) Loading
testdata/update_project_feature_flag_gitlab_user_list.json 0 → 100644 +23 −0 Original line number Diff line number Diff line { "name": "awesome_feature", "description": null, "active": true, "version": "new_version_flag", "created_at": "2020-05-13T20:10:32Z", "updated_at": "2020-05-13T20:10:32Z", "scopes": [], "strategies": [ { "id": 39, "name": "gitlabUserList", "parameters": {}, "scopes": [], "user_list": { "id": 7, "iid": 1, "name": "my_user_list", "user_xids": "user1,user2,user3" } } ] }
testdata/update_project_feature_flag_scope_destroy.json 0 → 100644 +17 −0 Original line number Diff line number Diff line { "name": "awesome_feature", "description": null, "active": true, "version": "new_version_flag", "created_at": "2020-05-13T20:10:32Z", "updated_at": "2020-05-13T20:10:32Z", "scopes": [], "strategies": [ { "id": 36, "name": "default", "parameters": {}, "scopes": [] } ] }