Repository: google/go-github
Pull request #747 (2017-10-09 03:59:25)

Merge NestedTeamsPreview branch to master

googlebot: We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s).  If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA ([login here](https://cla.developers.google.com/) to double check)?  If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again.

<!-- need_author_cla -->
gmlewis: All CLAs signed. Changing label.
gmlewis: libraryVersion needs bumping.
elliotbeach: @gmlewis Would you like me to do that in another PR? I can’t here. I realize now that I could have opened this PR myself.
gmlewis: Thanks @elliotbeach, but I think we are good now.  This has been a fun little exercise.
I'm going to ask that @shurcooL review it after I look it over one time, and he can merge if I haven't made any mistakes.
shurcooL: This is waiting on GitHub indirectly via #748.
elliott-beach: I will make a pull request to add a method for setting `parent_team_id` to null, but I don't see a reason this couldn't be merged.
shurcooL: We'll need to resolve the conflict with `libraryVersion` bump (it should become 14 now). I'll do that by rebasing this branch on latest `master`. Maybe it's best to bump it just before merging the PR, to avoid the possibility of other conflicts. So I'll leave out 98b35b2be8ae24fcea8e1f84daebb0f59260d593 for now.

I notice that d51e256270584c5fb21a8ab2c9795fcf2d7de652 commit message says "Fixes #714.", but I don't see the new endpoint https://developer.github.com/v3/orgs/teams/#list-child-teams implemented yet. Doesn't that mean #714 is not going to be fully resolved yet?
gmlewis: I'm sorry, that Fix message was my fault... I thought it was resolved, but apparently not.
elliott-beach: It’s more my fault - I will fix tomorrow.
gmlewis: @elliott-beach - what is the status here - as far as I can tell, I can squash and merge this, correct?

googlebot: So there's good news and bad news.

:thumbsup: The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so.  Everything is all good there.

:confused: The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter.  We need to confirm that they're okay with their commits being contributed to this project.  Please have them confirm that here in the pull request.

*Note to project maintainer: This is a terminal state, meaning the `cla/google` commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.*

<!-- need_author_consent -->

Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 68a23f00..8da635a6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -55,7 +55,7 @@ again.
 
 [forking]: https://help.github.com/articles/fork-a-repo
 [golint]: https://github.com/golang/lint
-[golint readme]: https://github.com/golang/lint/blob/master/README
+[golint readme]: https://github.com/golang/lint/blob/master/README.md
 [gocov]: https://github.com/axw/gocov
 [gocov-html]: https://github.com/matm/gocov-html
 [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
diff --git a/github/apps.go b/github/apps.go
index ff338938..a83ea7c2 100644
--- a/github/apps.go
+++ b/github/apps.go
@@ -5,7 +5,11 @@
 
 package github
 
-import "context"
+import (
+	"context"
+	"fmt"
+	"time"
+)
 
 // AppsService provides access to the installation related functions
 // in the GitHub API.
@@ -13,6 +17,57 @@ import "context"
 // GitHub API docs: https://developer.github.com/v3/apps/
 type AppsService service
 
+// App represents a GitHub App.
+type App struct {
+	ID          *int       `json:"id,omitempty"`
+	Owner       *User      `json:"owner,omitempty"`
+	Name        *string    `json:"name,omitempty"`
+	Description *string    `json:"description,omitempty"`
+	ExternalURL *string    `json:"external_url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+	CreatedAt   *time.Time `json:"created_at,omitempty"`
+	UpdatedAt   *time.Time `json:"updated_at,omitempty"`
+}
+
+// InstallationToken represents an installation token.
+type InstallationToken struct {
+	Token     *string    `json:"token,omitempty"`
+	ExpiresAt *time.Time `json:"expires_at,omitempty"`
+}
+
+// Get a single GitHub App. Passing the empty string will get
+// the authenticated GitHub App.
+//
+// Note: appSlug is just the URL-friendly name of your GitHub App.
+// You can find this on the settings page for your GitHub App
+// (e.g., https://github.com/settings/apps/:app_slug).
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app
+func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) {
+	var u string
+	if appSlug != "" {
+		u = fmt.Sprintf("apps/%v", appSlug)
+	} else {
+		u = "app"
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	app := new(App)
+	resp, err := s.client.Do(ctx, req, app)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return app, resp, nil
+}
+
 // ListInstallations lists the installations that the current GitHub App has.
 //
 // GitHub API docs: https://developer.github.com/v3/apps/#find-installations
@@ -38,3 +93,77 @@ func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) (
 
 	return i, resp, nil
 }
+
+// GetInstallation returns the specified installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation
+func (s *AppsService) GetInstallation(ctx context.Context, id int) (*Installation, *Response, error) {
+	u := fmt.Sprintf("app/installations/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	i := new(Installation)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// ListUserInstallations lists installations that are accessible to the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user
+func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
+	u, err := addOptions("user/installations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var i struct {
+		Installations []*Installation `json:"installations"`
+	}
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i.Installations, resp, nil
+}
+
+// CreateInstallationToken creates a new installation token.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token
+func (s *AppsService) CreateInstallationToken(ctx context.Context, id int) (*InstallationToken, *Response, error) {
+	u := fmt.Sprintf("installations/%v/access_tokens", id)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	t := new(InstallationToken)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
diff --git a/github/apps_installation.go b/github/apps_installation.go
index 5c932919..ccac316c 100644
--- a/github/apps_installation.go
+++ b/github/apps_installation.go
@@ -51,6 +51,33 @@ func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repos
 	return r.Repositories, resp, nil
 }
 
+// ListUserRepos lists repositories that are accessible
+// to the authenticated user for an installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation
+func (s *AppsService) ListUserRepos(ctx context.Context, id int, opt *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("user/installations/%v/repositories", id)
+	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 r struct {
+		Repositories []*Repository `json:"repositories"`
+	}
+	resp, err := s.client.Do(ctx, req, &r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r.Repositories, resp, nil
+}
+
 // AddRepository adds a single repository to an installation.
 //
 // GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 6da009ba..c48e71a9 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -36,6 +36,62 @@ func (a *APIMeta) GetVerifiablePasswordAuthentication() bool {
 	return *a.VerifiablePasswordAuthentication
 }
 
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetCreatedAt() time.Time {
+	if a == nil || a.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *a.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (a *App) GetDescription() string {
+	if a == nil || a.Description == nil {
+		return ""
+	}
+	return *a.Description
+}
+
+// GetExternalURL returns the ExternalURL field if it's non-nil, zero value otherwise.
+func (a *App) GetExternalURL() string {
+	if a == nil || a.ExternalURL == nil {
+		return ""
+	}
+	return *a.ExternalURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (a *App) GetHTMLURL() string {
+	if a == nil || a.HTMLURL == nil {
+		return ""
+	}
+	return *a.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *App) GetID() int {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (a *App) GetName() string {
+	if a == nil || a.Name == nil {
+		return ""
+	}
+	return *a.Name
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetUpdatedAt() time.Time {
+	if a == nil || a.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *a.UpdatedAt
+}
+
 // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
 func (a *Authorization) GetCreatedAt() Timestamp {
 	if a == nil || a.CreatedAt == nil {
@@ -2036,6 +2092,22 @@ func (i *InstallationRepositoriesEvent) GetRepositorySelection() string {
 	return *i.RepositorySelection
 }
 
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetExpiresAt() time.Time {
+	if i == nil || i.ExpiresAt == nil {
+		return time.Time{}
+	}
+	return *i.ExpiresAt
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetToken() string {
+	if i == nil || i.Token == nil {
+		return ""
+	}
+	return *i.Token
+}
+
 // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
 func (i *Invitation) GetCreatedAt() time.Time {
 	if i == nil || i.CreatedAt == nil {
@@ -2948,6 +3020,46 @@ func (n *NewPullRequest) GetTitle() string {
 	return *n.Title
 }
 
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetDescription() string {
+	if n == nil || n.Description == nil {
+		return ""
+	}
+	return *n.Description
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetLDAPDN() string {
+	if n == nil || n.LDAPDN == nil {
+		return ""
+	}
+	return *n.LDAPDN
+}
+
+// GetParentTeamID returns the ParentTeamID field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetParentTeamID() int {
+	if n == nil || n.ParentTeamID == nil {
+		return 0
+	}
+	return *n.ParentTeamID
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPermission() string {
+	if n == nil || n.Permission == nil {
+		return ""
+	}
+	return *n.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPrivacy() string {
+	if n == nil || n.Privacy == nil {
+		return ""
+	}
+	return *n.Privacy
+}
+
 // GetID returns the ID field if it's non-nil, zero value otherwise.
 func (n *Notification) GetID() string {
 	if n == nil || n.ID == nil {
diff --git a/github/github.go b/github/github.go
index 54769bc3..db06cfb4 100644
--- a/github/github.go
+++ b/github/github.go
@@ -27,7 +27,7 @@ import (
 )
 
 const (
-	libraryVersion = "13"
+	libraryVersion = "14"
 	defaultBaseURL = "https://api.github.com/"
 	uploadBaseURL  = "https://uploads.github.com/"
 	userAgent      = "go-github/" + libraryVersion
@@ -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.
@@ -235,6 +238,37 @@ func NewClient(httpClient *http.Client) *Client {
 	return c
 }
 
+// NewEnterpriseClient returns a new GitHub API client with provided
+// base URL and upload URL (often the same URL).
+// If either URL does not have a trailing slash, one is added automatically.
+// If a nil httpClient is provided, http.DefaultClient will be used.
+//
+// Note that NewEnterpriseClient is a convenience helper only;
+// its behavior is equivalent to using NewClient, followed by setting
+// the BaseURL and UploadURL fields.
+func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) {
+	baseEndpoint, err := url.Parse(baseURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(baseEndpoint.Path, "/") {
+		baseEndpoint.Path += "/"
+	}
+
+	uploadEndpoint, err := url.Parse(uploadURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(uploadEndpoint.Path, "/") {
+		uploadEndpoint.Path += "/"
+	}
+
+	c := NewClient(httpClient)
+	c.BaseURL = baseEndpoint
+	c.UploadURL = uploadEndpoint
+	return c, nil
+}
+
 // NewRequest creates an API request. A relative URL can be provided in urlStr,
 // in which case it is resolved relative to the BaseURL of the Client.
 // Relative URLs should always be specified without a preceding slash. If
@@ -252,7 +286,9 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ
 	var buf io.ReadWriter
 	if body != nil {
 		buf = new(bytes.Buffer)
-		err := json.NewEncoder(buf).Encode(body)
+		enc := json.NewEncoder(buf)
+		enc.SetEscapeHTML(false)
+		err := enc.Encode(body)
 		if err != nil {
 			return nil, err
 		}
diff --git a/github/orgs_teams.go b/github/orgs_teams.go
index 684e2daf..8a209d93 100644
--- a/github/orgs_teams.go
+++ b/github/orgs_teams.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"strings"
 	"time"
 )
 
@@ -20,11 +21,7 @@ type Team struct {
 	URL         *string `json:"url,omitempty"`
 	Slug        *string `json:"slug,omitempty"`
 
-	// Permission is deprecated when creating or editing a team in an org
-	// using the new GitHub permission model. It no longer identifies the
-	// permission a team has on its repos, but only specifies the default
-	// permission a repo is initially added with. Avoid confusion by
-	// specifying a permission value when calling AddTeamRepo.
+	// Permission specifies the default permission for repositories owned by the team.
 	Permission *string `json:"permission,omitempty"`
 
 	// Privacy identifies the level of privacy this team should have.
@@ -39,6 +36,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 +77,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 +99,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 {
@@ -107,16 +111,50 @@ func (s *OrganizationsService) GetTeam(ctx context.Context, team int) (*Team, *R
 	return t, resp, nil
 }
 
+// NewTeam represents a team to be created or modified.
+type NewTeam struct {
+	Name         string   `json:"name"` // Name of the team. (Required.)
+	Description  *string  `json:"description,omitempty"`
+	Maintainers  []string `json:"maintainers,omitempty"`
+	RepoNames    []string `json:"repo_names,omitempty"`
+	ParentTeamID *int     `json:"parent_team_id,omitempty"`
+
+	// Deprecated: Permission is deprecated when creating or editing a team in an org
+	// using the new GitHub permission model. It no longer identifies the
+	// permission a team has on its repos, but only specifies the default
+	// permission a repo is initially added with. Avoid confusion by
+	// specifying a permission value when calling AddTeamRepo.
+	Permission *string `json:"permission,omitempty"`
+
+	// Privacy identifies the level of privacy this team should have.
+	// Possible values are:
+	//     secret - only visible to organization owners and members of this team
+	//     closed - visible to all members of this organization
+	// Default is "secret".
+	Privacy *string `json:"privacy,omitempty"`
+
+	// LDAPDN may be used in GitHub Enterprise when the team membership
+	// is synchronized with LDAP.
+	LDAPDN *string `json:"ldap_dn,omitempty"`
+}
+
+func (s NewTeam) String() string {
+	return Stringify(s)
+}
+
 // CreateTeam creates a new team within an organization.
 //
 // GitHub API docs: https://developer.github.com/v3/orgs/teams/#create-team
-func (s *OrganizationsService) CreateTeam(ctx context.Context, org string, team *Team) (*Team, *Response, error) {
+func (s *OrganizationsService) CreateTeam(ctx context.Context, org string, team *NewTeam) (*Team, *Response, error) {
 	u := fmt.Sprintf("orgs/%v/teams", org)
 	req, err := s.client.NewRequest("POST", u, team)
 	if err != nil {
 		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 {
@@ -129,13 +167,16 @@ func (s *OrganizationsService) CreateTeam(ctx context.Context, org string, team
 // EditTeam edits a team.
 //
 // GitHub API docs: https://developer.github.com/v3/orgs/teams/#edit-team
-func (s *OrganizationsService) EditTeam(ctx context.Context, id int, team *Team) (*Team, *Response, error) {
+func (s *OrganizationsService) EditTeam(ctx context.Context, id int, team *NewTeam) (*Team, *Response, error) {
 	u := fmt.Sprintf("teams/%v", id)
 	req, err := s.client.NewRequest("PATCH", u, team)
 	if err != nil {
 		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 {
@@ -155,6 +196,8 @@ func (s *OrganizationsService) DeleteTeam(ctx context.Context, team int) (*Respo
 		return nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
 	return s.client.Do(ctx, req, nil)
 }
 
@@ -168,6 +211,32 @@ type OrganizationListTeamMembersOptions struct {
 	ListOptions
 }
 
+// ListChildTeams lists child teams for a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-child-teams
+func (s *OrganizationsService) ListChildTeams(ctx context.Context, teamID int, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v/teams", teamID)
+	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
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
 // ListTeamMembers lists all of the users who are members of the specified
 // team.
 //
@@ -184,6 +253,8 @@ func (s *OrganizationsService) ListTeamMembers(ctx context.Context, team int, op
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
 	var members []*User
 	resp, err := s.client.Do(ctx, req, &members)
 	if err != nil {
@@ -196,6 +267,9 @@ func (s *OrganizationsService) ListTeamMembers(ctx context.Context, team int, op
 // IsTeamMember checks if a user is a member of the specified team.
 //
 // GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-member
+//
+// Deprecated: This API has been marked as deprecated in the Github API docs,
+// OrganizationsService.GetTeamMembership method should be used instead.
 func (s *OrganizationsService) IsTeamMember(ctx context.Context, team int, user string) (bool, *Response, error) {
 	u := fmt.Sprintf("teams/%v/members/%v", team, user)
 	req, err := s.client.NewRequest("GET", u, nil)
@@ -224,7 +298,8 @@ func (s *OrganizationsService) ListTeamRepos(ctx context.Context, team int, opt
 	}
 
 	// TODO: remove custom Accept header when topics API fully launches.
-	req.Header.Set("Accept", mediaTypeTopicsPreview)
+	headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
 
 	var repos []*Repository
 	resp, err := s.client.Do(ctx, req, &repos)
@@ -247,7 +322,8 @@ func (s *OrganizationsService) IsTeamRepo(ctx context.Context, team int, owner s
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeOrgPermissionRepo)
+	headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
 
 	repository := new(Repository)
 	resp, err := s.client.Do(ctx, req, repository)
@@ -315,6 +391,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 {
@@ -334,6 +413,8 @@ func (s *OrganizationsService) GetTeamMembership(ctx context.Context, team int,
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
 	t := new(Membership)
 	resp, err := s.client.Do(ctx, req, t)
 	if err != nil {
diff --git a/github/pulls.go b/github/pulls.go
index bc46081f..6681c8b2 100644
--- a/github/pulls.go
+++ b/github/pulls.go
@@ -138,7 +138,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string
 	return pull, resp, nil
 }
 
-// GetRaw gets raw (diff or patch) format of a pull request.
+// GetRaw gets a single pull request in raw (diff or patch) format.
 func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opt RawOptions) (string, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
 	req, err := s.client.NewRequest("GET", u, nil)
@@ -155,13 +155,13 @@ func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo str
 		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
 	}
 
-	ret := new(bytes.Buffer)
-	resp, err := s.client.Do(ctx, req, ret)
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
 	if err != nil {
 		return "", resp, err
 	}
 
-	return ret.String(), resp, nil
+	return buf.String(), resp, nil
 }
 
 // NewPullRequest represents a new pull request to be created.
diff --git a/github/repos.go b/github/repos.go
index e3fe26fc..13daa7e9 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -481,6 +481,8 @@ func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
 	var teams []*Team
 	resp, err := s.client.Do(ctx, req, &teams)
 	if err != nil {
diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go
index 100a9257..61ee9d39 100644
--- a/github/repos_collaborators.go
+++ b/github/repos_collaborators.go
@@ -41,6 +41,8 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
 	var users []*User
 	resp, err := s.client.Do(ctx, req, &users)
 	if err != nil {
diff --git a/github/repos_commits.go b/github/repos_commits.go
index 4451b6bb..04847373 100644
--- a/github/repos_commits.go
+++ b/github/repos_commits.go
@@ -140,10 +140,9 @@ func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo strin
 }
 
 // GetCommit fetches the specified commit, including all details about it.
-// todo: support media formats - https://github.com/google/go-github/issues/6
 //
 // GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit
-// See also: https://developer.github.com//v3/git/commits/#get-a-single-commit provides the same functionality
+// See also: https://developer.github.com/v3/git/commits/#get-a-single-commit provides the same functionality
 func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
 
@@ -164,6 +163,32 @@ func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha st
 	return commit, resp, nil
 }
 
+// GetCommitRaw fetches the specified commit in raw (diff or patch) format.
+func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opt RawOptions) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	switch opt.Type {
+	case Diff:
+		req.Header.Set("Accept", mediaTypeV3Diff)
+	case Patch:
+		req.Header.Set("Accept", mediaTypeV3Patch)
+	default:
+		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
+	}
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
 // GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is
 // supplied and no new commits have occurred, a 304 Unmodified response is returned.
 //


Test patch:
diff --git a/github/apps_installation_test.go b/github/apps_installation_test.go
index 69598cfe..ec796cd3 100644
--- a/github/apps_installation_test.go
+++ b/github/apps_installation_test.go
@@ -39,6 +39,31 @@ func TestAppsService_ListRepos(t *testing.T) {
 	}
 }
 
+func TestAppsService_ListUserRepos(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/user/installations/1/repositories", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{
+			"page":     "1",
+			"per_page": "2",
+		})
+		fmt.Fprint(w, `{"repositories": [{"id":1}]}`)
+	})
+
+	opt := &ListOptions{Page: 1, PerPage: 2}
+	repositories, _, err := client.Apps.ListUserRepos(context.Background(), 1, opt)
+	if err != nil {
+		t.Errorf("Apps.ListUserRepos returned error: %v", err)
+	}
+
+	want := []*Repository{{ID: Int(1)}}
+	if !reflect.DeepEqual(repositories, want) {
+		t.Errorf("Apps.ListUserRepos returned %+v, want %+v", repositories, want)
+	}
+}
+
 func TestAppsService_AddRepository(t *testing.T) {
 	setup()
 	defer teardown()
diff --git a/github/apps_test.go b/github/apps_test.go
index f847b842..9ef1f468 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -13,6 +13,48 @@ import (
 	"testing"
 )
 
+func TestAppsService_Get_authenticatedApp(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/app", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	app, _, err := client.Apps.Get(context.Background(), "")
+	if err != nil {
+		t.Errorf("Apps.Get returned error: %v", err)
+	}
+
+	want := &App{ID: Int(1)}
+	if !reflect.DeepEqual(app, want) {
+		t.Errorf("Apps.Get returned %+v, want %+v", app, want)
+	}
+}
+
+func TestAppsService_Get_specifiedApp(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/apps/a", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
+		fmt.Fprint(w, `{"html_url":"https://github.com/apps/a"}`)
+	})
+
+	app, _, err := client.Apps.Get(context.Background(), "a")
+	if err != nil {
+		t.Errorf("Apps.Get returned error: %v", err)
+	}
+
+	want := &App{HTMLURL: String("https://github.com/apps/a")}
+	if !reflect.DeepEqual(app, want) {
+		t.Errorf("Apps.Get returned %+v, want %+v", *app.HTMLURL, *want.HTMLURL)
+	}
+}
+
 func TestAppsService_ListInstallations(t *testing.T) {
 	setup()
 	defer teardown()
@@ -38,3 +80,71 @@ func TestAppsService_ListInstallations(t *testing.T) {
 		t.Errorf("Apps.ListInstallations returned %+v, want %+v", installations, want)
 	}
 }
+
+func TestAppsService_GetInstallation(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	installation, _, err := client.Apps.GetInstallation(context.Background(), 1)
+	if err != nil {
+		t.Errorf("Apps.GetInstallation returned error: %v", err)
+	}
+
+	want := &Installation{ID: Int(1)}
+	if !reflect.DeepEqual(installation, want) {
+		t.Errorf("Apps.GetInstallation returned %+v, want %+v", installation, want)
+	}
+}
+
+func TestAppsService_ListUserInstallations(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/user/installations", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
+		testFormValues(t, r, values{
+			"page":     "1",
+			"per_page": "2",
+		})
+		fmt.Fprint(w, `{"installations":[{"id":1}]}`)
+	})
+
+	opt := &ListOptions{Page: 1, PerPage: 2}
+	installations, _, err := client.Apps.ListUserInstallations(context.Background(), opt)
+	if err != nil {
+		t.Errorf("Apps.ListUserInstallations returned error: %v", err)
+	}
+
+	want := []*Installation{{ID: Int(1)}}
+	if !reflect.DeepEqual(installations, want) {
+		t.Errorf("Apps.ListUserInstallations returned %+v, want %+v", installations, want)
+	}
+}
+
+func TestAppsService_CreateInstallationToken(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
+		fmt.Fprint(w, `{"token":"t"}`)
+	})
+
+	token, _, err := client.Apps.CreateInstallationToken(context.Background(), 1)
+	if err != nil {
+		t.Errorf("Apps.CreateInstallationToken returned error: %v", err)
+	}
+
+	want := &InstallationToken{Token: String("t")}
+	if !reflect.DeepEqual(token, want) {
+		t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want)
+	}
+}
diff --git a/github/github_test.go b/github/github_test.go
index aff436a6..cc62fc6b 100644
--- a/github/github_test.go
+++ b/github/github_test.go
@@ -186,6 +186,41 @@ func TestNewClient(t *testing.T) {
 	}
 }
 
+func TestNewEnterpriseClient(t *testing.T) {
+	baseURL := "https://custom-url/"
+	uploadURL := "https://custom-upload-url/"
+	c, err := NewEnterpriseClient(baseURL, uploadURL, nil)
+	if err != nil {
+		t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err)
+	}
+
+	if got, want := c.BaseURL.String(), baseURL; got != want {
+		t.Errorf("NewClient BaseURL is %v, want %v", got, want)
+	}
+	if got, want := c.UploadURL.String(), uploadURL; got != want {
+		t.Errorf("NewClient UploadURL is %v, want %v", got, want)
+	}
+}
+
+func TestNewEnterpriseClient_addsTrailingSlashToURLs(t *testing.T) {
+	baseURL := "https://custom-url"
+	uploadURL := "https://custom-upload-url"
+	formattedBaseURL := baseURL + "/"
+	formattedUploadURL := uploadURL + "/"
+
+	c, err := NewEnterpriseClient(baseURL, uploadURL, nil)
+	if err != nil {
+		t.Fatalf("NewEnterpriseClient returned unexpected error: %v", err)
+	}
+
+	if got, want := c.BaseURL.String(), formattedBaseURL; got != want {
+		t.Errorf("NewClient BaseURL is %v, want %v", got, want)
+	}
+	if got, want := c.UploadURL.String(), formattedUploadURL; got != want {
+		t.Errorf("NewClient UploadURL is %v, want %v", got, want)
+	}
+}
+
 // Ensure that length of Client.rateLimits is the same as number of fields in RateLimits struct.
 func TestClient_rateLimits(t *testing.T) {
 	if got, want := len(Client{}.rateLimits), reflect.TypeOf(RateLimits{}).NumField(); got != want {
diff --git a/github/orgs_teams_test.go b/github/orgs_teams_test.go
index ff1101dc..04669866 100644
--- a/github/orgs_teams_test.go
+++ b/github/orgs_teams_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 	"time"
 )
@@ -21,6 +22,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 +50,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 +65,42 @@ 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")}
+	input := &NewTeam{Name: "n", Privacy: String("closed"), RepoNames: []string{"r"}}
 
 	mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
-		v := new(Team)
+		v := new(NewTeam)
 		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)
 		}
@@ -100,12 +128,13 @@ func TestOrganizationsService_EditTeam(t *testing.T) {
 	setup()
 	defer teardown()
 
-	input := &Team{Name: String("n"), Privacy: String("closed")}
+	input := &NewTeam{Name: "n", Privacy: String("closed")}
 
 	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
-		v := new(Team)
+		v := new(NewTeam)
 		json.NewDecoder(r.Body).Decode(v)
 
+		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testMethod(t, r, "PATCH")
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
@@ -131,6 +160,7 @@ func TestOrganizationsService_DeleteTeam(t *testing.T) {
 
 	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
+		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 	})
 
 	_, err := client.Organizations.DeleteTeam(context.Background(), 1)
@@ -139,12 +169,36 @@ func TestOrganizationsService_DeleteTeam(t *testing.T) {
 	}
 }
 
+func TestOrganizationsService_ListChildTeams(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc("/teams/1/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":2}]`)
+	})
+
+	opt := &ListOptions{Page: 2}
+	teams, _, err := client.Organizations.ListChildTeams(context.Background(), 1, opt)
+	if err != nil {
+		t.Errorf("Organizations.ListTeams returned error: %v", err)
+	}
+
+	want := []*Team{{ID: Int(2)}}
+	if !reflect.DeepEqual(teams, want) {
+		t.Errorf("Organizations.ListTeams returned %+v, want %+v", teams, want)
+	}
+}
+
 func TestOrganizationsService_ListTeamMembers(t *testing.T) {
 	setup()
 	defer teardown()
 
 	mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"role": "member", "page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -268,7 +322,8 @@ func TestOrganizationsService_ListTeamRepos(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTopicsPreview)
+		acceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -291,7 +346,8 @@ func TestOrganizationsService_IsTeamRepo_true(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeOrgPermissionRepo)
+		acceptHeaders := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -423,6 +479,7 @@ func TestOrganizationsService_GetTeamMembership(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		fmt.Fprint(w, `{"url":"u", "state":"active"}`)
 	})
 
