diff --git a/github/github.go b/github/github.go index 99ad8d078d0..6bc1c47aefb 100644 --- a/github/github.go +++ b/github/github.go @@ -102,6 +102,9 @@ const ( // https://developer.github.com/changes/2017-07-26-team-review-request-thor-preview/ mediaTypeTeamReviewPreview = "application/vnd.github.thor-preview+json" + + // https://developer.github.com/changes/2017-08-30-preview-nested-teams/ + mediaTypeNestedTeamsPreview = "application/vnd.github.hellcat-preview+json" ) // A Client manages communication with the GitHub API. diff --git a/github/orgs_teams.go b/github/orgs_teams.go index 684e2dafffa..39161d7580f 100644 --- a/github/orgs_teams.go +++ b/github/orgs_teams.go @@ -39,6 +39,7 @@ type Team struct { Organization *Organization `json:"organization,omitempty"` MembersURL *string `json:"members_url,omitempty"` RepositoriesURL *string `json:"repositories_url,omitempty"` + Parent *Team `json:"parent,omitempty"` // LDAPDN is only available in GitHub Enterprise and when the team // membership is synchronized with LDAP. @@ -79,6 +80,9 @@ func (s *OrganizationsService) ListTeams(ctx context.Context, org string, opt *L return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeNestedTeamsPreview) + var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { @@ -98,6 +102,9 @@ func (s *OrganizationsService) GetTeam(ctx context.Context, team int) (*Team, *R return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeNestedTeamsPreview) + t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -117,6 +124,9 @@ func (s *OrganizationsService) CreateTeam(ctx context.Context, org string, team return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeNestedTeamsPreview) + t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -136,6 +146,9 @@ func (s *OrganizationsService) EditTeam(ctx context.Context, id int, team *Team) return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeNestedTeamsPreview) + t := new(Team) resp, err := s.client.Do(ctx, req, t) if err != nil { @@ -315,6 +328,9 @@ func (s *OrganizationsService) ListUserTeams(ctx context.Context, opt *ListOptio return nil, nil, err } + // TODO: remove custom Accept header when this API fully launches. + req.Header.Set("Accept", mediaTypeNestedTeamsPreview) + var teams []*Team resp, err := s.client.Do(ctx, req, &teams) if err != nil { diff --git a/github/orgs_teams_test.go b/github/orgs_teams_test.go index ff1101dc57a..a3933240368 100644 --- a/github/orgs_teams_test.go +++ b/github/orgs_teams_test.go @@ -21,6 +21,7 @@ func TestOrganizationsService_ListTeams(t *testing.T) { mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "2"}) fmt.Fprint(w, `[{"id":1}]`) }) @@ -48,7 +49,8 @@ func TestOrganizationsService_GetTeam(t *testing.T) { mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com"}`) + testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) + fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`) }) team, _, err := client.Organizations.GetTeam(context.Background(), 1) @@ -62,17 +64,41 @@ func TestOrganizationsService_GetTeam(t *testing.T) { } } +func TestOrganizationService_GetTeam_nestedTeams(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) + fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", + "parent": {"id":2, "name":"n", "description": "d", "parent": null}}`) + }) + + team, _, err := client.Organizations.GetTeam(context.Background(), 1) + if err != nil { + t.Errorf("Organizations.GetTeam returned error: %v", err) + } + + want := &Team{ID: Int(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p"), + Parent: &Team{ID: Int(2), Name: String("n"), Description: String("d")}, + } + if !reflect.DeepEqual(team, want) { + t.Errorf("Organizations.GetTeam returned %+v, want %+v", team, want) + } +} + func TestOrganizationsService_CreateTeam(t *testing.T) { setup() defer teardown() input := &Team{Name: String("n"), Privacy: String("closed")} - mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) { v := new(Team) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) if !reflect.DeepEqual(v, input) { t.Errorf("Request body = %+v, want %+v", v, input) } @@ -487,6 +513,7 @@ func TestOrganizationsService_ListUserTeams(t *testing.T) { mux.HandleFunc("/user/teams", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview) testFormValues(t, r, values{"page": "1"}) fmt.Fprint(w, `[{"id":1}]`) })