Repository: xanzy/go-gitlab
Pull request #793 (2020-03-04 02:55:22)

added ListGroupHooks issue #776
Adds feature to list Group scoped web hooks.

svanharmelen: It seems you processed some feedback, but not all yet. Let me know when I can review your PR again.

Patch:
diff --git a/deployments.go b/deployments.go
index cd3645d..8041ce9 100644
--- a/deployments.go
+++ b/deployments.go
@@ -118,71 +118,3 @@ func (s *DeploymentsService) GetProjectDeployment(pid interface{}, deployment in
 
 	return d, resp, err
 }
-
-// CreateProjectDeploymentOptions represents the available
-// CreateProjectDeployment() options.
-//
-// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment
-type CreateProjectDeploymentOptions struct {
-	Environment *string                `url:"environment,omitempty" json:"environment,omitempty"`
-	Ref         *string                `url:"ref,omitempty" json:"ref,omitempty"`
-	SHA         *string                `url:"sha,omitempty" json:"sha,omitempty"`
-	Tag         *bool                  `url:"tag,omitempty" json:"tag,omitempty"`
-	Status      *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"`
-}
-
-// CreateProjectDeployment creates a project deployment.
-//
-// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment
-func (s *DeploymentsService) CreateProjectDeployment(pid interface{}, opt *CreateProjectDeploymentOptions, options ...OptionFunc) (*Deployment, *Response, error) {
-	project, err := parseID(pid)
-	if err != nil {
-		return nil, nil, err
-	}
-	u := fmt.Sprintf("projects/%s/deployments", pathEscape(project))
-
-	req, err := s.client.NewRequest("POST", u, opt, options)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	d := new(Deployment)
-	resp, err := s.client.Do(req, &d)
-	if err != nil {
-		return nil, resp, err
-	}
-
-	return d, resp, err
-}
-
-// UpdateProjectDeploymentOptions represents the available
-// UpdateProjectDeployment() options.
-//
-// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment
-type UpdateProjectDeploymentOptions struct {
-	Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"`
-}
-
-// UpdateProjectDeployment updates a project deployment.
-//
-// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment
-func (s *DeploymentsService) UpdateProjectDeployment(pid interface{}, deployment int, opt *UpdateProjectDeploymentOptions, options ...OptionFunc) (*Deployment, *Response, error) {
-	project, err := parseID(pid)
-	if err != nil {
-		return nil, nil, err
-	}
-	u := fmt.Sprintf("projects/%s/deployments/%d", pathEscape(project), deployment)
-
-	req, err := s.client.NewRequest("PUT", u, opt, options)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	d := new(Deployment)
-	resp, err := s.client.Do(req, &d)
-	if err != nil {
-		return nil, resp, err
-	}
-
-	return d, resp, err
-}
diff --git a/gitlab.go b/gitlab.go
index dc81219..84eddc6 100644
--- a/gitlab.go
+++ b/gitlab.go
@@ -83,7 +83,6 @@ type BuildStateValue string
 // These constants represent all valid build states.
 const (
 	Pending  BuildStateValue = "pending"
-	Created  BuildStateValue = "created"
 	Running  BuildStateValue = "running"
 	Success  BuildStateValue = "success"
 	Failed   BuildStateValue = "failed"
@@ -92,18 +91,6 @@ const (
 	Manual   BuildStateValue = "manual"
 )
 
-// DeploymentStatusValue represents a Gitlab deployment status.
-type DeploymentStatusValue string
-
-// These constants represent all valid deployment statuses.
-const (
-	DeploymentStatusCreated  DeploymentStatusValue = "created"
-	DeploymentStatusRunning  DeploymentStatusValue = "running"
-	DeploymentStatusSuccess  DeploymentStatusValue = "success"
-	DeploymentStatusFailed   DeploymentStatusValue = "failed"
-	DeploymentStatusCanceled DeploymentStatusValue = "canceled"
-)
-
 // ISOTime represents an ISO 8601 formatted date
 type ISOTime time.Time
 
@@ -941,14 +928,6 @@ func BuildState(v BuildStateValue) *BuildStateValue {
 	return p
 }
 
-// DeploymentStatus is a helper routine that allocates a new
-// DeploymentStatusValue to store v and returns a pointer to it.
-func DeploymentStatus(v DeploymentStatusValue) *DeploymentStatusValue {
-	p := new(DeploymentStatusValue)
-	*p = v
-	return p
-}
-
 // NotificationLevel is a helper routine that allocates a new NotificationLevelValue
 // to store v and returns a pointer to it.
 func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue {
diff --git a/group_hooks.go b/group_hooks.go
new file mode 100644
index 0000000..6c92517
--- /dev/null
+++ b/group_hooks.go
@@ -0,0 +1,65 @@
+//
+// Copyright 2020, Eric Stevens
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+import (
+	"fmt"
+	"time"
+)
+
+// GroupHook represents a GitLab group hook.
+//
+// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
+type GroupHook struct {
+	ID                       int        `json:"id"`
+	URL                      string     `json:"url"`
+	GroupID                  int        `json:"group_id"`
+	PushEvents               bool       `json:"push_events"`
+	IssuesEvents             bool       `json:"issues_events"`
+	ConfidentialIssuesEvents bool       `json:"confidential_issues_events"`
+	MergeRequestsEvents      bool       `json:"merge_requests_events"`
+	TagPushEvents            bool       `json:"tag_push_events"`
+	NoteEvents               bool       `json:"note_events"`
+	JobEvents                bool       `json:"job_events"`
+	PipelineEvents           bool       `json:"pipeline_events"`
+	WikiPageEvents           bool       `json:"wiki_page_events"`
+	EnableSslVerification    bool       `json:"enable_ssl_verification"`
+	CreatedAt                *time.Time `json:"created_at"`
+}
+
+// ListGroupHooks gets a list of group hooks.
+//
+// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
+func (s *GroupsService) ListGroupHooks(gid interface{}) ([]*GroupHook, *Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("groups/%s/hooks", pathEscape(group))
+
+	req, err := s.client.NewRequest("GET", u, nil, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	var gh []*GroupHook
+	resp, err := s.client.Do(req, &gh)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gh, resp, err
+}
diff --git a/group_variables.go b/group_variables.go
index 727aa0f..694b201 100644
--- a/group_variables.go
+++ b/group_variables.go
@@ -39,7 +39,6 @@ type GroupVariable struct {
 	Value        string            `json:"value"`
 	VariableType VariableTypeValue `json:"variable_type"`
 	Protected    bool              `json:"protected"`
-	Masked       bool              `json:"masked"`
 }
 
 func (v GroupVariable) String() string {
@@ -113,7 +112,6 @@ type CreateGroupVariableOptions struct {
 	Value        *string            `url:"value,omitempty" json:"value,omitempty"`
 	VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
 	Protected    *bool              `url:"protected,omitempty" json:"protected,omitempty"`
-	Masked       *bool              `url:"masked,omitempty" json:"masked,omitempty"`
 }
 
 // CreateVariable creates a new group variable.
@@ -150,7 +148,6 @@ type UpdateGroupVariableOptions struct {
 	Value        *string            `url:"value,omitempty" json:"value,omitempty"`
 	VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
 	Protected    *bool              `url:"protected,omitempty" json:"protected,omitempty"`
-	Masked       *bool              `url:"masked,omitempty" json:"masked,omitempty"`
 }
 
 // UpdateVariable updates the position of an existing
diff --git a/groups.go b/groups.go
index 1b8e4df..b3f7b5a 100644
--- a/groups.go
+++ b/groups.go
@@ -36,7 +36,6 @@ type Group struct {
 	Name                           string                     `json:"name"`
 	Path                           string                     `json:"path"`
 	Description                    string                     `json:"description"`
-	MembershipLock                 bool                       `json:"membership_lock"`
 	Visibility                     VisibilityValue            `json:"visibility"`
 	LFSEnabled                     bool                       `json:"lfs_enabled"`
 	AvatarURL                      string                     `json:"avatar_url"`
@@ -130,7 +129,6 @@ type CreateGroupOptions struct {
 	Name                           *string                     `url:"name,omitempty" json:"name,omitempty"`
 	Path                           *string                     `url:"path,omitempty" json:"path,omitempty"`
 	Description                    *string                     `url:"description,omitempty" json:"description,omitempty"`
-	MembershipLock                 *bool                       `url:"membership_lock,omitempty" json:"membership_lock,omitempty"`
 	Visibility                     *VisibilityValue            `url:"visibility,omitempty" json:"visibility,omitempty"`
 	ShareWithGroupLock             *bool                       `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"`
 	RequireTwoFactorAuth           *bool                       `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"`
diff --git a/issues.go b/issues.go
index 3aa1a3b..77e80b2 100644
--- a/issues.go
+++ b/issues.go
@@ -19,7 +19,6 @@ package gitlab
 import (
 	"encoding/json"
 	"fmt"
-	"net/url"
 	"strings"
 	"time"
 )
@@ -110,12 +109,6 @@ func (l *Labels) MarshalJSON() ([]byte, error) {
 	return json.Marshal(strings.Join(*l, ","))
 }
 
-// EncodeValues implements the query.EncodeValues interface
-func (l *Labels) EncodeValues(key string, v *url.Values) error {
-	v.Set(key, strings.Join(*l, ","))
-	return nil
-}
-
 // ListIssuesOptions represents the available ListIssues() options.
 //
 // GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues


Test patch:
diff --git a/group_hooks_test.go b/group_hooks_test.go
new file mode 100644
index 0000000..725bb58
--- /dev/null
+++ b/group_hooks_test.go
@@ -0,0 +1,80 @@
+//
+// Copyright 2020, Eric Stevens
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"reflect"
+	"testing"
+	"time"
+)
+
+func TestListGroupHooks(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/groups/1/hooks", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `
+[
+	{
+		"id": 1,
+		"url": "http://example.com/hook",
+		"group_id": 3,
+		"push_events": true,
+		"issues_events": true,
+		"confidential_issues_events": true,
+		"merge_requests_events": true,
+		"tag_push_events": true,
+		"note_events": true,
+		"job_events": true,
+		"pipeline_events": true,
+		"wiki_page_events": true,
+		"enable_ssl_verification": true,
+		"created_at": "2012-10-12T17:04:47Z"
+	}
+]`)
+	})
+
+	groupHooks, _, err := client.Groups.ListGroupHooks(1)
+	if err != nil {
+		t.Error(err)
+	}
+
+	datePointer := time.Date(2012, 10, 12, 17, 4, 47, 0, time.UTC)
+	want := []*GroupHook{{
+		ID:                       1,
+		URL:                      "http://example.com/hook",
+		GroupID:                  3,
+		PushEvents:               true,
+		IssuesEvents:             true,
+		ConfidentialIssuesEvents: true,
+		MergeRequestsEvents:      true,
+		TagPushEvents:            true,
+		NoteEvents:               true,
+		JobEvents:                true,
+		PipelineEvents:           true,
+		WikiPageEvents:           true,
+		EnableSslVerification:    true,
+		CreatedAt:                &datePointer,
+	}}
+
+	if !reflect.DeepEqual(groupHooks, want) {
+		t.Errorf("listGroupHooks returned \ngot:\n%v\nwant:\n%v", Stringify(groupHooks), Stringify(want))
+	}
+}
diff --git a/group_variables_test.go b/group_variables_test.go
deleted file mode 100644
index 34198b8..0000000
--- a/group_variables_test.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package gitlab
-
-import (
-	"fmt"
-	"net/http"
-	"reflect"
-	"testing"
-)
-
-func TestListGroupVariabless(t *testing.T) {
-	mux, server, client := setup()
-	defer teardown(server)
-
-	mux.HandleFunc("/api/v4/groups/1/variables",
-		func(w http.ResponseWriter, r *http.Request) {
-			testMethod(t, r, "GET")
-			fmt.Fprint(w, `[{"key": "TEST_VARIABLE_1","value": "test1","protected": false,"masked": true}]`)
-		})
-
-	variables, _, err := client.GroupVariables.ListVariables(1, &ListGroupVariablesOptions{})
-	if err != nil {
-		t.Errorf("GroupVariables.ListVariables returned error: %v", err)
-	}
-
-	want := []*GroupVariable{
-		{
-			Key:       "TEST_VARIABLE_1",
-			Value:     "test1",
-			Protected: false,
-			Masked:    true,
-		},
-	}
-
-	if !reflect.DeepEqual(want, variables) {
-		t.Errorf("GroupVariables.ListVariablesreturned %+v, want %+v", variables, want)
-	}
-}
-
-func TestGetGroupVariable(t *testing.T) {
-	mux, server, client := setup()
-	defer teardown(server)
-
-	mux.HandleFunc("/api/v4/groups/1/variables/TEST_VARIABLE_1",
-		func(w http.ResponseWriter, r *http.Request) {
-			testMethod(t, r, "GET")
-			fmt.Fprint(w, `{"key": "TEST_VARIABLE_1","value": "test1","protected": false,"masked": true}`)
-		})
-
-	variable, _, err := client.GroupVariables.GetVariable(1, "TEST_VARIABLE_1")
-
-	if err != nil {
-		t.Errorf("GroupVariables.GetVariable returned error: %v", err)
-	}
-
-	want := &GroupVariable{Key: "TEST_VARIABLE_1", Value: "test1", Protected: false, Masked: true}
-	if !reflect.DeepEqual(want, variable) {
-		t.Errorf("GroupVariables.GetVariable returned %+v, want %+v", variable, want)
-	}
-}
-
-func TestCreateGroupVariable(t *testing.T) {
-	mux, server, client := setup()
-	defer teardown(server)
-
-	mux.HandleFunc("/api/v4/groups/1/variables",
-		func(w http.ResponseWriter, r *http.Request) {
-			testMethod(t, r, "POST")
-			fmt.Fprint(w, `{"key": "TEST_VARIABLE_1","value": "test1","protected": false,"masked": true}`)
-		})
-
-	opt := &CreateGroupVariableOptions{
-		Key:       String("TEST_VARIABLE_1"),
-		Value:     String("test1"),
-		Protected: Bool(false),
-		Masked:    Bool(true),
-	}
-
-	variable, _, err := client.GroupVariables.CreateVariable(1, opt, nil)
-	if err != nil {
-		t.Errorf("GroupVariables.CreateVariable returned error: %v", err)
-	}
-
-	want := &GroupVariable{Key: "TEST_VARIABLE_1", Value: "test1", Protected: false, Masked: true}
-	if !reflect.DeepEqual(want, variable) {
-		t.Errorf("GroupVariables.CreateVariable returned %+v, want %+v", variable, want)
-	}
-}
-
-func TestDeleteGroupVariable(t *testing.T) {
-	mux, server, client := setup()
-	defer teardown(server)
-
-	mux.HandleFunc("/api/v4/groups/1/variables/TEST_VARIABLE_1",
-		func(w http.ResponseWriter, r *http.Request) {
-			testMethod(t, r, "DELETE")
-			w.WriteHeader(http.StatusAccepted)
-		})
-
-	resp, err := client.GroupVariables.RemoveVariable(1, "TEST_VARIABLE_1")
-	if err != nil {
-		t.Errorf("GroupVariables.RemoveVariable returned error: %v", err)
-	}
-
-	want := http.StatusAccepted
-	got := resp.StatusCode
-	if got != want {
-		t.Errorf("GroupVariables.RemoveVariable returned %d, want %d", got, want)
-	}
-}
-
-func TestUpdateGroupVariable(t *testing.T) {
-	mux, server, client := setup()
-	defer teardown(server)
-
-	mux.HandleFunc("/api/v4/groups/1/variables/TEST_VARIABLE_1",
-		func(w http.ResponseWriter, r *http.Request) {
-			testMethod(t, r, "PUT")
-			fmt.Fprint(w, `{"key": "TEST_VARIABLE_1","value": "test1","protected": false,"masked": true}`)
-		})
-
-	variable, _, err := client.GroupVariables.UpdateVariable(1, "TEST_VARIABLE_1", &UpdateGroupVariableOptions{})
-	if err != nil {
-		t.Errorf("GroupVariables.UpdateVariable returned error: %v", err)
-	}
-
-	want := &GroupVariable{Key: "TEST_VARIABLE_1", Value: "test1", Protected: false, Masked: true}
-	if !reflect.DeepEqual(want, variable) {
-		t.Errorf("Groups.UpdatedGroup returned %+v, want %+v", variable, want)
-	}
-}