@@ -487,6 +544,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}]`)
 	})
diff --git a/github/pulls_test.go b/github/pulls_test.go
index ea31e521..89adf239 100644
--- a/github/pulls_test.go
+++ b/github/pulls_test.go
@@ -70,9 +70,10 @@ func TestPullRequestsService_Get(t *testing.T) {
 	}
 }
 
-func TestPullRequestsService_GetRawDiff(t *testing.T) {
+func TestPullRequestsService_GetRaw_diff(t *testing.T) {
 	setup()
 	defer teardown()
+
 	const rawStr = "@@diff content"
 
 	mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
@@ -81,19 +82,20 @@ func TestPullRequestsService_GetRawDiff(t *testing.T) {
 		fmt.Fprint(w, rawStr)
 	})
 
-	ret, _, err := client.PullRequests.GetRaw(context.Background(), "o", "r", 1, RawOptions{Diff})
+	got, _, err := client.PullRequests.GetRaw(context.Background(), "o", "r", 1, RawOptions{Diff})
 	if err != nil {
 		t.Fatalf("PullRequests.GetRaw returned error: %v", err)
 	}
-
-	if ret != rawStr {
-		t.Errorf("PullRequests.GetRaw returned %s want %s", ret, rawStr)
+	want := rawStr
+	if got != want {
+		t.Errorf("PullRequests.GetRaw returned %s want %s", got, want)
 	}
 }
 
-func TestPullRequestsService_GetRawPatch(t *testing.T) {
+func TestPullRequestsService_GetRaw_patch(t *testing.T) {
 	setup()
 	defer teardown()
+
 	const rawStr = "@@patch content"
 
 	mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
@@ -102,17 +104,17 @@ func TestPullRequestsService_GetRawPatch(t *testing.T) {
 		fmt.Fprint(w, rawStr)
 	})
 
-	ret, _, err := client.PullRequests.GetRaw(context.Background(), "o", "r", 1, RawOptions{Patch})
+	got, _, err := client.PullRequests.GetRaw(context.Background(), "o", "r", 1, RawOptions{Patch})
 	if err != nil {
 		t.Fatalf("PullRequests.GetRaw returned error: %v", err)
 	}
-
-	if ret != rawStr {
-		t.Errorf("PullRequests.GetRaw returned %s want %s", ret, rawStr)
+	want := rawStr
+	if got != want {
+		t.Errorf("PullRequests.GetRaw returned %s want %s", got, want)
 	}
 }
 
-func TestPullRequestsService_GetRawInvalid(t *testing.T) {
+func TestPullRequestsService_GetRaw_invalid(t *testing.T) {
 	setup()
 	defer teardown()
 
diff --git a/github/repos_collaborators_test.go b/github/repos_collaborators_test.go
index 4ac23934..4f3d4770 100644
--- a/github/repos_collaborators_test.go
+++ b/github/repos_collaborators_test.go
@@ -20,6 +20,7 @@ func TestRepositoriesService_ListCollaborators(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
 	})
diff --git a/github/repos_commits_test.go b/github/repos_commits_test.go
index 98eadabb..1d5f5ec9 100644
--- a/github/repos_commits_test.go
+++ b/github/repos_commits_test.go
@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 	"time"
 )
@@ -126,6 +127,63 @@ func TestRepositoriesService_GetCommit(t *testing.T) {
 	}
 }
 
+func TestRepositoriesService_GetCommitRaw_diff(t *testing.T) {
+	setup()
+	defer teardown()
+
+	const rawStr = "@@diff content"
+
+	mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeV3Diff)
+		fmt.Fprint(w, rawStr)
+	})
+
+	got, _, err := client.Repositories.GetCommitRaw(context.Background(), "o", "r", "s", RawOptions{Type: Diff})
+	if err != nil {
+		t.Fatalf("Repositories.GetCommitRaw returned error: %v", err)
+	}
+	want := rawStr
+	if got != want {
+		t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want)
+	}
+}
+
+func TestRepositoriesService_GetCommitRaw_patch(t *testing.T) {
+	setup()
+	defer teardown()
+
+	const rawStr = "@@patch content"
+
+	mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeV3Patch)
+		fmt.Fprint(w, rawStr)
+	})
+
+	got, _, err := client.Repositories.GetCommitRaw(context.Background(), "o", "r", "s", RawOptions{Type: Patch})
+	if err != nil {
+		t.Fatalf("Repositories.GetCommitRaw returned error: %v", err)
+	}
+	want := rawStr
+	if got != want {
+		t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want)
+	}
+}
+
+func TestRepositoriesService_GetCommitRaw_invalid(t *testing.T) {
+	setup()
+	defer teardown()
+
+	_, _, err := client.Repositories.GetCommitRaw(context.Background(), "o", "r", "s", RawOptions{100})
+	if err == nil {
+		t.Fatal("Repositories.GetCommitRaw should return error")
+	}
+	if !strings.Contains(err.Error(), "unsupported raw type") {
+		t.Error("Repositories.GetCommitRaw should return unsupported raw type error")
+	}
+}
+
 func TestRepositoriesService_GetCommitSHA1(t *testing.T) {
 	setup()
 	defer teardown()
diff --git a/github/repos_test.go b/github/repos_test.go
index 43f8bda7..9e522c82 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -404,6 +404,7 @@ func TestRepositoriesService_ListTeams(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/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}]`)
 	})