From 23352c864e91b81cfecfe10401e13c6f37e0679a Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Tue, 9 Dec 2025 16:44:09 +0000 Subject: [PATCH 1/3] add support for enterprise team member apis --- github/enterprise_team.go | 133 +++++++++++++++++ github/enterprise_team_test.go | 257 +++++++++++++++++++++++++++++++++ 2 files changed, 390 insertions(+) diff --git a/github/enterprise_team.go b/github/enterprise_team.go index 4cbcb89ed1d..5322db41bef 100644 --- a/github/enterprise_team.go +++ b/github/enterprise_team.go @@ -150,3 +150,136 @@ func (s *EnterpriseService) DeleteTeam(ctx context.Context, enterprise, teamSlug return resp, nil } + +// ListTeamMembers lists all members of a team in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#list-members-in-an-enterprise-team +// +//meta:operation GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships +func (s *EnterpriseService) ListTeamMembers(ctx context.Context, enterprise, enterpriseTeam string, opt *ListOptions) ([]*User, *Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships", enterprise, enterpriseTeam) + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var members []*User + resp, err := s.client.Do(ctx, req, &members) + if err != nil { + return nil, resp, err + } + + return members, resp, nil +} + +// BulkAddTeamMembers adds multiple members to a team in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#bulk-add-team-members +// +//meta:operation POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/add +func (s *EnterpriseService) BulkAddTeamMembers(ctx context.Context, enterprise, enterpriseTeam string, username []string) ([]*User, *Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships/add", enterprise, enterpriseTeam) + req, err := s.client.NewRequest("POST", u, map[string][]string{"usernames": username}) + if err != nil { + return nil, nil, err + } + + var members []*User + resp, err := s.client.Do(ctx, req, &members) + if err != nil { + return nil, resp, err + } + + return members, resp, nil +} + +// BulkRemoveTeamMembers removes multiple members from a team in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#bulk-remove-team-members +// +//meta:operation POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/remove +func (s *EnterpriseService) BulkRemoveTeamMembers(ctx context.Context, enterprise, enterpriseTeam string, username []string) ([]*User, *Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships/remove", enterprise, enterpriseTeam) + req, err := s.client.NewRequest("POST", u, map[string][]string{"usernames": username}) + if err != nil { + return nil, nil, err + } + + var members []*User + resp, err := s.client.Do(ctx, req, &members) + if err != nil { + return nil, resp, err + } + + return members, resp, nil +} + +// GetTeamMembership retrieves a team membership for a user in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#get-enterprise-team-membership +// +//meta:operation GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username} +func (s *EnterpriseService) GetTeamMembership(ctx context.Context, enterprise, enterpriseTeam, username string) (*User, *Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships/%v", enterprise, enterpriseTeam, username) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var membership *User + resp, err := s.client.Do(ctx, req, &membership) + if err != nil { + return nil, resp, err + } + + return membership, resp, nil +} + +// AddTeamMember adds a member to a team in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#add-team-member +// +//meta:operation PUT /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username} +func (s *EnterpriseService) AddTeamMember(ctx context.Context, enterprise, enterpriseTeam, username string) (*User, *Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships/%v", enterprise, enterpriseTeam, username) + + req, err := s.client.NewRequest("PUT", u, nil) + if err != nil { + return nil, nil, err + } + + var member *User + resp, err := s.client.Do(ctx, req, &member) + if err != nil { + return nil, resp, err + } + + return member, resp, nil +} + +// RemoveTeamMember removes a member from a team in an enterprise team. +// +// GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#remove-team-membership +// +//meta:operation DELETE /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username} +func (s *EnterpriseService) RemoveTeamMember(ctx context.Context, enterprise, enterpriseTeam, username string) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/teams/%v/memberships/%v", enterprise, enterpriseTeam, username) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} diff --git a/github/enterprise_team_test.go b/github/enterprise_team_test.go index 573b1ec36d1..8643b4c1272 100644 --- a/github/enterprise_team_test.go +++ b/github/enterprise_team_test.go @@ -7,7 +7,9 @@ package github import ( "fmt" + "io" "net/http" + "strings" "testing" "time" @@ -234,3 +236,258 @@ func TestEnterpriseService_DeleteTeam(t *testing.T) { return client.Enterprise.DeleteTeam(ctx, "e", "t1") }) } + +func TestEnterpriseService_ListTeamMembers(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[{ + "login": "user1", + "id": 1001, + "url": "https://example.com/user1" + }]`) + }) + ctx := t.Context() + opts := &ListOptions{Page: 1, PerPage: 10} + got, _, err := client.Enterprise.ListTeamMembers(ctx, "e", "t1", opts) + if err != nil { + t.Fatalf("Enterprise.ListTeamMembers returned error: %v", err) + } + + want := []*User{ + { + Login: Ptr("user1"), + ID: Ptr(int64(1001)), + URL: Ptr("https://example.com/user1"), + }, + } + + if !cmp.Equal(got, want) { + t.Errorf("Enterprise.ListTeamMembers = %+v, want %+v", got, want) + } + + const methodName = "ListTeamMembers" + testBadOptions(t, methodName, func() error { + _, _, err := client.Enterprise.ListTeamMembers(ctx, "\n", "t1", opts) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.ListTeamMembers(ctx, "e", "t1", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_BulkAddTeamMembers(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships/add", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + + body, _ := io.ReadAll(r.Body) + if !strings.Contains(string(body), `"usernames":["u1","u2"]`) { + t.Errorf("Request body = %v, want usernames u1,u2", body) + } + + fmt.Fprint(w, `[{ + "login": "u1", + "id": 1 + },{ + "login": "u2", + "id": 2 + }]`) + }) + + ctx := t.Context() + got, _, err := client.Enterprise.BulkAddTeamMembers(ctx, "e", "t1", []string{"u1", "u2"}) + if err != nil { + t.Fatalf("BulkAddTeamMembers returned error: %v", err) + } + + want := []*User{ + {Login: Ptr("u1"), ID: Ptr(int64(1))}, + {Login: Ptr("u2"), ID: Ptr(int64(2))}, + } + + if !cmp.Equal(got, want) { + t.Errorf("BulkAddTeamMembers = %+v, want %+v", got, want) + } + + const methodName = "BulkAddTeamMembers" + testBadOptions(t, methodName, func() error { + _, _, err := client.Enterprise.BulkAddTeamMembers(ctx, "\n", "t1", []string{"u1"}) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.BulkAddTeamMembers(ctx, "e", "t1", []string{"u1"}) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_BulkRemoveTeamMembers(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships/remove", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + + body, _ := io.ReadAll(r.Body) + if !strings.Contains(string(body), `"usernames":["u1","u2"]`) { + t.Errorf("Request body = %v, want usernames u1,u2", body) + } + + fmt.Fprint(w, `[{ + "login": "u1", + "id": 1 + },{ + "login": "u2", + "id": 2 + }]`) + }) + + ctx := t.Context() + got, _, err := client.Enterprise.BulkRemoveTeamMembers(ctx, "e", "t1", []string{"u1", "u2"}) + if err != nil { + t.Fatalf("BulkRemoveTeamMembers returned error: %v", err) + } + + want := []*User{ + {Login: Ptr("u1"), ID: Ptr(int64(1))}, + {Login: Ptr("u2"), ID: Ptr(int64(2))}, + } + + if !cmp.Equal(got, want) { + t.Errorf("BulkRemoveTeamMembers = %+v, want %+v", got, want) + } + + const methodName = "BulkRemoveTeamMembers" + testBadOptions(t, methodName, func() error { + _, _, err := client.Enterprise.BulkRemoveTeamMembers(ctx, "\n", "t1", []string{"u1"}) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.BulkRemoveTeamMembers(ctx, "e", "t1", []string{"u1"}) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetTeamMembership(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships/u1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "login": "u1", + "id": 10 + }`) + }) + + ctx := t.Context() + got, _, err := client.Enterprise.GetTeamMembership(ctx, "e", "t1", "u1") + if err != nil { + t.Fatalf("GetTeamMembership returned error: %v", err) + } + + want := &User{ + Login: Ptr("u1"), + ID: Ptr(int64(10)), + } + + if !cmp.Equal(got, want) { + t.Errorf("GetTeamMembership = %+v, want %+v", got, want) + } + + const methodName = "GetTeamMembership" + testBadOptions(t, methodName, func() error { + _, _, err := client.Enterprise.GetTeamMembership(ctx, "\n", "t1", "u1") + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetTeamMembership(ctx, "e", "t1", "u1") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_AddTeamMember(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships/u1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, `{ + "login": "u1", + "id": 5 + }`) + }) + + ctx := t.Context() + got, _, err := client.Enterprise.AddTeamMember(ctx, "e", "t1", "u1") + if err != nil { + t.Fatalf("AddTeamMember returned error: %v", err) + } + + want := &User{ + Login: Ptr("u1"), + ID: Ptr(int64(5)), + } + + if !cmp.Equal(got, want) { + t.Errorf("AddTeamMember = %+v, want %+v", got, want) + } + + const methodName = "AddTeamMember" + testBadOptions(t, methodName, func() error { + _, _, err := client.Enterprise.AddTeamMember(ctx, "\n", "t1", "u1") + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.AddTeamMember(ctx, "e", "t1", "u1") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_RemoveTeamMember(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/teams/t1/memberships/u1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + ctx := t.Context() + resp, err := client.Enterprise.RemoveTeamMember(ctx, "e", "t1", "u1") + if err != nil { + t.Fatalf("RemoveTeamMember returned error: %v", err) + } + if resp == nil { + t.Fatal("RemoveTeamMember returned nil Response") + } + + const methodName = "RemoveTeamMember" + testBadOptions(t, methodName, func() error { + _, err := client.Enterprise.RemoveTeamMember(ctx, "\n", "t1", "u1") + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Enterprise.RemoveTeamMember(ctx, "e", "t1", "u1") + }) +} From ff3044d97b4e02a06757166e22ff760f1f173e96 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Tue, 9 Dec 2025 16:52:40 +0000 Subject: [PATCH 2/3] update test --- github/enterprise_team_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/github/enterprise_team_test.go b/github/enterprise_team_test.go index 8643b4c1272..a31872653d3 100644 --- a/github/enterprise_team_test.go +++ b/github/enterprise_team_test.go @@ -7,9 +7,7 @@ package github import ( "fmt" - "io" "net/http" - "strings" "testing" "time" @@ -289,11 +287,6 @@ func TestEnterpriseService_BulkAddTeamMembers(t *testing.T) { mux.HandleFunc("/enterprises/e/teams/t1/memberships/add", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - body, _ := io.ReadAll(r.Body) - if !strings.Contains(string(body), `"usernames":["u1","u2"]`) { - t.Errorf("Request body = %v, want usernames u1,u2", body) - } - fmt.Fprint(w, `[{ "login": "u1", "id": 1 @@ -339,11 +332,6 @@ func TestEnterpriseService_BulkRemoveTeamMembers(t *testing.T) { mux.HandleFunc("/enterprises/e/teams/t1/memberships/remove", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - body, _ := io.ReadAll(r.Body) - if !strings.Contains(string(body), `"usernames":["u1","u2"]`) { - t.Errorf("Request body = %v, want usernames u1,u2", body) - } - fmt.Fprint(w, `[{ "login": "u1", "id": 1 From 2671a0bb15e1df6390c311d9ef8c3af8eb3d4055 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 10 Dec 2025 03:22:27 +0000 Subject: [PATCH 3/3] fix comments --- github/enterprise_team.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/github/enterprise_team.go b/github/enterprise_team.go index 5322db41bef..716a330e281 100644 --- a/github/enterprise_team.go +++ b/github/enterprise_team.go @@ -151,7 +151,7 @@ func (s *EnterpriseService) DeleteTeam(ctx context.Context, enterprise, teamSlug return resp, nil } -// ListTeamMembers lists all members of a team in an enterprise team. +// ListTeamMembers lists all members of an enterprise team. // // GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#list-members-in-an-enterprise-team // @@ -177,7 +177,7 @@ func (s *EnterpriseService) ListTeamMembers(ctx context.Context, enterprise, ent return members, resp, nil } -// BulkAddTeamMembers adds multiple members to a team in an enterprise team. +// BulkAddTeamMembers adds multiple members to an enterprise team. // // GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#bulk-add-team-members // @@ -198,7 +198,7 @@ func (s *EnterpriseService) BulkAddTeamMembers(ctx context.Context, enterprise, return members, resp, nil } -// BulkRemoveTeamMembers removes multiple members from a team in an enterprise team. +// BulkRemoveTeamMembers removes multiple members from an enterprise team. // // GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#bulk-remove-team-members // @@ -241,7 +241,7 @@ func (s *EnterpriseService) GetTeamMembership(ctx context.Context, enterprise, e return membership, resp, nil } -// AddTeamMember adds a member to a team in an enterprise team. +// AddTeamMember adds a member to an enterprise team. // // GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#add-team-member // @@ -263,7 +263,7 @@ func (s *EnterpriseService) AddTeamMember(ctx context.Context, enterprise, enter return member, resp, nil } -// RemoveTeamMember removes a member from a team in an enterprise team. +// RemoveTeamMember removes a member from an enterprise team. // // GitHub API docs: https://docs.github.com/rest/enterprise-teams/enterprise-team-members#remove-team-membership //