Repository: google/go-github
Pull request #2674 (2023-02-24 12:49:48)

Add ListExternalGroupsForTeamBySlug to Teams API
#2217 added support for the majority of the External Groups API but omitted listing groups for a specific Team within an Organization.

This PR adds the missing method, and corrects the comment on the original `ListExternalGroups` method as that actually returns all external groups within the Organization. I added the `ForTeamBySlug` suffix based on other methods in the source to distinguish it from the original method.

I've added tests based on the original `ListExternalGroups` method and everything passes.

codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/2674?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#2674](https://codecov.io/gh/google/go-github/pull/2674?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (1f336cc) into [master](https://codecov.io/gh/google/go-github/commit/4814a50d3876239c88772c10bcd470e3a7ebe4ee?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (4814a50) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##           master    #2674   +/-   ##
=======================================
  Coverage   98.05%   98.05%           
=======================================
  Files         131      131           
  Lines       11442    11455   +13     
=======================================
+ Hits        11219    11232   +13     
  Misses        152      152           
  Partials       71       71           
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/2674?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Coverage Δ | |
|---|---|---|
| [github/teams.go](https://codecov.io/gh/google/go-github/pull/2674?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL3RlYW1zLmdv) | `98.18% <100.00%> (+0.04%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google)


Patch:
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
index cf4edcb6..d57bb7f4 100644
--- a/.github/workflows/linter.yml
+++ b/.github/workflows/linter.yml
@@ -26,8 +26,8 @@ jobs:
     - uses: actions/checkout@v3
 
     - name: golangci-lint ${{ matrix.working-directory }}
-      uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 #v3.4.0
+      uses: golangci/golangci-lint-action@v3
       with:
-        version: v1.50.1
+        version: latest
         working-directory: ${{ matrix.working-directory}}
         args: --verbose
diff --git a/example/go.mod b/example/go.mod
index e268c7ad..6138d931 100644
--- a/example/go.mod
+++ b/example/go.mod
@@ -17,7 +17,7 @@ require (
 	github.com/google/go-github/v41 v41.0.0 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
-	golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
+	golang.org/x/sys v0.1.0 // indirect
 	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
 )
 
diff --git a/example/go.sum b/example/go.sum
index 1043059f..9b12b78d 100644
--- a/example/go.sum
+++ b/example/go.sum
@@ -25,8 +25,9 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/github/teams.go b/github/teams.go
index 963a69b3..0ee7c200 100644
--- a/github/teams.go
+++ b/github/teams.go
@@ -913,7 +913,7 @@ type ListExternalGroupsOptions struct {
 	ListOptions
 }
 
-// ListExternalGroups lists external groups connected to a team on GitHub.
+// ListExternalGroups lists external groups in an organization on GitHub.
 //
 // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#list-external-groups-in-an-organization
 func (s *TeamsService) ListExternalGroups(ctx context.Context, org string, opts *ListExternalGroupsOptions) (*ExternalGroupList, *Response, error) {
@@ -937,6 +937,26 @@ func (s *TeamsService) ListExternalGroups(ctx context.Context, org string, opts
 	return externalGroups, resp, nil
 }
 
+// ListExternalGroupsForTeamBySlug lists external groups connected to a team on GitHub.
+//
+// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#list-a-connection-between-an-external-group-and-a-team
+func (s *TeamsService) ListExternalGroupsForTeamBySlug(ctx context.Context, org, slug string) (*ExternalGroupList, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/external-groups", org, slug)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	externalGroups := new(ExternalGroupList)
+	resp, err := s.client.Do(ctx, req, externalGroups)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return externalGroups, resp, nil
+}
+
 // UpdateConnectedExternalGroup updates the connection between an external group and a team.
 //
 // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#update-the-connection-between-an-external-group-and-a-team
diff --git a/scrape/go.mod b/scrape/go.mod
index 3aa019c5..97c793d0 100644
--- a/scrape/go.mod
+++ b/scrape/go.mod
@@ -6,6 +6,6 @@ require (
 	github.com/PuerkitoBio/goquery v1.8.1
 	github.com/google/go-cmp v0.5.9
 	github.com/google/go-github/v50 v50.0.0
-	github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
+	github.com/xlzd/gotp v0.1.0
 	golang.org/x/net v0.7.0
 )
diff --git a/scrape/go.sum b/scrape/go.sum
index a67b4395..2ac0d30e 100644
--- a/scrape/go.sum
+++ b/scrape/go.sum
@@ -12,8 +12,8 @@ github.com/google/go-github/v50 v50.0.0 h1:gdO1AeuSZZK4iYWwVbjni7zg8PIQhp7QfmPun
 github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
-github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4=
-github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8=
+github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
+github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=


Test patch:
diff --git a/github/teams_test.go b/github/teams_test.go
index 93e658af..d86fab7f 100644
--- a/github/teams_test.go
+++ b/github/teams_test.go
@@ -1935,6 +1935,79 @@ func TestTeamsService_ListExternalGroups_notFound(t *testing.T) {
 	}
 }
 
+func TestTeamsService_ListExternalGroupsForTeamBySlug(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/teams/t/external-groups", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{
+			"groups": [
+				{
+					"group_id": 123,
+					"group_name": "Octocat admins",
+					"updated_at": "2006-01-02T15:04:05Z"
+				}
+			]
+		}`)
+	})
+
+	ctx := context.Background()
+	list, _, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+	if err != nil {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned error: %v", err)
+	}
+
+	want := &ExternalGroupList{
+		Groups: []*ExternalGroup{
+			{
+				GroupID:   Int64(123),
+				GroupName: String("Octocat admins"),
+				UpdatedAt: &Timestamp{Time: referenceTime},
+			},
+		},
+	}
+	if !cmp.Equal(list, want) {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned %+v, want %+v", list, want)
+	}
+
+	const methodName = "ListExternalGroupsForTeamBySlug"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Teams.ListExternalGroupsForTeamBySlug(ctx, "\n", "\n")
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
+func TestTeamsService_ListExternalGroupsForTeamBySlug_notFound(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/teams/t/external-groups", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		w.WriteHeader(http.StatusNotFound)
+	})
+
+	ctx := context.Background()
+	eg, resp, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+	if err == nil {
+		t.Errorf("Expected HTTP 404 response")
+	}
+	if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned status %d, want %d", got, want)
+	}
+	if eg != nil {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned %+v, want nil", eg)
+	}
+}
+
 func TestTeamsService_UpdateConnectedExternalGroup(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()