Repository: xanzy/go-gitlab
Pull request #1687 (2023-04-10 18:07:48)

Add feature flag event
@svanharmelen Looking for review


Patch:
diff --git a/event_parsing.go b/event_parsing.go
index 3a6868a..3943aba 100644
--- a/event_parsing.go
+++ b/event_parsing.go
@@ -31,6 +31,7 @@ const (
 	EventConfidentialNote  EventType = "Confidential Note Hook"
 	EventTypeBuild         EventType = "Build Hook"
 	EventTypeDeployment    EventType = "Deployment Hook"
+	EventTypeFeatureFlag   EventType = "Feature Flag Hook"
 	EventTypeIssue         EventType = "Issue Hook"
 	EventTypeJob           EventType = "Job Hook"
 	EventTypeMember        EventType = "Member Hook"
@@ -212,6 +213,8 @@ func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err e
 		event = &BuildEvent{}
 	case EventTypeDeployment:
 		event = &DeploymentEvent{}
+	case EventTypeFeatureFlag:
+		event = &FeatureFlagEvent{}
 	case EventTypeIssue, EventConfidentialIssue:
 		event = &IssueEvent{}
 	case EventTypeJob:
diff --git a/event_webhook_types.go b/event_webhook_types.go
index 5044444..771a2bb 100644
--- a/event_webhook_types.go
+++ b/event_webhook_types.go
@@ -178,6 +178,40 @@ type DeploymentEvent struct {
 	CommitTitle string     `json:"commit_title"`
 }
 
+// FeatureFlagEvent represents a feature flag event
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events
+type FeatureFlagEvent struct {
+	ObjectKind string `json:"object_kind"`
+	Project    struct {
+		ID                int     `json:"id"`
+		Name              string  `json:"name"`
+		Description       string  `json:"description"`
+		WebURL            string  `json:"web_url"`
+		AvatarURL         *string `json:"avatar_url"`
+		GitSSHURL         string  `json:"git_ssh_url"`
+		GitHTTPURL        string  `json:"git_http_url"`
+		Namespace         string  `json:"namespace"`
+		VisibilityLevel   int     `json:"visibility_level"`
+		PathWithNamespace string  `json:"path_with_namespace"`
+		DefaultBranch     string  `json:"default_branch"`
+		CIConfigPath      string  `json:"ci_config_path"`
+		Homepage          string  `json:"homepage"`
+		URL               string  `json:"url"`
+		SSHURL            string  `json:"ssh_url"`
+		HTTPURL           string  `json:"http_url"`
+	} `json:"project"`
+	User             *EventUser `json:"user"`
+	UserURL          string     `json:"user_url"`
+	ObjectAttributes struct {
+		ID          int    `json:"id"`
+		Name        string `json:"name"`
+		Description string `json:"description"`
+		Active      bool   `json:"active"`
+	} `json:"object_attributes"`
+}
+
 // IssueCommentEvent represents a comment on an issue event.
 //
 // GitLab API docs:


Test patch:
diff --git a/event_parsing_webhook_test.go b/event_parsing_webhook_test.go
index f63db48..c9d6b9d 100644
--- a/event_parsing_webhook_test.go
+++ b/event_parsing_webhook_test.go
@@ -101,6 +101,52 @@ func TestParseCommitCommentHook(t *testing.T) {
 	}
 }
 
