Repository: xanzy/go-gitlab
Pull request #1192 (2021-08-17 23:41:42)

GroupMember ExpiresAt wrong type
The API return for the ExpiresAt date is actually ISOTime. See the below example query and response:

```
% curl -s -H "Private-Token: [redacted]" "https://gitlab.com/api/v4/groups/[redacted]/members" | jq
[
  {
    "id": [redacted],
    "name": "Brandon Butler",
    "username": "[redacted]",
    "state": "active",
    "avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/[redacted]/avatar.png",
    "web_url": "https://gitlab.com/[redacted]",
    "access_level": 50,
    "created_at": "2020-09-04T18:21:04.197Z",
    "expires_at": "2021-08-18"
  }
]
```

The docs actually seem to be wrong about the returned time format but I can confirm it's either ISOTime or null. Wouldn't make any sense for it to be a timestamp because there's no option to specify a specific expiration time anyway, only the date. And gitlab fulfills the expiration at midnight (I believe UTC.) 

Also, in case you saw my other two PRs open up, I apologize about that 🤦 It's been _one of those days_.


Patch:
diff --git a/group_members.go b/group_members.go
index 7f0e2dc..3ec95de 100644
--- a/group_members.go
+++ b/group_members.go
@@ -52,7 +52,7 @@ type GroupMember struct {
 	AvatarURL         string                   `json:"avatar_url"`
 	WebURL            string                   `json:"web_url"`
 	CreatedAt         *time.Time               `json:"created_at"`
-	ExpiresAt         *time.Time               `json:"expires_at"`
+	ExpiresAt         *ISOTime                 `json:"expires_at"`
 	AccessLevel       AccessLevelValue         `json:"access_level"`
 	GroupSAMLIdentity *GroupMemberSAMLIdentity `json:"group_saml_identity"`
 }


Test patch:
diff --git a/group_members_test.go b/group_members_test.go
index 98448b5..6c5a9e0 100644
--- a/group_members_test.go
+++ b/group_members_test.go
@@ -88,7 +88,7 @@ func TestListGroupMembersWithoutSAML(t *testing.T) {
 						"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
 						"web_url": "http://192.168.1.8:3000/root",
 						"created_at": "2012-10-21T14:13:35Z",
-						"expires_at": "2012-10-22T14:13:35Z",
+						"expires_at": "2012-10-22",
 						"access_level": 30,
 						"group_saml_identity": null
 					}
@@ -101,7 +101,8 @@ func TestListGroupMembersWithoutSAML(t *testing.T) {
 	}
 
 	createdAt, _ := time.Parse(time.RFC3339, "2012-10-21T14:13:35Z")
-	expiresAt, _ := time.Parse(time.RFC3339, "2012-10-22T14:13:35Z")
+	expiresAt, _ := time.Parse(time.RFC3339, "2012-10-22T00:00:00Z")
+	expiresAtISOTime := ISOTime(expiresAt)
 	want := []*GroupMember{
 		{
 			ID:                1,
@@ -111,7 +112,7 @@ func TestListGroupMembersWithoutSAML(t *testing.T) {
 			AvatarURL:         "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
 			WebURL:            "http://192.168.1.8:3000/root",
 			CreatedAt:         &createdAt,
-			ExpiresAt:         &expiresAt,
+			ExpiresAt:         &expiresAtISOTime,
 			AccessLevel:       30,
 			GroupSAMLIdentity: nil,
 		},
@@ -138,7 +139,7 @@ func TestListGroupMembersWithSAML(t *testing.T) {
 						"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
 						"web_url": "http://192.168.1.8:3000/root",
 						"created_at": "2012-10-21T14:13:35Z",
-						"expires_at": "2012-10-22T14:13:35Z",
+						"expires_at": "2012-10-22",
 						"access_level": 30,
 						"group_saml_identity": {
 							"extern_uid":"ABC-1234567890",
@@ -155,7 +156,8 @@ func TestListGroupMembersWithSAML(t *testing.T) {
 	}
 
 	createdAt, _ := time.Parse(time.RFC3339, "2012-10-21T14:13:35Z")
-	expiresAt, _ := time.Parse(time.RFC3339, "2012-10-22T14:13:35Z")
+	expiresAt, _ := time.Parse(time.RFC3339, "2012-10-22T00:00:00Z")
+	expiresAtISOTime := ISOTime(expiresAt)
 	want := []*GroupMember{
 		{
 			ID:          2,
@@ -165,7 +167,7 @@ func TestListGroupMembersWithSAML(t *testing.T) {
 			AvatarURL:   "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
 			WebURL:      "http://192.168.1.8:3000/root",
 			CreatedAt:   &createdAt,
-			ExpiresAt:   &expiresAt,
+			ExpiresAt:   &expiresAtISOTime,
 			AccessLevel: 30,
 			GroupSAMLIdentity: &GroupMemberSAMLIdentity{
 				ExternUID:      "ABC-1234567890",