Repository: xanzy/go-gitlab
Pull request #1930 (2024-05-03 16:17:53)

Fix: Sync project/group resource access token webhook events to match current documentation
**Update:** After raising [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/460466), [this merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152907) updated the webhook payloads that we can expect.

This PR updates the payloads and structs to reflect that ✌️ 

---

I searched for other places in the code where a format like `2024-01-24 16:27:40 UTC` occurs and found (among others) this which I used as a reference:

https://github.com/xanzy/go-gitlab/blob/2c4b565c47917bc633bc2b0521802a0630b76f83/event_webhook_types.go#L832-L833

Hope that this is the correct way! Let me know if it's not

svanharmelen: Hmm... Yeah the inconsistencies around how time is used in the API is quite frustrating. In this case I guess it would make sense to first open an issue with GitLab to see if it's a bug there which they need to fix instead?
vntw: Good idea, I'll create an issue (if there hasn't been one already) and report back

Patch:
diff --git a/event_webhook_types.go b/event_webhook_types.go
index b75a8eb..8a0a057 100644
--- a/event_webhook_types.go
+++ b/event_webhook_types.go
@@ -213,19 +213,17 @@ type FeatureFlagEvent struct {
 type GroupResourceAccessTokenEvent struct {
 	EventName  string `json:"event_name"`
 	ObjectKind string `json:"object_kind"`
-	GroupID    int    `json:"group_id"`
 	Group      struct {
 		GroupID   int    `json:"group_id"`
 		GroupName string `json:"group_name"`
 		GroupPath string `json:"group_path"`
-		FullPath  string `json:"full_path"`
 	} `json:"group"`
 	ObjectAttributes struct {
-		ID        int        `json:"id"`
-		UserID    int        `json:"user_id"`
-		Name      string     `json:"name"`
-		CreatedAt *time.Time `json:"created_at"`
-		ExpiresAt *ISOTime   `json:"expires_at"`
+		ID        int      `json:"id"`
+		UserID    int      `json:"user_id"`
+		Name      string   `json:"name"`
+		CreatedAt string   `json:"created_at"`
+		ExpiresAt *ISOTime `json:"expires_at"`
 	} `json:"object_attributes"`
 }
 
@@ -933,7 +931,6 @@ type PipelineEvent struct {
 type ProjectResourceAccessTokenEvent struct {
 	EventName  string `json:"event_name"`
 	ObjectKind string `json:"object_kind"`
-	ProjectID  int    `json:"project_id"`
 	Project    struct {
 		ID                int    `json:"id"`
 		Name              string `json:"name"`
@@ -953,11 +950,11 @@ type ProjectResourceAccessTokenEvent struct {
 		HTTPURL           string `json:"http_url"`
 	} `json:"project"`
 	ObjectAttributes struct {
-		ID        int        `json:"id"`
-		UserID    int        `json:"user_id"`
-		Name      string     `json:"name"`
-		CreatedAt *time.Time `json:"created_at"`
-		ExpiresAt *ISOTime   `json:"expires_at"`
+		ID        int      `json:"id"`
+		UserID    int      `json:"user_id"`
+		Name      string   `json:"name"`
+		CreatedAt string   `json:"created_at"`
+		ExpiresAt *ISOTime `json:"expires_at"`
 	} `json:"object_attributes"`
 }
 


Test patch:
diff --git a/event_parsing_webhook_test.go b/event_parsing_webhook_test.go
index 163eeff..9c860ab 100644
--- a/event_parsing_webhook_test.go
+++ b/event_parsing_webhook_test.go
@@ -160,8 +160,10 @@ func TestParseGroupResourceAccessTokenHook(t *testing.T) {
 		t.Errorf("Expected GroupResourceAccessTokenEvent, but parsing produced %T", parsedEvent)
 	}
 
-	if event.GroupID != 35 {
-		t.Errorf("GroupID is %v, want %v", event.GroupID, 35)
+	expectedEventName := "expiring_access_token"
+
+	if event.EventName != expectedEventName {
+		t.Errorf("EventName is %v, want %v", event.EventName, expectedEventName)
 	}
 }
 
@@ -382,8 +384,10 @@ func TestParseProjectResourceAccessTokenHook(t *testing.T) {
 		t.Errorf("Expected ProjectResourceAccessTokenEvent, but parsing produced %T", parsedEvent)
 	}
 
-	if event.ProjectID != 7 {
-		t.Errorf("ProjectID is %v, want %v", event.ProjectID, 7)
+	expectedEventName := "expiring_access_token"
+
+	if event.EventName != expectedEventName {
+		t.Errorf("EventName is %v, want %v", event.EventName, expectedEventName)
 	}
 }
 
diff --git a/event_webhook_types_test.go b/event_webhook_types_test.go
index f31b2fe..e51787d 100644
--- a/event_webhook_types_test.go
+++ b/event_webhook_types_test.go
@@ -298,18 +298,12 @@ func TestGroupResourceAccessTokenEventUnmarshal(t *testing.T) {
 		t.Errorf("event is null")
 	}
 
-	createdAt, err := time.Parse(time.RFC3339, "2024-02-05T03:13:44.855Z")
-	if err != nil {
-		t.Fatalf("could not parse time: %v", err)
-	}
-
 	expiresAt, err := ParseISOTime("2024-01-26")
 	if err != nil {
 		t.Fatalf("could not parse ISO time: %v", err)
 	}
 
 	expected := &GroupResourceAccessTokenEvent{
-		GroupID:    35,
 		ObjectKind: "access_token",
 		EventName:  "expiring_access_token",
 	}
@@ -317,12 +311,11 @@ func TestGroupResourceAccessTokenEventUnmarshal(t *testing.T) {
 	expected.Group.GroupID = 35
 	expected.Group.GroupName = "Twitter"
 	expected.Group.GroupPath = "twitter"
-	expected.Group.FullPath = "twitter"
 
 	expected.ObjectAttributes.ID = 25
 	expected.ObjectAttributes.UserID = 90
 	expected.ObjectAttributes.Name = "acd"
-	expected.ObjectAttributes.CreatedAt = &createdAt
+	expected.ObjectAttributes.CreatedAt = "2024-01-24 16:27:40 UTC"
 	expected.ObjectAttributes.ExpiresAt = &expiresAt
 
 	assert.Equal(t, expected, event)
@@ -1068,18 +1061,12 @@ func TestProjectResourceAccessTokenEventUnmarshal(t *testing.T) {
 		t.Errorf("event is null")
 	}
 
-	createdAt, err := time.Parse(time.RFC3339, "2024-02-05T03:13:44.855Z")
-	if err != nil {
-		t.Fatalf("could not parse time: %v", err)
-	}
-
 	expiresAt, err := ParseISOTime("2024-01-26")
 	if err != nil {
 		t.Fatalf("could not parse ISO time: %v", err)
 	}
 
 	expected := &ProjectResourceAccessTokenEvent{
-		ProjectID:  7,
 		ObjectKind: "access_token",
 		EventName:  "expiring_access_token",
 	}
@@ -1087,7 +1074,7 @@ func TestProjectResourceAccessTokenEventUnmarshal(t *testing.T) {
 	expected.ObjectAttributes.ID = 25
 	expected.ObjectAttributes.UserID = 90
 	expected.ObjectAttributes.Name = "acd"
-	expected.ObjectAttributes.CreatedAt = &createdAt
+	expected.ObjectAttributes.CreatedAt = "2024-01-24 16:27:40 UTC"
 	expected.ObjectAttributes.ExpiresAt = &expiresAt
 
 	expected.Project.ID = 7
diff --git a/testdata/webhooks/resource_access_token_group.json b/testdata/webhooks/resource_access_token_group.json
index 613c795..cb96d29 100644
--- a/testdata/webhooks/resource_access_token_group.json
+++ b/testdata/webhooks/resource_access_token_group.json
@@ -1,15 +1,13 @@
 {
   "object_kind": "access_token",
-  "group_id": 35,
   "group": {
     "group_name": "Twitter",
     "group_path": "twitter",
-    "full_path": "twitter",
     "group_id": 35
   },
   "object_attributes": {
     "user_id": 90,
-    "created_at": "2024-02-05T03:13:44.855Z",
+    "created_at": "2024-01-24 16:27:40 UTC",
     "id": 25,
     "name": "acd",
     "expires_at": "2024-01-26"
diff --git a/testdata/webhooks/resource_access_token_project.json b/testdata/webhooks/resource_access_token_project.json
index efc4dd9..6f4098b 100644
--- a/testdata/webhooks/resource_access_token_project.json
+++ b/testdata/webhooks/resource_access_token_project.json
@@ -1,6 +1,5 @@
 {
   "object_kind": "access_token",
-  "project_id": 7,
   "project": {
     "id": 7,
     "name": "Flight",
@@ -21,7 +20,7 @@
   },
   "object_attributes": {
     "user_id": 90,
-    "created_at": "2024-02-05T03:13:44.855Z",
+    "created_at": "2024-01-24 16:27:40 UTC",
     "id": 25,
     "name": "acd",
     "expires_at": "2024-01-26"