+func TestParseFeatureFLagHook(t *testing.T) {
+	raw := loadFixture("testdata/webhooks/feature_flag.json")
+
+	parsedEvent, err := ParseWebhook("Feature Flag Hook", raw)
+	if err != nil {
+		t.Errorf("Error parsing feature flag hook: %s", err)
+	}
+
+	event, ok := parsedEvent.(*FeatureFlagEvent)
+	if !ok {
+		t.Errorf("Expected FeatureFlagEvent, but parsing produced %T", parsedEvent)
+	}
+
+	if event.ObjectKind != "feature_flag" {
+		t.Errorf("ObjectKind is %s, want %s", event.ObjectKind, "feature_flag")
+	}
+
+	if event.Project.ID != 1 {
+		t.Errorf("Project.ID is %v, want %v", event.Project.ID, 1)
+	}
+
+	if event.User.ID != 1 {
+		t.Errorf("User ID is %d, want %d", event.User.ID, 1)
+	}
+
+	if event.User.Name != "Administrator" {
+		t.Errorf("Username is %s, want %s", event.User.Name, "Administrator")
+	}
+
+	if event.ObjectAttributes.ID != 6 {
+		t.Errorf("ObjectAttributes.ID is %d, want %d", event.ObjectAttributes.ID, 6)
+	}
+
+	if event.ObjectAttributes.Name != "test-feature-flag" {
+		t.Errorf("ObjectAttributes.Name is %s, want %s", event.ObjectAttributes.Name, "test-feature-flag")
+	}
+
+	if event.ObjectAttributes.Description != "test-feature-flag-description" {
+		t.Errorf("ObjectAttributes.Description is %s, want %s", event.ObjectAttributes.Description, "test-feature-flag-description")
+	}
+
+	if event.ObjectAttributes.Active != true {
+		t.Errorf("ObjectAttributes.Active is %t, want %t", event.ObjectAttributes.Active, true)
+	}
+}
+
 func TestParseHookWebHook(t *testing.T) {
 	parsedEvent1, err := ParseHook("Merge Request Hook", loadFixture("testdata/webhooks/merge_request.json"))
 	if err != nil {
diff --git a/event_webhook_types_test.go b/event_webhook_types_test.go
index 421e3c6..f84267c 100644
--- a/event_webhook_types_test.go
+++ b/event_webhook_types_test.go
@@ -192,6 +192,52 @@ func TestDeploymentEventUnmarshal(t *testing.T) {
 	}
 }
 
+func TestFeatureFlagEventUnmarshal(t *testing.T) {
+	jsonObject := loadFixture("testdata/webhooks/feature_flag.json")
+
+	var event *FeatureFlagEvent
+	err := json.Unmarshal(jsonObject, &event)
+	if err != nil {
+		t.Errorf("FeatureFlag Event can not unmarshaled: %v\n ", err.Error())
+	}
+
+	if event == nil {
+		t.Errorf("FeatureFlag Event is null")
+	}
+
+	if event.ObjectKind != "feature_flag" {
+		t.Errorf("ObjectKind is %s, want %s", event.ObjectKind, "feature_flag")
+	}
+
+	if event.Project.ID != 1 {
+		t.Errorf("Project.ID is %v, want %v", event.Project.ID, 1)
+	}
+
+	if event.User.ID != 1 {
+		t.Errorf("User ID is %d, want %d", event.User.ID, 1)
+	}
+
+	if event.User.Name != "Administrator" {
+		t.Errorf("Username is %s, want %s", event.User.Name, "Administrator")
+	}
+
+	if event.ObjectAttributes.ID != 6 {
+		t.Errorf("ObjectAttributes.ID is %d, want %d", event.ObjectAttributes.ID, 6)
+	}
+
+	if event.ObjectAttributes.Name != "test-feature-flag" {
+		t.Errorf("ObjectAttributes.Name is %s, want %s", event.ObjectAttributes.Name, "test-feature-flag")
+	}
+
+	if event.ObjectAttributes.Description != "test-feature-flag-description" {
+		t.Errorf("ObjectAttributes.Description is %s, want %s", event.ObjectAttributes.Description, "test-feature-flag-description")
+	}
+
+	if event.ObjectAttributes.Active != true {
+		t.Errorf("ObjectAttributes.Active is %t, want %t", event.ObjectAttributes.Active, true)
+	}
+}
+
 func TestIssueCommentEventUnmarshal(t *testing.T) {
 	jsonObject := loadFixture("testdata/webhooks/note_issue.json")
 
diff --git a/testdata/webhooks/feature_flag.json b/testdata/webhooks/feature_flag.json
new file mode 100644
index 0000000..4606784
--- /dev/null
+++ b/testdata/webhooks/feature_flag.json
@@ -0,0 +1,35 @@
+{
+    "object_kind": "feature_flag",
+    "project": {
+      "id": 1,
+      "name":"Gitlab Test",
+      "description":"Aut reprehenderit ut est.",
+      "web_url":"http://example.com/gitlabhq/gitlab-test",
+      "avatar_url":null,
+      "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git",
+      "git_http_url":"http://example.com/gitlabhq/gitlab-test.git",
+      "namespace":"GitlabHQ",
+      "visibility_level":20,
+      "path_with_namespace":"gitlabhq/gitlab-test",
+      "default_branch":"master",
+      "ci_config_path": null,
+      "homepage":"http://example.com/gitlabhq/gitlab-test",
+      "url":"http://example.com/gitlabhq/gitlab-test.git",
+      "ssh_url":"git@example.com:gitlabhq/gitlab-test.git",
+      "http_url":"http://example.com/gitlabhq/gitlab-test.git"
+    },
+    "user": {
+      "id": 1,
+      "name": "Administrator",
+      "username": "root",
+      "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+      "email": "admin@example.com"
+    },
+    "user_url": "http://example.com/root",
+    "object_attributes": {
+      "id": 6,
+      "name": "test-feature-flag",
+      "description": "test-feature-flag-description",
+      "active": true
+    }
+  }