Commit d16e0188 authored by Pablo Carranza's avatar Pablo Carranza Committed by Sander van Harmelen

Add Feature Flags baseline (#192)

* Add Feature Flags baseline

This commit adds the service, ensures that the service gets instanciated
with the rest and provides the required types and method to list
features flags.

* Add SetFeatureFlag method to FeaturesService

This commit allows to create and modify feature flags by setting their
values

* Change doc urls and simplify use of values according to docs too
parent 1206a345
package gitlab
import (
"fmt"
"net/url"
)
// FeaturesService handles the communication with the application FeaturesService
// related methods of the GitLab API.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/features.html
type FeaturesService struct {
client *Client
}
// Feature represents a GitLab feature flag.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/features.html
type Feature struct {
Name string `json:"name"`
State string `json:"state"`
Gates []Gate
}
// Gate represents a gate of a GitLab feature flag.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/features.html
type Gate struct {
Key string `json:"key"`
Value interface{} `json:"value"`
}
func (f Feature) String() string {
return Stringify(f)
}
// ListFeatures gets a list of feature flags
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/features.html
func (s *FeaturesService) ListFeatures(options ...OptionFunc) ([]*Feature, *Response, error) {
req, err := s.client.NewRequest("GET", "features", nil, options)
if err != nil {
return nil, nil, err
}
var f []*Feature
resp, err := s.client.Do(req, &f)
if err != nil {
return nil, resp, err
}
return f, resp, err
}
// SetFeatureFlag sets or creates a feature flag gate
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/features.html
func (s *FeaturesService) SetFeatureFlag(name string, value interface{}, options ...OptionFunc) (*Feature, *Response, error) {
u := fmt.Sprintf("features/%s", url.QueryEscape(name))
opt := struct {
Value interface{} `url:"value" json:"value"`
}{
value,
}
req, err := s.client.NewRequest("POST", u, opt, options)
if err != nil {
return nil, nil, err
}
f := &Feature{}
resp, err := s.client.Do(req, f)
if err != nil {
return nil, resp, err
}
return f, resp, err
}
package gitlab
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestListFeatureFlags(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/features", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
[
{
"name": "experimental_feature",
"state": "off",
"gates": [
{
"key": "boolean",
"value": false
}
]
},
{
"name": "new_library",
"state": "on"
}
]
`)
})
features, _, err := client.Features.ListFeatures()
if err != nil {
t.Errorf("Features.ListFeatures returned error: %v", err)
}
want := []*Feature{
{Name: "experimental_feature", State: "off", Gates: []Gate{
{Key: "boolean", Value: false},
}},
{Name: "new_library", State: "on"},
}
if !reflect.DeepEqual(want, features) {
t.Errorf("Features.ListFeatures returned %+v, want %+v", features, want)
}
}
func TestSetFeatureFlag(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/features/new_library", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `
{
"name": "new_library",
"state": "conditional",
"gates": [
{
"key": "boolean",
"value": false
},
{
"key": "percentage_of_time",
"value": 30
}
]
}
`)
})
feature, _, err := client.Features.SetFeatureFlag("new_library", "30")
if err != nil {
t.Errorf("Features.SetFeatureFlag returned error: %v", err)
}
want := &Feature{
Name: "new_library",
State: "conditional",
Gates: []Gate{
{Key: "boolean", Value: false},
{Key: "percentage_of_time", Value: 30.0},
},
}
if !reflect.DeepEqual(want, feature) {
t.Errorf("Features.SetFeatureFlag returned %+v, want %+v", feature, want)
}
}
...@@ -165,6 +165,7 @@ type Client struct { ...@@ -165,6 +165,7 @@ type Client struct {
BuildVariables *BuildVariablesService BuildVariables *BuildVariablesService
Commits *CommitsService Commits *CommitsService
DeployKeys *DeployKeysService DeployKeys *DeployKeysService
Features *FeaturesService
Groups *GroupsService Groups *GroupsService
Issues *IssuesService Issues *IssuesService
Jobs *JobsService Jobs *JobsService
...@@ -230,6 +231,7 @@ func newClient(httpClient *http.Client, tokenType tokenType, token string) *Clie ...@@ -230,6 +231,7 @@ func newClient(httpClient *http.Client, tokenType tokenType, token string) *Clie
c.BuildVariables = &BuildVariablesService{client: c} c.BuildVariables = &BuildVariablesService{client: c}
c.Commits = &CommitsService{client: c} c.Commits = &CommitsService{client: c}
c.DeployKeys = &DeployKeysService{client: c} c.DeployKeys = &DeployKeysService{client: c}
c.Features = &FeaturesService{client: c}
c.Groups = &GroupsService{client: c} c.Groups = &GroupsService{client: c}
c.Issues = &IssuesService{client: c} c.Issues = &IssuesService{client: c}
c.Jobs = &JobsService{client: c} c.Jobs = &JobsService{client: c}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment