Repository: google/go-github
Pull request #1930 (2021-06-27 18:44:03)

Add test cases for JSON resource marshaling
Resources Covered :

* MinutesUsedBreakdown
* ActionBilling
* PackageBilling
* StorageBilling

Helps with issue: #55


Patch:
diff --git a/github/activity.go b/github/activity.go
index 4310564b..e683afb9 100644
--- a/github/activity.go
+++ b/github/activity.go
@@ -21,22 +21,25 @@ type FeedLink struct {
 
 // Feeds represents timeline resources in Atom format.
 type Feeds struct {
-	TimelineURL                 *string  `json:"timeline_url,omitempty"`
-	UserURL                     *string  `json:"user_url,omitempty"`
-	CurrentUserPublicURL        *string  `json:"current_user_public_url,omitempty"`
-	CurrentUserURL              *string  `json:"current_user_url,omitempty"`
-	CurrentUserActorURL         *string  `json:"current_user_actor_url,omitempty"`
-	CurrentUserOrganizationURL  *string  `json:"current_user_organization_url,omitempty"`
-	CurrentUserOrganizationURLs []string `json:"current_user_organization_urls,omitempty"`
-	Links                       *struct {
-		Timeline                 *FeedLink   `json:"timeline,omitempty"`
-		User                     *FeedLink   `json:"user,omitempty"`
-		CurrentUserPublic        *FeedLink   `json:"current_user_public,omitempty"`
-		CurrentUser              *FeedLink   `json:"current_user,omitempty"`
-		CurrentUserActor         *FeedLink   `json:"current_user_actor,omitempty"`
-		CurrentUserOrganization  *FeedLink   `json:"current_user_organization,omitempty"`
-		CurrentUserOrganizations []*FeedLink `json:"current_user_organizations,omitempty"`
-	} `json:"_links,omitempty"`
+	TimelineURL                 *string    `json:"timeline_url,omitempty"`
+	UserURL                     *string    `json:"user_url,omitempty"`
+	CurrentUserPublicURL        *string    `json:"current_user_public_url,omitempty"`
+	CurrentUserURL              *string    `json:"current_user_url,omitempty"`
+	CurrentUserActorURL         *string    `json:"current_user_actor_url,omitempty"`
+	CurrentUserOrganizationURL  *string    `json:"current_user_organization_url,omitempty"`
+	CurrentUserOrganizationURLs []string   `json:"current_user_organization_urls,omitempty"`
+	Links                       *FeedLinks `json:"_links,omitempty"`
+}
+
+// FeedLinks represents the links in a Feed.
+type FeedLinks struct {
+	Timeline                 *FeedLink   `json:"timeline,omitempty"`
+	User                     *FeedLink   `json:"user,omitempty"`
+	CurrentUserPublic        *FeedLink   `json:"current_user_public,omitempty"`
+	CurrentUser              *FeedLink   `json:"current_user,omitempty"`
+	CurrentUserActor         *FeedLink   `json:"current_user_actor,omitempty"`
+	CurrentUserOrganization  *FeedLink   `json:"current_user_organization,omitempty"`
+	CurrentUserOrganizations []*FeedLink `json:"current_user_organizations,omitempty"`
 }
 
 // ListFeeds lists all the feeds available to the authenticated user.
diff --git a/github/code-scanning.go b/github/code-scanning.go
index 9eb711cf..8602c446 100644
--- a/github/code-scanning.go
+++ b/github/code-scanning.go
@@ -18,11 +18,23 @@ import (
 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/code-scanning/
 type CodeScanningService service
 
+// Tool represents the tool used to generate a GitHub Code Scanning Alert.
+//
+// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#list-code-scanning-alerts-for-a-repository
+type Tool struct {
+	Name    *string `json:"name,omitempty"`
+	GUID    *string `json:"guid,omitempty"`
+	Version *string `json:"version,omitempty"`
+}
+
+// Alert represents an individual GitHub Code Scanning Alert on a single repository.
+//
+// GitHub API docs: https://docs.github.com/en/rest/reference/code-scanning#list-code-scanning-alerts-for-a-repository
 type Alert struct {
 	RuleID          *string    `json:"rule_id,omitempty"`
 	RuleSeverity    *string    `json:"rule_severity,omitempty"`
 	RuleDescription *string    `json:"rule_description,omitempty"`
-	Tool            *string    `json:"tool,omitempty"`
+	Tool            *Tool      `json:"tool,omitempty"`
 	CreatedAt       *Timestamp `json:"created_at,omitempty"`
 	Open            *bool      `json:"open,omitempty"`
 	ClosedBy        *User      `json:"closed_by,omitempty"`
diff --git a/github/event_types.go b/github/event_types.go
index 48347f37..f99a1296 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -215,66 +215,111 @@ type GollumEvent struct {
 // EditChange represents the changes when an issue, pull request, or comment has
 // been edited.
 type EditChange struct {
-	Title *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"title,omitempty"`
-	Body *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"body,omitempty"`
-	Base *struct {
-		Ref *struct {
-			From *string `json:"from,omitempty"`
-		} `json:"ref,omitempty"`
-		SHA *struct {
-			From *string `json:"from,omitempty"`
-		} `json:"sha,omitempty"`
-	} `json:"base,omitempty"`
+	Title *EditTitle `json:"title,omitempty"`
+	Body  *EditBody  `json:"body,omitempty"`
+	Base  *EditBase  `json:"base,omitempty"`
+}
+
+// EditTitle represents a pull-request title change.
+type EditTitle struct {
+	From *string `json:"from,omitempty"`
+}
+
+// EditBody represents a change of pull-request body.
+type EditBody struct {
+	From *string `json:"from,omitempty"`
+}
+
+// EditBase represents the change of a pull-request base branch.
+type EditBase struct {
+	Ref *EditRef `json:"ref,omitempty"`
+	SHA *EditSHA `json:"sha,omitempty"`
+}
+
+// EditRef represents a ref change of a pull-request.
+type EditRef struct {
+	From *string `json:"from,omitempty"`
+}
+
+// EditSHA represents a sha change of a pull-request.
+type EditSHA struct {
+	From *string `json:"from,omitempty"`
 }
 
 // ProjectChange represents the changes when a project has been edited.
 type ProjectChange struct {
-	Name *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"name,omitempty"`
-	Body *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"body,omitempty"`
+	Name *ProjectName `json:"name,omitempty"`
+	Body *ProjectBody `json:"body,omitempty"`
+}
+
+// ProjectName represents a project name change.
+type ProjectName struct {
+	From *string `json:"from,omitempty"`
+}
+
+// ProjectBody represents a project body change.
+type ProjectBody struct {
+	From *string `json:"from,omitempty"`
 }
 
 // ProjectCardChange represents the changes when a project card has been edited.
 type ProjectCardChange struct {
-	Note *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"note,omitempty"`
+	Note *ProjectCardNote `json:"note,omitempty"`
+}
+
+// ProjectCardNote represents a change of a note of a project card.
+type ProjectCardNote struct {
+	From *string `json:"from,omitempty"`
 }
 
 // ProjectColumnChange represents the changes when a project column has been edited.
 type ProjectColumnChange struct {
-	Name *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"name,omitempty"`
+	Name *ProjectColumnName `json:"name,omitempty"`
+}
+
+// ProjectColumnName represents a project column name change.
+type ProjectColumnName struct {
+	From *string `json:"from,omitempty"`
 }
 
 // TeamChange represents the changes when a team has been edited.
 type TeamChange struct {
-	Description *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"description,omitempty"`
-	Name *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"name,omitempty"`
-	Privacy *struct {
-		From *string `json:"from,omitempty"`
-	} `json:"privacy,omitempty"`
-	Repository *struct {
-		Permissions *struct {
-			From *struct {
-				Admin *bool `json:"admin,omitempty"`
-				Pull  *bool `json:"pull,omitempty"`
-				Push  *bool `json:"push,omitempty"`
-			} `json:"from,omitempty"`
-		} `json:"permissions,omitempty"`
-	} `json:"repository,omitempty"`
+	Description *TeamDescription `json:"description,omitempty"`
+	Name        *TeamName        `json:"name,omitempty"`
+	Privacy     *TeamPrivacy     `json:"privacy,omitempty"`
+	Repository  *TeamRepository  `json:"repository,omitempty"`
+}
+
+// TeamDescription represents a team description change.
+type TeamDescription struct {
+	From *string `json:"from,omitempty"`
+}
+
+// TeamName represents a team name change.
+type TeamName struct {
+	From *string `json:"from,omitempty"`
+}
+
+// TeamPrivacy represents a team privacy change.
+type TeamPrivacy struct {
+	From *string `json:"from,omitempty"`
+}
+
+// TeamRepository represents a team repository permission change.
+type TeamRepository struct {
+	Permissions *TeamPermissions `json:"permissions,omitempty"`
+}
+
+// TeamPermissions represents a team permission change.
+type TeamPermissions struct {
+	From *TeamPermissionsFrom `json:"from,omitempty"`
+}
+
+// TeamPermissionsFrom represents a team permission change.
+type TeamPermissionsFrom struct {
+	Admin *bool `json:"admin,omitempty"`
+	Pull  *bool `json:"pull,omitempty"`
+	Push  *bool `json:"push,omitempty"`
 }
 
 // InstallationEvent is triggered when a GitHub App has been installed, uninstalled, suspend, unsuspended
@@ -890,22 +935,28 @@ type RepositoryVulnerabilityAlertEvent struct {
 	Action *string `json:"action,omitempty"`
 
 	//The security alert of the vulnerable dependency.
-	Alert *struct {
-		ID                  *int64     `json:"id,omitempty"`
-		AffectedRange       *string    `json:"affected_range,omitempty"`
-		AffectedPackageName *string    `json:"affected_package_name,omitempty"`
-		ExternalReference   *string    `json:"external_reference,omitempty"`
-		ExternalIdentifier  *string    `json:"external_identifier,omitempty"`
-		FixedIn             *string    `json:"fixed_in,omitempty"`
-		Dismisser           *User      `json:"dismisser,omitempty"`
-		DismissReason       *string    `json:"dismiss_reason,omitempty"`
-		DismissedAt         *Timestamp `json:"dismissed_at,omitempty"`
-	} `json:"alert,omitempty"`
+	Alert *RepositoryVulnerabilityAlert `json:"alert,omitempty"`
 
 	//The repository of the vulnerable dependency.
 	Repository *Repository `json:"repository,omitempty"`
 }
 
+// RepositoryVulnerabilityAlert represents a repository security alert.
+type RepositoryVulnerabilityAlert struct {
+	ID                       *int64     `json:"id,omitempty"`
+	AffectedRange            *string    `json:"affected_range,omitempty"`
+	AffectedPackageName      *string    `json:"affected_package_name,omitempty"`
+	ExternalReference        *string    `json:"external_reference,omitempty"`
+	ExternalIdentifier       *string    `json:"external_identifier,omitempty"`
+	GitHubSecurityAdvisoryID *string    `json:"ghsa_id,omitempty"`
+	Severity                 *string    `json:"severity,omitempty"`
+	CreatedAt                *Timestamp `json:"created_at,omitempty"`
+	FixedIn                  *string    `json:"fixed_in,omitempty"`
+	Dismisser                *User      `json:"dismisser,omitempty"`
+	DismissReason            *string    `json:"dismiss_reason,omitempty"`
+	DismissedAt              *Timestamp `json:"dismissed_at,omitempty"`
+}
+
 // StarEvent is triggered when a star is added or removed from a repository.
 // The Webhook event name is "star".
 //
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 1c17384e..a16db624 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -212,12 +212,12 @@ func (a *Alert) GetRuleSeverity() string {
 	return *a.RuleSeverity
 }
 
-// GetTool returns the Tool field if it's non-nil, zero value otherwise.
-func (a *Alert) GetTool() string {
-	if a == nil || a.Tool == nil {
-		return ""
+// GetTool returns the Tool field.
+func (a *Alert) GetTool() *Tool {
+	if a == nil {
+		return nil
 	}
-	return *a.Tool
+	return a.Tool
 }
 
 // GetURL returns the URL field if it's non-nil, zero value otherwise.
@@ -3620,6 +3620,78 @@ func (d *DraftReviewComment) GetStartSide() string {
 	return *d.StartSide
 }
 
+// GetRef returns the Ref field.
+func (e *EditBase) GetRef() *EditRef {
+	if e == nil {
+		return nil
+	}
+	return e.Ref
+}
+
+// GetSHA returns the SHA field.
+func (e *EditBase) GetSHA() *EditSHA {
+	if e == nil {
+		return nil
+	}
+	return e.SHA
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (e *EditBody) GetFrom() string {
+	if e == nil || e.From == nil {
+		return ""
+	}
+	return *e.From
+}
+
+// GetBase returns the Base field.
+func (e *EditChange) GetBase() *EditBase {
+	if e == nil {
+		return nil
+	}
+	return e.Base
+}
+
+// GetBody returns the Body field.
+func (e *EditChange) GetBody() *EditBody {
+	if e == nil {
+		return nil
+	}
+	return e.Body
+}
+
+// GetTitle returns the Title field.
+func (e *EditChange) GetTitle() *EditTitle {
+	if e == nil {
+		return nil
+	}
+	return e.Title
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (e *EditRef) GetFrom() string {
+	if e == nil || e.From == nil {
+		return ""
+	}
+	return *e.From
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (e *EditSHA) GetFrom() string {
+	if e == nil || e.From == nil {
+		return ""
+	}
+	return *e.From
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (e *EditTitle) GetFrom() string {
+	if e == nil || e.From == nil {
+		return ""
+	}
+	return *e.From
+}
+
 // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
 func (e *Enterprise) GetAvatarURL() string {
 	if e == nil || e.AvatarURL == nil {
@@ -3820,6 +3892,22 @@ func (e *EnvReviewers) GetType() string {
 	return *e.Type
 }
 
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (e *ErrorBlock) GetCreatedAt() Timestamp {
+	if e == nil || e.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *e.CreatedAt
+}
+
+// GetBlock returns the Block field.
+func (e *ErrorResponse) GetBlock() *ErrorBlock {
+	if e == nil {
+		return nil
+	}
+	return e.Block
+}
+
 // GetActor returns the Actor field.
 func (e *Event) GetActor() *User {
 	if e == nil {
@@ -3900,6 +3988,54 @@ func (f *FeedLink) GetType() string {
 	return *f.Type
 }
 
+// GetCurrentUser returns the CurrentUser field.
+func (f *FeedLinks) GetCurrentUser() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.CurrentUser
+}
+
+// GetCurrentUserActor returns the CurrentUserActor field.
+func (f *FeedLinks) GetCurrentUserActor() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.CurrentUserActor
+}
+
+// GetCurrentUserOrganization returns the CurrentUserOrganization field.
+func (f *FeedLinks) GetCurrentUserOrganization() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.CurrentUserOrganization
+}
+
+// GetCurrentUserPublic returns the CurrentUserPublic field.
+func (f *FeedLinks) GetCurrentUserPublic() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.CurrentUserPublic
+}
+
+// GetTimeline returns the Timeline field.
+func (f *FeedLinks) GetTimeline() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.Timeline
+}
+
+// GetUser returns the User field.
+func (f *FeedLinks) GetUser() *FeedLink {
+	if f == nil {
+		return nil
+	}
+	return f.User
+}
+
 // GetCurrentUserActorURL returns the CurrentUserActorURL field if it's non-nil, zero value otherwise.
 func (f *Feeds) GetCurrentUserActorURL() string {
 	if f == nil || f.CurrentUserActorURL == nil {
@@ -3932,6 +4068,14 @@ func (f *Feeds) GetCurrentUserURL() string {
 	return *f.CurrentUserURL
 }
 
+// GetLinks returns the Links field.
+func (f *Feeds) GetLinks() *FeedLinks {
+	if f == nil {
+		return nil
+	}
+	return f.Links
+}
+
 // GetTimelineURL returns the TimelineURL field if it's non-nil, zero value otherwise.
 func (f *Feeds) GetTimelineURL() string {
 	if f == nil || f.TimelineURL == nil {
@@ -9316,6 +9460,14 @@ func (p *Project) GetURL() string {
 	return *p.URL
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (p *ProjectBody) GetFrom() string {
+	if p == nil || p.From == nil {
+		return ""
+	}
+	return *p.From
+}
+
 // GetArchived returns the Archived field if it's non-nil, zero value otherwise.
 func (p *ProjectCard) GetArchived() bool {
 	if p == nil || p.Archived == nil {
@@ -9436,6 +9588,14 @@ func (p *ProjectCard) GetURL() string {
 	return *p.URL
 }
 
+// GetNote returns the Note field.
+func (p *ProjectCardChange) GetNote() *ProjectCardNote {
+	if p == nil {
+		return nil
+	}
+	return p.Note
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (p *ProjectCardEvent) GetAction() string {
 	if p == nil || p.Action == nil {
@@ -9508,6 +9668,14 @@ func (p *ProjectCardListOptions) GetArchivedState() string {
 	return *p.ArchivedState
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (p *ProjectCardNote) GetFrom() string {
+	if p == nil || p.From == nil {
+		return ""
+	}
+	return *p.From
+}
+
 // GetArchived returns the Archived field if it's non-nil, zero value otherwise.
 func (p *ProjectCardOptions) GetArchived() bool {
 	if p == nil || p.Archived == nil {
@@ -9516,6 +9684,22 @@ func (p *ProjectCardOptions) GetArchived() bool {
 	return *p.Archived
 }
 
+// GetBody returns the Body field.
+func (p *ProjectChange) GetBody() *ProjectBody {
+	if p == nil {
+		return nil
+	}
+	return p.Body
+}
+
+// GetName returns the Name field.
+func (p *ProjectChange) GetName() *ProjectName {
+	if p == nil {
+		return nil
+	}
+	return p.Name
+}
+
 // GetPermission returns the Permission field if it's non-nil, zero value otherwise.
 func (p *ProjectCollaboratorOptions) GetPermission() string {
 	if p == nil || p.Permission == nil {
@@ -9588,6 +9772,14 @@ func (p *ProjectColumn) GetURL() string {
 	return *p.URL
 }
 
+// GetName returns the Name field.
+func (p *ProjectColumnChange) GetName() *ProjectColumnName {
+	if p == nil {
+		return nil
+	}
+	return p.Name
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (p *ProjectColumnEvent) GetAction() string {
 	if p == nil || p.Action == nil {
@@ -9652,6 +9844,14 @@ func (p *ProjectColumnEvent) GetSender() *User {
 	return p.Sender
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (p *ProjectColumnName) GetFrom() string {
+	if p == nil || p.From == nil {
+		return ""
+	}
+	return *p.From
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (p *ProjectEvent) GetAction() string {
 	if p == nil || p.Action == nil {
@@ -9708,6 +9908,14 @@ func (p *ProjectEvent) GetSender() *User {
 	return p.Sender
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (p *ProjectName) GetFrom() string {
+	if p == nil || p.From == nil {
+		return ""
+	}
+	return *p.From
+}
+
 // GetBody returns the Body field if it's non-nil, zero value otherwise.
 func (p *ProjectOptions) GetBody() string {
 	if p == nil || p.Body == nil {
@@ -9972,6 +10180,14 @@ func (p *PullRequest) GetAuthorAssociation() string {
 	return *p.AuthorAssociation
 }
 
+// GetAutoMerge returns the AutoMerge field.
+func (p *PullRequest) GetAutoMerge() *PullRequestAutoMerge {
+	if p == nil {
+		return nil
+	}
+	return p.AutoMerge
+}
+
 // GetBase returns the Base field.
 func (p *PullRequest) GetBase() *PullRequestBranch {
 	if p == nil {
@@ -10284,6 +10500,38 @@ func (p *PullRequest) GetUser() *User {
 	return p.User
 }
 
+// GetCommitMessage returns the CommitMessage field if it's non-nil, zero value otherwise.
+func (p *PullRequestAutoMerge) GetCommitMessage() string {
+	if p == nil || p.CommitMessage == nil {
+		return ""
+	}
+	return *p.CommitMessage
+}
+
+// GetCommitTitle returns the CommitTitle field if it's non-nil, zero value otherwise.
+func (p *PullRequestAutoMerge) GetCommitTitle() string {
+	if p == nil || p.CommitTitle == nil {
+		return ""
+	}
+	return *p.CommitTitle
+}
+
+// GetEnabledBy returns the EnabledBy field.
+func (p *PullRequestAutoMerge) GetEnabledBy() *User {
+	if p == nil {
+		return nil
+	}
+	return p.EnabledBy
+}
+
+// GetMergeMethod returns the MergeMethod field if it's non-nil, zero value otherwise.
+func (p *PullRequestAutoMerge) GetMergeMethod() string {
+	if p == nil || p.MergeMethod == nil {
+		return ""
+	}
+	return *p.MergeMethod
+}
+
 // GetLabel returns the Label field if it's non-nil, zero value otherwise.
 func (p *PullRequestBranch) GetLabel() string {
 	if p == nil || p.Label == nil {
@@ -12460,6 +12708,14 @@ func (r *Repository) GetNotificationsURL() string {
 	return *r.NotificationsURL
 }
 
+// GetOpenIssues returns the OpenIssues field if it's non-nil, zero value otherwise.
+func (r *Repository) GetOpenIssues() int {
+	if r == nil || r.OpenIssues == nil {
+		return 0
+	}
+	return *r.OpenIssues
+}
+
 // GetOpenIssuesCount returns the OpenIssuesCount field if it's non-nil, zero value otherwise.
 func (r *Repository) GetOpenIssuesCount() int {
 	if r == nil || r.OpenIssuesCount == nil {
@@ -12676,6 +12932,14 @@ func (r *Repository) GetVisibility() string {
 	return *r.Visibility
 }
 
+// GetWatchers returns the Watchers field if it's non-nil, zero value otherwise.
+func (r *Repository) GetWatchers() int {
+	if r == nil || r.Watchers == nil {
+		return 0
+	}
+	return *r.Watchers
+}
+
 // GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise.
 func (r *Repository) GetWatchersCount() int {
 	if r == nil || r.WatchersCount == nil {
@@ -13452,6 +13716,102 @@ func (r *RepositoryTag) GetZipballURL() string {
 	return *r.ZipballURL
 }
 
+// GetAffectedPackageName returns the AffectedPackageName field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetAffectedPackageName() string {
+	if r == nil || r.AffectedPackageName == nil {
+		return ""
+	}
+	return *r.AffectedPackageName
+}
+
+// GetAffectedRange returns the AffectedRange field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetAffectedRange() string {
+	if r == nil || r.AffectedRange == nil {
+		return ""
+	}
+	return *r.AffectedRange
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDismissedAt returns the DismissedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetDismissedAt() Timestamp {
+	if r == nil || r.DismissedAt == nil {
+		return Timestamp{}
+	}
+	return *r.DismissedAt
+}
+
+// GetDismisser returns the Dismisser field.
+func (r *RepositoryVulnerabilityAlert) GetDismisser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Dismisser
+}
+
+// GetDismissReason returns the DismissReason field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetDismissReason() string {
+	if r == nil || r.DismissReason == nil {
+		return ""
+	}
+	return *r.DismissReason
+}
+
+// GetExternalIdentifier returns the ExternalIdentifier field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetExternalIdentifier() string {
+	if r == nil || r.ExternalIdentifier == nil {
+		return ""
+	}
+	return *r.ExternalIdentifier
+}
+
+// GetExternalReference returns the ExternalReference field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetExternalReference() string {
+	if r == nil || r.ExternalReference == nil {
+		return ""
+	}
+	return *r.ExternalReference
+}
+
+// GetFixedIn returns the FixedIn field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetFixedIn() string {
+	if r == nil || r.FixedIn == nil {
+		return ""
+	}
+	return *r.FixedIn
+}
+
+// GetGitHubSecurityAdvisoryID returns the GitHubSecurityAdvisoryID field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetGitHubSecurityAdvisoryID() string {
+	if r == nil || r.GitHubSecurityAdvisoryID == nil {
+		return ""
+	}
+	return *r.GitHubSecurityAdvisoryID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetSeverity returns the Severity field if it's non-nil, zero value otherwise.
+func (r *RepositoryVulnerabilityAlert) GetSeverity() string {
+	if r == nil || r.Severity == nil {
+		return ""
+	}
+	return *r.Severity
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (r *RepositoryVulnerabilityAlertEvent) GetAction() string {
 	if r == nil || r.Action == nil {
@@ -13460,6 +13820,14 @@ func (r *RepositoryVulnerabilityAlertEvent) GetAction() string {
 	return *r.Action
 }
 
+// GetAlert returns the Alert field.
+func (r *RepositoryVulnerabilityAlertEvent) GetAlert() *RepositoryVulnerabilityAlert {
+	if r == nil {
+		return nil
+	}
+	return r.Alert
+}
+
 // GetRepository returns the Repository field.
 func (r *RepositoryVulnerabilityAlertEvent) GetRepository() *Repository {
 	if r == nil {
@@ -14468,6 +14836,46 @@ func (t *TeamAddEvent) GetTeam() *Team {
 	return t.Team
 }
 
+// GetDescription returns the Description field.
+func (t *TeamChange) GetDescription() *TeamDescription {
+	if t == nil {
+		return nil
+	}
+	return t.Description
+}
+
+// GetName returns the Name field.
+func (t *TeamChange) GetName() *TeamName {
+	if t == nil {
+		return nil
+	}
+	return t.Name
+}
+
+// GetPrivacy returns the Privacy field.
+func (t *TeamChange) GetPrivacy() *TeamPrivacy {
+	if t == nil {
+		return nil
+	}
+	return t.Privacy
+}
+
+// GetRepository returns the Repository field.
+func (t *TeamChange) GetRepository() *TeamRepository {
+	if t == nil {
+		return nil
+	}
+	return t.Repository
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (t *TeamDescription) GetFrom() string {
+	if t == nil || t.From == nil {
+		return ""
+	}
+	return *t.From
+}
+
 // GetAuthor returns the Author field.
 func (t *TeamDiscussion) GetAuthor() *User {
 	if t == nil {
@@ -14748,6 +15156,54 @@ func (t *TeamLDAPMapping) GetURL() string {
 	return *t.URL
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (t *TeamName) GetFrom() string {
+	if t == nil || t.From == nil {
+		return ""
+	}
+	return *t.From
+}
+
+// GetFrom returns the From field.
+func (t *TeamPermissions) GetFrom() *TeamPermissionsFrom {
+	if t == nil {
+		return nil
+	}
+	return t.From
+}
+
+// GetAdmin returns the Admin field if it's non-nil, zero value otherwise.
+func (t *TeamPermissionsFrom) GetAdmin() bool {
+	if t == nil || t.Admin == nil {
+		return false
+	}
+	return *t.Admin
+}
+
+// GetPull returns the Pull field if it's non-nil, zero value otherwise.
+func (t *TeamPermissionsFrom) GetPull() bool {
+	if t == nil || t.Pull == nil {
+		return false
+	}
+	return *t.Pull
+}
+
+// GetPush returns the Push field if it's non-nil, zero value otherwise.
+func (t *TeamPermissionsFrom) GetPush() bool {
+	if t == nil || t.Push == nil {
+		return false
+	}
+	return *t.Push
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (t *TeamPrivacy) GetFrom() string {
+	if t == nil || t.From == nil {
+		return ""
+	}
+	return *t.From
+}
+
 // GetPermission returns the Permission field if it's non-nil, zero value otherwise.
 func (t *TeamProjectOptions) GetPermission() string {
 	if t == nil || t.Permission == nil {
@@ -14756,6 +15212,14 @@ func (t *TeamProjectOptions) GetPermission() string {
 	return *t.Permission
 }
 
+// GetPermissions returns the Permissions field.
+func (t *TeamRepository) GetPermissions() *TeamPermissions {
+	if t == nil {
+		return nil
+	}
+	return t.Permissions
+}
+
 // GetDescription returns the Description field if it's non-nil, zero value otherwise.
 func (t *TemplateRepoRequest) GetDescription() string {
 	if t == nil || t.Description == nil {
@@ -14924,6 +15388,14 @@ func (t *Timeline) GetSource() *Source {
 	return t.Source
 }
 
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetState() string {
+	if t == nil || t.State == nil {
+		return ""
+	}
+	return *t.State
+}
+
 // GetURL returns the URL field if it's non-nil, zero value otherwise.
 func (t *Timeline) GetURL() string {
 	if t == nil || t.URL == nil {
@@ -14932,6 +15404,30 @@ func (t *Timeline) GetURL() string {
 	return *t.URL
 }
 
+// GetGUID returns the GUID field if it's non-nil, zero value otherwise.
+func (t *Tool) GetGUID() string {
+	if t == nil || t.GUID == nil {
+		return ""
+	}
+	return *t.GUID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *Tool) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetVersion returns the Version field if it's non-nil, zero value otherwise.
+func (t *Tool) GetVersion() string {
+	if t == nil || t.Version == nil {
+		return ""
+	}
+	return *t.Version
+}
+
 // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
 func (t *TopicResult) GetCreatedAt() Timestamp {
 	if t == nil || t.CreatedAt == nil {
diff --git a/github/github.go b/github/github.go
index efde8f8d..264e27f4 100644
--- a/github/github.go
+++ b/github/github.go
@@ -522,6 +522,12 @@ func parseRate(r *http.Response) Rate {
 	return rate
 }
 
+type requestContext uint8
+
+const (
+	bypassRateLimitCheck requestContext = iota
+)
+
 // BareDo sends an API request and lets you handle the api response. If an error
 // or API Error occurs, the error will contain more information. Otherwise you
 // are supposed to read and close the response's Body. If rate limit is exceeded
@@ -538,12 +544,14 @@ func (c *Client) BareDo(ctx context.Context, req *http.Request) (*Response, erro
 
 	rateLimitCategory := category(req.URL.Path)
 
-	// If we've hit rate limit, don't make further requests before Reset time.
-	if err := c.checkRateLimitBeforeDo(req, rateLimitCategory); err != nil {
-		return &Response{
-			Response: err.Response,
-			Rate:     err.Rate,
-		}, err
+	if bypass := ctx.Value(bypassRateLimitCheck); bypass == nil {
+		// If we've hit rate limit, don't make further requests before Reset time.
+		if err := c.checkRateLimitBeforeDo(req, rateLimitCategory); err != nil {
+			return &Response{
+				Response: err.Response,
+				Rate:     err.Rate,
+			}, err
+		}
 	}
 
 	resp, err := c.client.Do(req)
@@ -679,18 +687,21 @@ type ErrorResponse struct {
 	Message  string         `json:"message"` // error message
 	Errors   []Error        `json:"errors"`  // more detail on individual errors
 	// Block is only populated on certain types of errors such as code 451.
-	// See https://developer.github.com/changes/2016-03-17-the-451-status-code-is-now-supported/
-	// for more information.
-	Block *struct {
-		Reason    string     `json:"reason,omitempty"`
-		CreatedAt *Timestamp `json:"created_at,omitempty"`
-	} `json:"block,omitempty"`
+	Block *ErrorBlock `json:"block,omitempty"`
 	// Most errors will also include a documentation_url field pointing
 	// to some content that might help you resolve the error, see
 	// https://docs.github.com/en/free-pro-team@latest/rest/reference/#client-errors
 	DocumentationURL string `json:"documentation_url,omitempty"`
 }
 
+// ErrorBlock contains a further explanation for the reason of an error.
+// See https://developer.github.com/changes/2016-03-17-the-451-status-code-is-now-supported/
+// for more information.
+type ErrorBlock struct {
+	Reason    string     `json:"reason,omitempty"`
+	CreatedAt *Timestamp `json:"created_at,omitempty"`
+}
+
 func (r *ErrorResponse) Error() string {
 	return fmt.Sprintf("%v %v: %d %v %+v",
 		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
@@ -1022,6 +1033,9 @@ func (c *Client) RateLimits(ctx context.Context) (*RateLimits, *Response, error)
 	response := new(struct {
 		Resources *RateLimits `json:"resources"`
 	})
+
+	// This resource is not subject to rate limits.
+	ctx = context.WithValue(ctx, bypassRateLimitCheck, true)
 	resp, err := c.Do(ctx, req, response)
 	if err != nil {
 		return nil, resp, err
diff --git a/github/issues_timeline.go b/github/issues_timeline.go
index 2033a723..1fd13b12 100644
--- a/github/issues_timeline.go
+++ b/github/issues_timeline.go
@@ -81,6 +81,9 @@ type Timeline struct {
 	//     reopened
 	//       The issue was reopened by the actor.
 	//
+	//     reviewed
+	//       The pull request was reviewed.
+	//
 	//     subscribed
 	//       The actor subscribed to receive notifications for an issue.
 	//
@@ -118,6 +121,10 @@ type Timeline struct {
 	// Only provided for 'renamed' events.
 	Rename      *Rename      `json:"rename,omitempty"`
 	ProjectCard *ProjectCard `json:"project_card,omitempty"`
+	// The state of a submitted review. Can be one of: 'commented',
+	// 'changes_requested' or 'approved'.
+	// Only provided for 'reviewed' events.
+	State *string `json:"state,omitempty"`
 }
 
 // Source represents a reference's source.
diff --git a/github/messages.go b/github/messages.go
index 98a76da6..06ea9e4c 100644
--- a/github/messages.go
+++ b/github/messages.go
@@ -19,6 +19,7 @@ import (
 	"fmt"
 	"hash"
 	"io/ioutil"
+	"mime"
 	"net/http"
 	"net/url"
 	"strings"
@@ -157,7 +158,14 @@ func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
 func ValidatePayload(r *http.Request, secretToken []byte) (payload []byte, err error) {
 	var body []byte // Raw body that GitHub uses to calculate the signature.
 
-	switch ct := r.Header.Get("Content-Type"); ct {
+	ct := r.Header.Get("Content-Type")
+
+	mediatype, _, err := mime.ParseMediaType(ct)
+	if err != nil {
+		mediatype = ""
+	}
+
+	switch mediatype {
 	case "application/json":
 		var err error
 		if body, err = ioutil.ReadAll(r.Body); err != nil {
diff --git a/github/pulls.go b/github/pulls.go
index 0b48c232..6c866ea8 100644
--- a/github/pulls.go
+++ b/github/pulls.go
@@ -18,50 +18,59 @@ import (
 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/pulls/
 type PullRequestsService service
 
+// PullRequestAutoMerge represents the "auto_merge" response for a PullRequest.
+type PullRequestAutoMerge struct {
+	EnabledBy     *User   `json:"enabled_by,omitempty"`
+	MergeMethod   *string `json:"merge_method,omitempty"`
+	CommitTitle   *string `json:"commit_title,omitempty"`
+	CommitMessage *string `json:"commit_message,omitempty"`
+}
+
 // PullRequest represents a GitHub pull request on a repository.
 type PullRequest struct {
-	ID                  *int64     `json:"id,omitempty"`
-	Number              *int       `json:"number,omitempty"`
-	State               *string    `json:"state,omitempty"`
-	Locked              *bool      `json:"locked,omitempty"`
-	Title               *string    `json:"title,omitempty"`
-	Body                *string    `json:"body,omitempty"`
-	CreatedAt           *time.Time `json:"created_at,omitempty"`
-	UpdatedAt           *time.Time `json:"updated_at,omitempty"`
-	ClosedAt            *time.Time `json:"closed_at,omitempty"`
-	MergedAt            *time.Time `json:"merged_at,omitempty"`
-	Labels              []*Label   `json:"labels,omitempty"`
-	User                *User      `json:"user,omitempty"`
-	Draft               *bool      `json:"draft,omitempty"`
-	Merged              *bool      `json:"merged,omitempty"`
-	Mergeable           *bool      `json:"mergeable,omitempty"`
-	MergeableState      *string    `json:"mergeable_state,omitempty"`
-	MergedBy            *User      `json:"merged_by,omitempty"`
-	MergeCommitSHA      *string    `json:"merge_commit_sha,omitempty"`
-	Rebaseable          *bool      `json:"rebaseable,omitempty"`
-	Comments            *int       `json:"comments,omitempty"`
-	Commits             *int       `json:"commits,omitempty"`
-	Additions           *int       `json:"additions,omitempty"`
-	Deletions           *int       `json:"deletions,omitempty"`
-	ChangedFiles        *int       `json:"changed_files,omitempty"`
-	URL                 *string    `json:"url,omitempty"`
-	HTMLURL             *string    `json:"html_url,omitempty"`
-	IssueURL            *string    `json:"issue_url,omitempty"`
-	StatusesURL         *string    `json:"statuses_url,omitempty"`
-	DiffURL             *string    `json:"diff_url,omitempty"`
-	PatchURL            *string    `json:"patch_url,omitempty"`
-	CommitsURL          *string    `json:"commits_url,omitempty"`
-	CommentsURL         *string    `json:"comments_url,omitempty"`
-	ReviewCommentsURL   *string    `json:"review_comments_url,omitempty"`
-	ReviewCommentURL    *string    `json:"review_comment_url,omitempty"`
-	ReviewComments      *int       `json:"review_comments,omitempty"`
-	Assignee            *User      `json:"assignee,omitempty"`
-	Assignees           []*User    `json:"assignees,omitempty"`
-	Milestone           *Milestone `json:"milestone,omitempty"`
-	MaintainerCanModify *bool      `json:"maintainer_can_modify,omitempty"`
-	AuthorAssociation   *string    `json:"author_association,omitempty"`
-	NodeID              *string    `json:"node_id,omitempty"`
-	RequestedReviewers  []*User    `json:"requested_reviewers,omitempty"`
+	ID                  *int64                `json:"id,omitempty"`
+	Number              *int                  `json:"number,omitempty"`
+	State               *string               `json:"state,omitempty"`
+	Locked              *bool                 `json:"locked,omitempty"`
+	Title               *string               `json:"title,omitempty"`
+	Body                *string               `json:"body,omitempty"`
+	CreatedAt           *time.Time            `json:"created_at,omitempty"`
+	UpdatedAt           *time.Time            `json:"updated_at,omitempty"`
+	ClosedAt            *time.Time            `json:"closed_at,omitempty"`
+	MergedAt            *time.Time            `json:"merged_at,omitempty"`
+	Labels              []*Label              `json:"labels,omitempty"`
+	User                *User                 `json:"user,omitempty"`
+	Draft               *bool                 `json:"draft,omitempty"`
+	Merged              *bool                 `json:"merged,omitempty"`
+	Mergeable           *bool                 `json:"mergeable,omitempty"`
+	MergeableState      *string               `json:"mergeable_state,omitempty"`
+	MergedBy            *User                 `json:"merged_by,omitempty"`
+	MergeCommitSHA      *string               `json:"merge_commit_sha,omitempty"`
+	Rebaseable          *bool                 `json:"rebaseable,omitempty"`
+	Comments            *int                  `json:"comments,omitempty"`
+	Commits             *int                  `json:"commits,omitempty"`
+	Additions           *int                  `json:"additions,omitempty"`
+	Deletions           *int                  `json:"deletions,omitempty"`
+	ChangedFiles        *int                  `json:"changed_files,omitempty"`
+	URL                 *string               `json:"url,omitempty"`
+	HTMLURL             *string               `json:"html_url,omitempty"`
+	IssueURL            *string               `json:"issue_url,omitempty"`
+	StatusesURL         *string               `json:"statuses_url,omitempty"`
+	DiffURL             *string               `json:"diff_url,omitempty"`
+	PatchURL            *string               `json:"patch_url,omitempty"`
+	CommitsURL          *string               `json:"commits_url,omitempty"`
+	CommentsURL         *string               `json:"comments_url,omitempty"`
+	ReviewCommentsURL   *string               `json:"review_comments_url,omitempty"`
+	ReviewCommentURL    *string               `json:"review_comment_url,omitempty"`
+	ReviewComments      *int                  `json:"review_comments,omitempty"`
+	Assignee            *User                 `json:"assignee,omitempty"`
+	Assignees           []*User               `json:"assignees,omitempty"`
+	Milestone           *Milestone            `json:"milestone,omitempty"`
+	MaintainerCanModify *bool                 `json:"maintainer_can_modify,omitempty"`
+	AuthorAssociation   *string               `json:"author_association,omitempty"`
+	NodeID              *string               `json:"node_id,omitempty"`
+	RequestedReviewers  []*User               `json:"requested_reviewers,omitempty"`
+	AutoMerge           *PullRequestAutoMerge `json:"auto_merge,omitempty"`
 
 	// RequestedTeams is populated as part of the PullRequestEvent.
 	// See, https://docs.github.com/en/developers/webhooks-and-events/github-event-types#pullrequestevent for an example.
diff --git a/github/repos.go b/github/repos.go
index 8f34cf8b..300495f2 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"net/http"
 	"strings"
 )
 
@@ -44,9 +45,11 @@ type Repository struct {
 	ForksCount          *int            `json:"forks_count,omitempty"`
 	NetworkCount        *int            `json:"network_count,omitempty"`
 	OpenIssuesCount     *int            `json:"open_issues_count,omitempty"`
+	OpenIssues          *int            `json:"open_issues,omitempty"` // Deprecated: Replaced by OpenIssuesCount. For backward compatibility OpenIssues is still populated.
 	StargazersCount     *int            `json:"stargazers_count,omitempty"`
 	SubscribersCount    *int            `json:"subscribers_count,omitempty"`
-	WatchersCount       *int            `json:"watchers_count,omitempty"`
+	WatchersCount       *int            `json:"watchers_count,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility WatchersCount is still populated.
+	Watchers            *int            `json:"watchers,omitempty"`       // Deprecated: Replaced by StargazersCount. For backward compatibility Watchers is still populated.
 	Size                *int            `json:"size,omitempty"`
 	AutoInit            *bool           `json:"auto_init,omitempty"`
 	Parent              *Repository     `json:"parent,omitempty"`
@@ -933,20 +936,49 @@ func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, re
 // GetBranch gets the specified branch for a repository.
 //
 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-a-branch
-func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) {
+func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string, followRedirects bool) (*Branch, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch)
-	req, err := s.client.NewRequest("GET", u, nil)
+
+	resp, err := s.getBranchFromURL(ctx, u, followRedirects)
 	if err != nil {
 		return nil, nil, err
 	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
+	}
 
 	b := new(Branch)
-	resp, err := s.client.Do(ctx, req, b)
+	err = json.NewDecoder(resp.Body).Decode(b)
+	return b, newResponse(resp), err
+}
+
+func (s *RepositoriesService) getBranchFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
+	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
-		return nil, resp, err
+		return nil, err
+	}
+
+	var resp *http.Response
+	// Use http.DefaultTransport if no custom Transport is configured
+	req = withContext(ctx, req)
+	if s.client.client.Transport == nil {
+		resp, err = http.DefaultTransport.RoundTrip(req)
+	} else {
+		resp, err = s.client.client.Transport.RoundTrip(req)
+	}
+	if err != nil {
+		return nil, err
 	}
 
-	return b, resp, nil
+	// If redirect response is returned, follow it
+	if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
+		resp.Body.Close()
+		u = resp.Header.Get("Location")
+		resp, err = s.getBranchFromURL(ctx, u, false)
+	}
+	return resp, err
 }
 
 // GetBranchProtection gets the protection of a given branch.
diff --git a/update-urls/main.go b/update-urls/main.go
index d0d4955a..a82ffbd9 100644
--- a/update-urls/main.go
+++ b/update-urls/main.go
@@ -655,12 +655,12 @@ func (e *Endpoint) String() string {
 	return b.String()
 }
 
-func (ep *Endpoint) checkHttpMethodOverride(path string) {
-	lookupOverride := fmt.Sprintf("%v.%v: %v %v", ep.serviceName, ep.endpointName, ep.httpMethod, path)
+func (e *Endpoint) checkHttpMethodOverride(path string) {
+	lookupOverride := fmt.Sprintf("%v.%v: %v %v", e.serviceName, e.endpointName, e.httpMethod, path)
 	logf("Looking up override for %q", lookupOverride)
 	if v, ok := methodOverrides[lookupOverride]; ok {
 		logf("overriding method for %v to %q", lookupOverride, v)
-		ep.httpMethod = v
+		e.httpMethod = v
 		return
 	}
 }


Test patch:
diff --git a/github/actions_artifacts_test.go b/github/actions_artifacts_test.go
index 7344d4cf..e526e059 100644
--- a/github/actions_artifacts_test.go
+++ b/github/actions_artifacts_test.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -294,6 +295,15 @@ func TestActionsSerivice_DownloadArtifact(t *testing.T) {
 		_, _, err = client.Actions.DownloadArtifact(ctx, "\n", "\n", -1, true)
 		return err
 	})
+
+	// Add custom round tripper
+	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
+		return nil, errors.New("failed to download artifact")
+	})
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.DownloadArtifact(ctx, "o", "r", 1, true)
+		return err
+	})
 }
 
 func TestActionsService_DownloadArtifact_invalidOwner(t *testing.T) {
@@ -419,3 +429,67 @@ func TestActionsService_DeleteArtifact_notFound(t *testing.T) {
 		t.Errorf("Actions.DeleteArtifact return status %d, want %d", got, want)
 	}
 }
+
+func TestArtifact_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Artifact{}, "{}")
+
+	u := &Artifact{
+		ID:                 Int64(1),
+		NodeID:             String("nid"),
+		Name:               String("n"),
+		SizeInBytes:        Int64(1),
+		ArchiveDownloadURL: String("a"),
+		Expired:            Bool(false),
+		CreatedAt:          &Timestamp{referenceTime},
+		ExpiresAt:          &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "nid",
+		"name": "n",
+		"size_in_bytes": 1,
+		"archive_download_url": "a",
+		"expired": false,
+		"created_at": ` + referenceTimeStr + `,
+		"expires_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestArtifactList_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ArtifactList{}, "{}")
+
+	u := &ArtifactList{
+		TotalCount: Int64(1),
+		Artifacts: []*Artifact{
+			{
+				ID:                 Int64(1),
+				NodeID:             String("nid"),
+				Name:               String("n"),
+				SizeInBytes:        Int64(1),
+				ArchiveDownloadURL: String("a"),
+				Expired:            Bool(false),
+				CreatedAt:          &Timestamp{referenceTime},
+				ExpiresAt:          &Timestamp{referenceTime},
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"artifacts": [{
+			"id": 1,
+			"node_id": "nid",
+			"name": "n",
+			"size_in_bytes": 1,
+			"archive_download_url": "a",
+			"expired": false,
+			"created_at": ` + referenceTimeStr + `,
+			"expires_at": ` + referenceTimeStr + `
+		}]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/actions_runner_groups_test.go b/github/actions_runner_groups_test.go
index ca24ae93..27489ad9 100644
--- a/github/actions_runner_groups_test.go
+++ b/github/actions_runner_groups_test.go
@@ -472,3 +472,131 @@ func TestActionsService_RemoveRunnerGroupRunners(t *testing.T) {
 		return client.Actions.RemoveRunnerGroupRunners(ctx, "o", 2, 42)
 	})
 }
+
+func TestRunnerGroup_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RunnerGroup{}, "{}")
+
+	u := &RunnerGroup{
+		ID:                       Int64(1),
+		Name:                     String("n"),
+		Visibility:               String("v"),
+		Default:                  Bool(true),
+		SelectedRepositoriesURL:  String("s"),
+		RunnersURL:               String("r"),
+		Inherited:                Bool(true),
+		AllowsPublicRepositories: Bool(true),
+	}
+
+	want := `{
+		"id": 1,
+		"name": "n",
+		"visibility": "v",
+		"default": true,
+		"selected_repositories_url": "s",
+		"runners_url": "r",
+		"inherited": true,
+		"allows_public_repositories": true
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRunnerGroups_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RunnerGroups{}, "{}")
+
+	u := &RunnerGroups{
+		TotalCount: int(1),
+		RunnerGroups: []*RunnerGroup{
+			{
+				ID:                       Int64(1),
+				Name:                     String("n"),
+				Visibility:               String("v"),
+				Default:                  Bool(true),
+				SelectedRepositoriesURL:  String("s"),
+				RunnersURL:               String("r"),
+				Inherited:                Bool(true),
+				AllowsPublicRepositories: Bool(true),
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"runner_groups": [{
+			"id": 1,
+			"name": "n",
+			"visibility": "v",
+			"default": true,
+			"selected_repositories_url": "s",
+			"runners_url": "r",
+			"inherited": true,
+			"allows_public_repositories": true
+		}]		
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestCreateRunnerGroupRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &CreateRunnerGroupRequest{}, "{}")
+
+	u := &CreateRunnerGroupRequest{
+		Name:                  String("n"),
+		Visibility:            String("v"),
+		SelectedRepositoryIDs: []int64{1},
+		Runners:               []int64{1},
+	}
+
+	want := `{
+		"name": "n",
+		"visibility": "v",
+		"selected_repository_ids": [1],
+		"runners": [1]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestUpdateRunnerGroupRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UpdateRunnerGroupRequest{}, "{}")
+
+	u := &UpdateRunnerGroupRequest{
+		Name:       String("n"),
+		Visibility: String("v"),
+	}
+
+	want := `{
+		"name": "n",
+		"visibility": "v"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestSetRepoAccessRunnerGroupRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SetRepoAccessRunnerGroupRequest{}, "{}")
+
+	u := &SetRepoAccessRunnerGroupRequest{
+		SelectedRepositoryIDs: []int64{1},
+	}
+
+	want := `{
+		"selected_repository_ids": [1]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestSetRunnerGroupRunnersRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SetRunnerGroupRunnersRequest{}, "{}")
+
+	u := &SetRunnerGroupRunnersRequest{
+		Runners: []int64{1},
+	}
+
+	want := `{
+		"runners": [1]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/actions_runners_test.go b/github/actions_runners_test.go
index a3e3b28e..a997f627 100644
--- a/github/actions_runners_test.go
+++ b/github/actions_runners_test.go
@@ -500,3 +500,187 @@ func TestActionsService_RemoveOrganizationRunner(t *testing.T) {
 		return client.Actions.RemoveOrganizationRunner(ctx, "o", 21)
 	})
 }
+
+func TestRunnerApplicationDownload_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RunnerApplicationDownload{}, "{}")
+
+	u := &RunnerApplicationDownload{
+		OS:                String("o"),
+		Architecture:      String("a"),
+		DownloadURL:       String("d"),
+		Filename:          String("f"),
+		TempDownloadToken: String("t"),
+		SHA256Checksum:    String("s"),
+	}
+
+	want := `{
+		"os": "o",
+		"architecture": "a",
+		"download_url": "d",
+		"filename": "f",
+		"temp_download_token": "t",
+		"sha256_checksum": "s"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestActionsEnabledOnOrgRepos_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ActionsEnabledOnOrgRepos{}, "{}")
+
+	u := &ActionsEnabledOnOrgRepos{
+		TotalCount: 1,
+		Repositories: []*Repository{
+			{
+				ID:   Int64(1),
+				URL:  String("u"),
+				Name: String("n"),
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"repositories": [
+			{
+				"id": 1,
+				"url": "u",
+				"name": "n"
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRegistrationToken_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RegistrationToken{}, "{}")
+
+	u := &RegistrationToken{
+		Token:     String("t"),
+		ExpiresAt: &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"token": "t",
+		"expires_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRunnerLabels_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RunnerLabels{}, "{}")
+
+	u := &RunnerLabels{
+		ID:   Int64(1),
+		Name: String("n"),
+		Type: String("t"),
+	}
+
+	want := `{
+		"id": 1,
+		"name": "n",
+		"type": "t"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRunner_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Runner{}, "{}")
+
+	u := &Runner{
+		ID:     Int64(1),
+		Name:   String("n"),
+		OS:     String("o"),
+		Status: String("s"),
+		Busy:   Bool(false),
+		Labels: []*RunnerLabels{
+			{
+				ID:   Int64(1),
+				Name: String("n"),
+				Type: String("t"),
+			},
+		},
+	}
+
+	want := `{
+		"id": 1,
+		"name": "n",
+		"os": "o",
+		"status": "s",
+		"busy": false,
+		"labels": [
+			{
+				"id": 1,
+				"name": "n",
+				"type": "t"
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRunners_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Runners{}, "{}")
+
+	u := &Runners{
+		TotalCount: 1,
+		Runners: []*Runner{
+			{
+				ID:     Int64(1),
+				Name:   String("n"),
+				OS:     String("o"),
+				Status: String("s"),
+				Busy:   Bool(false),
+				Labels: []*RunnerLabels{
+					{
+						ID:   Int64(1),
+						Name: String("n"),
+						Type: String("t"),
+					},
+				},
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"runners": [
+			{
+				"id": 1,
+		"name": "n",
+		"os": "o",
+		"status": "s",
+		"busy": false,
+		"labels": [
+			{
+				"id": 1,
+				"name": "n",
+				"type": "t"
+			}
+		]
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRemoveToken_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RemoveToken{}, "{}")
+
+	u := &RemoveToken{
+		Token:     String("t"),
+		ExpiresAt: &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"token": "t",
+		"expires_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/actions_workflow_jobs_test.go b/github/actions_workflow_jobs_test.go
index 4062cc5b..49315a03 100644
--- a/github/actions_workflow_jobs_test.go
+++ b/github/actions_workflow_jobs_test.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -154,6 +155,15 @@ func TestActionsService_GetWorkflowJobLogs(t *testing.T) {
 		_, _, err = client.Actions.GetWorkflowJobLogs(ctx, "\n", "\n", 399444496, true)
 		return err
 	})
+
+	// Add custom round tripper
+	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
+		return nil, errors.New("failed to get workflow logs")
+	})
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, true)
+		return err
+	})
 }
 
 func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
diff --git a/github/actions_workflow_runs_test.go b/github/actions_workflow_runs_test.go
index b01c594c..14274d53 100644
--- a/github/actions_workflow_runs_test.go
+++ b/github/actions_workflow_runs_test.go
@@ -412,3 +412,431 @@ func TestActionsService_GetWorkflowRunUsageByID(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestWorkflowRun_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowRun{}, "{}")
+
+	u := &WorkflowRun{
+		ID:         Int64(1),
+		Name:       String("n"),
+		NodeID:     String("nid"),
+		HeadBranch: String("hb"),
+		HeadSHA:    String("hs"),
+		RunNumber:  Int(1),
+		Event:      String("e"),
+		Status:     String("s"),
+		Conclusion: String("c"),
+		WorkflowID: Int64(1),
+		URL:        String("u"),
+		HTMLURL:    String("h"),
+		PullRequests: []*PullRequest{
+			{
+				URL:    String("u"),
+				ID:     Int64(1),
+				Number: Int(1),
+				Head: &PullRequestBranch{
+					Ref: String("r"),
+					SHA: String("s"),
+					Repo: &Repository{
+						ID:   Int64(1),
+						URL:  String("s"),
+						Name: String("n"),
+					},
+				},
+				Base: &PullRequestBranch{
+					Ref: String("r"),
+					SHA: String("s"),
+					Repo: &Repository{
+						ID:   Int64(1),
+						URL:  String("u"),
+						Name: String("n"),
+					},
+				},
+			},
+		},
+		CreatedAt:     &Timestamp{referenceTime},
+		UpdatedAt:     &Timestamp{referenceTime},
+		JobsURL:       String("j"),
+		LogsURL:       String("l"),
+		CheckSuiteURL: String("c"),
+		ArtifactsURL:  String("a"),
+		CancelURL:     String("c"),
+		RerunURL:      String("r"),
+		HeadCommit: &HeadCommit{
+			Message: String("m"),
+			Author: &CommitAuthor{
+				Name:  String("n"),
+				Email: String("e"),
+				Login: String("l"),
+			},
+			URL:       String("u"),
+			Distinct:  Bool(false),
+			SHA:       String("s"),
+			ID:        String("i"),
+			TreeID:    String("tid"),
+			Timestamp: &Timestamp{referenceTime},
+			Committer: &CommitAuthor{
+				Name:  String("n"),
+				Email: String("e"),
+				Login: String("l"),
+			},
+		},
+		WorkflowURL: String("w"),
+		Repository: &Repository{
+			ID:   Int64(1),
+			URL:  String("u"),
+			Name: String("n"),
+		},
+		HeadRepository: &Repository{
+			ID:   Int64(1),
+			URL:  String("u"),
+			Name: String("n"),
+		},
+	}
+
+	want := `{
+		"id": 1,
+		"name": "n",
+		"node_id": "nid",
+		"head_branch": "hb",
+		"head_sha": "hs",
+		"run_number": 1,
+		"event": "e",
+		"status": "s",
+		"conclusion": "c",
+		"workflow_id": 1,
+		"url": "u",
+		"html_url": "h",
+		"pull_requests": [
+			{
+				"id":1,
+				"number":1,
+				"url":"u",
+				"head":{
+					"ref":"r",
+					"sha":"s",
+					"repo": {
+						"id":1,
+						"name":"n",
+						"url":"s"
+						}
+					},
+					"base": {
+						"ref":"r",
+						"sha":"s",
+						"repo": {
+							"id":1,
+							"name":"n",
+							"url":"u"
+						}
+					}
+			}
+		],
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"jobs_url": "j",
+		"logs_url": "l",
+		"check_suite_url": "c",
+		"artifacts_url": "a",
+		"cancel_url": "c",
+		"rerun_url": "r",
+		"head_commit": {
+			"message": "m",
+			"author": {
+				"name": "n",
+				"email": "e",
+				"username": "l"
+			},
+			"url": "u",
+			"distinct": false,
+			"sha": "s",
+			"id": "i",
+			"tree_id": "tid",
+			"timestamp": ` + referenceTimeStr + `,
+			"committer": {
+				"name": "n",
+				"email": "e",
+				"username": "l"
+			}
+		},
+		"workflow_url": "w",
+		"repository": {
+			"id": 1,
+			"url": "u",
+			"name": "n"
+		},
+		"head_repository": {
+			"id": 1,
+			"url": "u",
+			"name": "n"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowRuns_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowRuns{}, "{}")
+
+	u := &WorkflowRuns{
+		TotalCount: Int(1),
+		WorkflowRuns: []*WorkflowRun{
+			{
+				ID:         Int64(1),
+				Name:       String("n"),
+				NodeID:     String("nid"),
+				HeadBranch: String("hb"),
+				HeadSHA:    String("hs"),
+				RunNumber:  Int(1),
+				Event:      String("e"),
+				Status:     String("s"),
+				Conclusion: String("c"),
+				WorkflowID: Int64(1),
+				URL:        String("u"),
+				HTMLURL:    String("h"),
+				PullRequests: []*PullRequest{
+					{
+						URL:    String("u"),
+						ID:     Int64(1),
+						Number: Int(1),
+						Head: &PullRequestBranch{
+							Ref: String("r"),
+							SHA: String("s"),
+							Repo: &Repository{
+								ID:   Int64(1),
+								URL:  String("s"),
+								Name: String("n"),
+							},
+						},
+						Base: &PullRequestBranch{
+							Ref: String("r"),
+							SHA: String("s"),
+							Repo: &Repository{
+								ID:   Int64(1),
+								URL:  String("u"),
+								Name: String("n"),
+							},
+						},
+					},
+				},
+				CreatedAt:     &Timestamp{referenceTime},
+				UpdatedAt:     &Timestamp{referenceTime},
+				JobsURL:       String("j"),
+				LogsURL:       String("l"),
+				CheckSuiteURL: String("c"),
+				ArtifactsURL:  String("a"),
+				CancelURL:     String("c"),
+				RerunURL:      String("r"),
+				HeadCommit: &HeadCommit{
+					Message: String("m"),
+					Author: &CommitAuthor{
+						Name:  String("n"),
+						Email: String("e"),
+						Login: String("l"),
+					},
+					URL:       String("u"),
+					Distinct:  Bool(false),
+					SHA:       String("s"),
+					ID:        String("i"),
+					TreeID:    String("tid"),
+					Timestamp: &Timestamp{referenceTime},
+					Committer: &CommitAuthor{
+						Name:  String("n"),
+						Email: String("e"),
+						Login: String("l"),
+					},
+				},
+				WorkflowURL: String("w"),
+				Repository: &Repository{
+					ID:   Int64(1),
+					URL:  String("u"),
+					Name: String("n"),
+				},
+				HeadRepository: &Repository{
+					ID:   Int64(1),
+					URL:  String("u"),
+					Name: String("n"),
+				},
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"workflow_runs": [
+			{
+				"id": 1,
+				"name": "n",
+				"node_id": "nid",
+				"head_branch": "hb",
+				"head_sha": "hs",
+				"run_number": 1,
+				"event": "e",
+				"status": "s",
+				"conclusion": "c",
+				"workflow_id": 1,
+				"url": "u",
+				"html_url": "h",
+				"pull_requests": [
+					{
+						"id":1,
+						"number":1,
+						"url":"u",
+						"head":{
+							"ref":"r",
+							"sha":"s",
+							"repo": {
+								"id":1,
+								"name":"n",
+								"url":"s"
+								}
+							},
+							"base": {
+								"ref":"r",
+								"sha":"s",
+								"repo": {
+									"id":1,
+									"name":"n",
+									"url":"u"
+								}
+							}
+					}
+				],
+				"created_at": ` + referenceTimeStr + `,
+				"updated_at": ` + referenceTimeStr + `,
+				"jobs_url": "j",
+				"logs_url": "l",
+				"check_suite_url": "c",
+				"artifacts_url": "a",
+				"cancel_url": "c",
+				"rerun_url": "r",
+				"head_commit": {
+					"message": "m",
+					"author": {
+						"name": "n",
+						"email": "e",
+						"username": "l"
+					},
+					"url": "u",
+					"distinct": false,
+					"sha": "s",
+					"id": "i",
+					"tree_id": "tid",
+					"timestamp": ` + referenceTimeStr + `,
+					"committer": {
+						"name": "n",
+						"email": "e",
+						"username": "l"
+					}
+				},
+				"workflow_url": "w",
+				"repository": {
+					"id": 1,
+					"url": "u",
+					"name": "n"
+				},
+				"head_repository": {
+					"id": 1,
+					"url": "u",
+					"name": "n"
+				}
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowRunBill_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowRunBill{}, "{}")
+
+	u := &WorkflowRunBill{
+		TotalMS: Int64(1),
+		Jobs:    Int(1),
+	}
+
+	want := `{
+		"total_ms": 1,
+		"jobs": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowRunEnvironment_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowRunEnvironment{}, "{}")
+
+	u := &WorkflowRunEnvironment{
+		Ubuntu: &WorkflowRunBill{
+			TotalMS: Int64(1),
+			Jobs:    Int(1),
+		},
+		MacOS: &WorkflowRunBill{
+			TotalMS: Int64(1),
+			Jobs:    Int(1),
+		},
+		Windows: &WorkflowRunBill{
+			TotalMS: Int64(1),
+			Jobs:    Int(1),
+		},
+	}
+
+	want := `{
+		"UBUNTU": {
+			"total_ms": 1,
+			"jobs": 1
+		},
+		"MACOS": {
+			"total_ms": 1,
+			"jobs": 1
+		},
+		"WINDOWS": {
+			"total_ms": 1,
+			"jobs": 1
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowRunUsage_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowRunUsage{}, "{}")
+
+	u := &WorkflowRunUsage{
+		Billable: &WorkflowRunEnvironment{
+			Ubuntu: &WorkflowRunBill{
+				TotalMS: Int64(1),
+				Jobs:    Int(1),
+			},
+			MacOS: &WorkflowRunBill{
+				TotalMS: Int64(1),
+				Jobs:    Int(1),
+			},
+			Windows: &WorkflowRunBill{
+				TotalMS: Int64(1),
+				Jobs:    Int(1),
+			},
+		},
+		RunDurationMS: Int64(1),
+	}
+
+	want := `{
+		"billable": {
+			"UBUNTU": {
+				"total_ms": 1,
+				"jobs": 1
+			},
+			"MACOS": {
+				"total_ms": 1,
+				"jobs": 1
+			},
+			"WINDOWS": {
+				"total_ms": 1,
+				"jobs": 1
+			}
+		},
+		"run_duration_ms": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go
index 45a161b6..60a9d91b 100644
--- a/github/actions_workflows_test.go
+++ b/github/actions_workflows_test.go
@@ -458,3 +458,174 @@ func TestActionsService_DisableWorkflowByFileName(t *testing.T) {
 		return client.Actions.DisableWorkflowByFileName(ctx, "o", "r", "main.yml")
 	})
 }
+
+func TestWorkflow_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Workflow{}, "{}")
+
+	u := &Workflow{
+		ID:        Int64(1),
+		NodeID:    String("nid"),
+		Name:      String("n"),
+		Path:      String("p"),
+		State:     String("s"),
+		CreatedAt: &Timestamp{referenceTime},
+		UpdatedAt: &Timestamp{referenceTime},
+		URL:       String("u"),
+		HTMLURL:   String("h"),
+		BadgeURL:  String("b"),
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "nid",
+		"name": "n",
+		"path": "p",
+		"state": "s",
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"url": "u",
+		"html_url": "h",
+		"badge_url": "b"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflows_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Workflows{}, "{}")
+
+	u := &Workflows{
+		TotalCount: Int(1),
+		Workflows: []*Workflow{
+			{
+				ID:        Int64(1),
+				NodeID:    String("nid"),
+				Name:      String("n"),
+				Path:      String("p"),
+				State:     String("s"),
+				CreatedAt: &Timestamp{referenceTime},
+				UpdatedAt: &Timestamp{referenceTime},
+				URL:       String("u"),
+				HTMLURL:   String("h"),
+				BadgeURL:  String("b"),
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"workflows": [{
+			"id": 1,
+			"node_id": "nid",
+			"name": "n",
+			"path": "p",
+			"state": "s",
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"url": "u",
+			"html_url": "h",
+			"badge_url": "b"
+		}]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowBill_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowBill{}, "{}")
+
+	u := &WorkflowBill{
+		TotalMS: Int64(1),
+	}
+
+	want := `{
+		"total_ms": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowEnvironment_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowEnvironment{}, "{}")
+
+	u := &WorkflowEnvironment{
+		Ubuntu: &WorkflowBill{
+			TotalMS: Int64(1),
+		},
+		MacOS: &WorkflowBill{
+			TotalMS: Int64(1),
+		},
+		Windows: &WorkflowBill{
+			TotalMS: Int64(1),
+		},
+	}
+
+	want := `{
+		"UBUNTU": {
+			"total_ms": 1
+		},
+		"MACOS": {
+			"total_ms": 1
+		},
+		"WINDOWS": {
+			"total_ms": 1
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestWorkflowUsage_Marshal(t *testing.T) {
+	testJSONMarshal(t, &WorkflowUsage{}, "{}")
+
+	u := &WorkflowUsage{
+		Billable: &WorkflowEnvironment{
+			Ubuntu: &WorkflowBill{
+				TotalMS: Int64(1),
+			},
+			MacOS: &WorkflowBill{
+				TotalMS: Int64(1),
+			},
+			Windows: &WorkflowBill{
+				TotalMS: Int64(1),
+			},
+		},
+	}
+
+	want := `{
+		"billable": {
+			"UBUNTU": {
+				"total_ms": 1
+			},
+			"MACOS": {
+				"total_ms": 1
+			},
+			"WINDOWS": {
+				"total_ms": 1
+			}
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestCreateWorkflowDispatchEventRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &CreateWorkflowDispatchEventRequest{}, "{}")
+
+	inputs := make(map[string]interface{}, 0)
+	inputs["key"] = "value"
+
+	u := &CreateWorkflowDispatchEventRequest{
+		Ref:    "r",
+		Inputs: inputs,
+	}
+
+	want := `{
+		"ref": "r",
+		"inputs": {
+			"key": "value"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/activity_notifications_test.go b/github/activity_notifications_test.go
index bce2136a..f46a12f4 100644
--- a/github/activity_notifications_test.go
+++ b/github/activity_notifications_test.go
@@ -312,3 +312,83 @@ func TestActivityService_DeleteThreadSubscription(t *testing.T) {
 		return client.Activity.DeleteThreadSubscription(ctx, "1")
 	})
 }
+
+func TestNotification_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Notification{}, "{}")
+
+	u := &Notification{
+		ID: String("id"),
+		Repository: &Repository{
+			ID:   Int64(1),
+			URL:  String("u"),
+			Name: String("n"),
+		},
+		Subject: &NotificationSubject{
+			Title:            String("t"),
+			URL:              String("u"),
+			LatestCommentURL: String("l"),
+			Type:             String("t"),
+		},
+		Reason:     String("r"),
+		Unread:     Bool(true),
+		UpdatedAt:  &referenceTime,
+		LastReadAt: &referenceTime,
+		URL:        String("u"),
+	}
+
+	want := `{
+		"id": "id",
+		"repository": {
+			"id": 1,
+			"url": "u",
+			"name": "n"
+		},
+		"subject": {
+			"title": "t",
+			"url": "u",
+			"latest_comment_url": "l",
+			"type": "t"
+		},
+		"reason": "r",
+		"unread": true,
+		"updated_at": ` + referenceTimeStr + `,
+		"last_read_at": ` + referenceTimeStr + `,
+		"url": "u"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestNotificationSubject_Marshal(t *testing.T) {
+	testJSONMarshal(t, &NotificationSubject{}, "{}")
+
+	u := &NotificationSubject{
+		Title:            String("t"),
+		URL:              String("u"),
+		LatestCommentURL: String("l"),
+		Type:             String("t"),
+	}
+
+	want := `{
+		"title": "t",
+		"url": "u",
+		"latest_comment_url": "l",
+		"type": "t"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestMarkReadOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &markReadOptions{}, "{}")
+
+	u := &markReadOptions{
+		LastReadAt: referenceTime,
+	}
+
+	want := `{
+		"last_read_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/activity_star_test.go b/github/activity_star_test.go
index 7e7a4a8e..122c3993 100644
--- a/github/activity_star_test.go
+++ b/github/activity_star_test.go
@@ -285,3 +285,81 @@ func TestActivityService_Unstar_invalidID(t *testing.T) {
 	_, err := client.Activity.Unstar(ctx, "%", "%")
 	testURLParseError(t, err)
 }
+
+func TestStarredRepository_Marshal(t *testing.T) {
+	testJSONMarshal(t, &StarredRepository{}, "{}")
+
+	u := &StarredRepository{
+		StarredAt: &Timestamp{referenceTime},
+		Repository: &Repository{
+			ID:   Int64(1),
+			URL:  String("u"),
+			Name: String("n"),
+		},
+	}
+
+	want := `{
+		"starred_at": ` + referenceTimeStr + `,
+		"repo": {
+			"id": 1,
+			"url": "u",
+			"name": "n"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestStargazer_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Stargazer{}, "{}")
+
+	u := &Stargazer{
+		StarredAt: &Timestamp{referenceTime},
+		User: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+	}
+
+	want := `{
+		"starred_at": ` + referenceTimeStr + `,
+		"user": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/activity_test.go b/github/activity_test.go
index c73f4795..3d774279 100644
--- a/github/activity_test.go
+++ b/github/activity_test.go
@@ -97,15 +97,7 @@ var wantFeeds = &Feeds{
 	CurrentUserOrganizationURLs: []string{
 		"https://github.com/organizations/github/defunkt.private.atom?token=abc123",
 	},
-	Links: &struct {
-		Timeline                 *FeedLink   `json:"timeline,omitempty"`
-		User                     *FeedLink   `json:"user,omitempty"`
-		CurrentUserPublic        *FeedLink   `json:"current_user_public,omitempty"`
-		CurrentUser              *FeedLink   `json:"current_user,omitempty"`
-		CurrentUserActor         *FeedLink   `json:"current_user_actor,omitempty"`
-		CurrentUserOrganization  *FeedLink   `json:"current_user_organization,omitempty"`
-		CurrentUserOrganizations []*FeedLink `json:"current_user_organizations,omitempty"`
-	}{
+	Links: &FeedLinks{
 		Timeline: &FeedLink{
 			HRef: String("https://github.com/timeline"),
 			Type: String("application/atom+xml"),
diff --git a/github/activity_watching_test.go b/github/activity_watching_test.go
index c41205f4..15b0f330 100644
--- a/github/activity_watching_test.go
+++ b/github/activity_watching_test.go
@@ -257,3 +257,29 @@ func TestActivityService_DeleteRepositorySubscription(t *testing.T) {
 		return client.Activity.DeleteRepositorySubscription(ctx, "o", "r")
 	})
 }
+
+func TestSubscription_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Subscription{}, "{}")
+
+	u := &Subscription{
+		Subscribed:    Bool(true),
+		Ignored:       Bool(false),
+		Reason:        String("r"),
+		CreatedAt:     &Timestamp{referenceTime},
+		URL:           String("u"),
+		RepositoryURL: String("ru"),
+		ThreadURL:     String("tu"),
+	}
+
+	want := `{
+		"subscribed": true,
+		"ignored": false,
+		"reason": "r",
+		"created_at": ` + referenceTimeStr + `,
+		"url": "u",
+		"repository_url": "ru",
+		"thread_url": "tu"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/admin_orgs_test.go b/github/admin_orgs_test.go
index 85d73fb1..0282425b 100644
--- a/github/admin_orgs_test.go
+++ b/github/admin_orgs_test.go
@@ -141,3 +141,49 @@ func TestAdminOrgs_RenameByName(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestCreateOrgRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &createOrgRequest{}, "{}")
+
+	u := &createOrgRequest{
+		Login: String("l"),
+		Admin: String("a"),
+	}
+
+	want := `{
+		"login": "l",
+		"admin": "a"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRenameOrgRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &renameOrgRequest{}, "{}")
+
+	u := &renameOrgRequest{
+		Login: String("l"),
+	}
+
+	want := `{
+		"login": "l"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRenameOrgResponse_Marshal(t *testing.T) {
+	testJSONMarshal(t, &renameOrgRequest{}, "{}")
+
+	u := &RenameOrgResponse{
+		Message: String("m"),
+		URL:     String("u"),
+	}
+
+	want := `{
+		"message": "m",
+		"url": "u"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/admin_stats_test.go b/github/admin_stats_test.go
index 0d20b74c..dab2bc21 100644
--- a/github/admin_stats_test.go
+++ b/github/admin_stats_test.go
@@ -209,3 +209,311 @@ var testAdminStats = &AdminStats{
 		TotalPullRequestComments: Int(30),
 	},
 }
+
+func TestIssueStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &IssueStats{}, "{}")
+
+	u := &IssueStats{
+		TotalIssues:  Int(1),
+		OpenIssues:   Int(1),
+		ClosedIssues: Int(1),
+	}
+
+	want := `{
+		"total_issues": 1,
+		"open_issues": 1,
+		"closed_issues": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestHookStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &HookStats{}, "{}")
+
+	u := &HookStats{
+		TotalHooks:    Int(1),
+		ActiveHooks:   Int(1),
+		InactiveHooks: Int(1),
+	}
+
+	want := `{
+		"total_hooks": 1,
+		"active_hooks": 1,
+		"inactive_hooks": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestMilestoneStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MilestoneStats{}, "{}")
+
+	u := &MilestoneStats{
+		TotalMilestones:  Int(1),
+		OpenMilestones:   Int(1),
+		ClosedMilestones: Int(1),
+	}
+
+	want := `{
+		"total_milestones": 1,
+		"open_milestones": 1,
+		"closed_milestones": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestOrgStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &OrgStats{}, "{}")
+
+	u := &OrgStats{
+		TotalOrgs:        Int(1),
+		DisabledOrgs:     Int(1),
+		TotalTeams:       Int(1),
+		TotalTeamMembers: Int(1),
+	}
+
+	want := `{
+		"total_orgs": 1,
+		"disabled_orgs": 1,
+		"total_teams": 1,
+		"total_team_members": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestCommentStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &CommentStats{}, "{}")
+
+	u := &CommentStats{
+		TotalCommitComments:      Int(1),
+		TotalGistComments:        Int(1),
+		TotalIssueComments:       Int(1),
+		TotalPullRequestComments: Int(1),
+	}
+
+	want := `{
+		"total_commit_comments": 1,
+		"total_gist_comments": 1,
+		"total_issue_comments": 1,
+		"total_pull_request_comments": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestPageStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &PageStats{}, "{}")
+
+	u := &PageStats{
+		TotalPages: Int(1),
+	}
+
+	want := `{
+		"total_pages": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestUserStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserStats{}, "{}")
+
+	u := &UserStats{
+		TotalUsers:     Int(1),
+		AdminUsers:     Int(1),
+		SuspendedUsers: Int(1),
+	}
+
+	want := `{
+		"total_users": 1,
+		"admin_users": 1,
+		"suspended_users": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestGistStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &GistStats{}, "{}")
+
+	u := &GistStats{
+		TotalGists:   Int(1),
+		PrivateGists: Int(1),
+		PublicGists:  Int(1),
+	}
+
+	want := `{
+		"total_gists": 1,
+		"private_gists": 1,
+		"public_gists": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestPullStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &PullStats{}, "{}")
+
+	u := &PullStats{
+		TotalPulls:      Int(1),
+		MergedPulls:     Int(1),
+		MergablePulls:   Int(1),
+		UnmergablePulls: Int(1),
+	}
+
+	want := `{
+		"total_pulls": 1,
+		"merged_pulls": 1,
+		"mergeable_pulls": 1,
+		"unmergeable_pulls": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRepoStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RepoStats{}, "{}")
+
+	u := &RepoStats{
+		TotalRepos:  Int(1),
+		RootRepos:   Int(1),
+		ForkRepos:   Int(1),
+		OrgRepos:    Int(1),
+		TotalPushes: Int(1),
+		TotalWikis:  Int(1),
+	}
+
+	want := `{
+		"total_repos": 1,
+		"root_repos": 1,
+		"fork_repos": 1,
+		"org_repos": 1,
+		"total_pushes": 1,
+		"total_wikis": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestAdminStats_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AdminStats{}, "{}")
+
+	u := &AdminStats{
+		Repos: &RepoStats{
+			TotalRepos:  Int(212),
+			RootRepos:   Int(194),
+			ForkRepos:   Int(18),
+			OrgRepos:    Int(51),
+			TotalPushes: Int(3082),
+			TotalWikis:  Int(15),
+		},
+		Hooks: &HookStats{
+			TotalHooks:    Int(27),
+			ActiveHooks:   Int(23),
+			InactiveHooks: Int(4),
+		},
+		Pages: &PageStats{
+			TotalPages: Int(36),
+		},
+		Orgs: &OrgStats{
+			TotalOrgs:        Int(33),
+			DisabledOrgs:     Int(0),
+			TotalTeams:       Int(60),
+			TotalTeamMembers: Int(314),
+		},
+		Users: &UserStats{
+			TotalUsers:     Int(254),
+			AdminUsers:     Int(45),
+			SuspendedUsers: Int(21),
+		},
+		Pulls: &PullStats{
+			TotalPulls:      Int(86),
+			MergedPulls:     Int(60),
+			MergablePulls:   Int(21),
+			UnmergablePulls: Int(3),
+		},
+		Issues: &IssueStats{
+			TotalIssues:  Int(179),
+			OpenIssues:   Int(83),
+			ClosedIssues: Int(96),
+		},
+		Milestones: &MilestoneStats{
+			TotalMilestones:  Int(7),
+			OpenMilestones:   Int(6),
+			ClosedMilestones: Int(1),
+		},
+		Gists: &GistStats{
+			TotalGists:   Int(178),
+			PrivateGists: Int(151),
+			PublicGists:  Int(25),
+		},
+		Comments: &CommentStats{
+			TotalCommitComments:      Int(6),
+			TotalGistComments:        Int(28),
+			TotalIssueComments:       Int(366),
+			TotalPullRequestComments: Int(30),
+		},
+	}
+
+	want := `{
+		"repos": {
+			"total_repos": 212,
+			"root_repos": 194,
+			"fork_repos": 18,
+			"org_repos": 51,
+			"total_pushes": 3082,
+			"total_wikis": 15
+		},
+		"hooks": {
+			"total_hooks": 27,
+			"active_hooks": 23,
+			"inactive_hooks": 4
+		},
+		"pages": {
+			"total_pages": 36
+		},
+		"orgs": {
+			"total_orgs": 33,
+			"disabled_orgs": 0,
+			"total_teams": 60,
+			"total_team_members": 314
+		},
+		"users": {
+			"total_users": 254,
+			"admin_users": 45,
+			"suspended_users": 21
+		},
+		"pulls": {
+			"total_pulls": 86,
+			"merged_pulls": 60,
+			"mergeable_pulls": 21,
+			"unmergeable_pulls": 3
+		},
+		"issues": {
+			"total_issues": 179,
+			"open_issues": 83,
+			"closed_issues": 96
+		},
+		"milestones": {
+			"total_milestones": 7,
+			"open_milestones": 6,
+			"closed_milestones": 1
+		},
+		"gists": {
+			"total_gists": 178,
+			"private_gists": 151,
+			"public_gists": 25
+		},
+		"comments": {
+			"total_commit_comments": 6,
+			"total_gist_comments": 28,
+			"total_issue_comments": 366,
+			"total_pull_request_comments": 30
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/admin_test.go b/github/admin_test.go
index 0e8deaea..207121c3 100644
--- a/github/admin_test.go
+++ b/github/admin_test.go
@@ -157,3 +157,113 @@ func TestAdminService_UserLDAPMapping_String(t *testing.T) {
 		t.Errorf("UserLDAPMapping.String = `%v`, want `%v`", got, want)
 	}
 }
+
+func TestTeamLDAPMapping_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TeamLDAPMapping{}, "{}")
+
+	u := &TeamLDAPMapping{
+		ID:              Int64(1),
+		LDAPDN:          String("ldapdn"),
+		URL:             String("u"),
+		Name:            String("n"),
+		Slug:            String("s"),
+		Description:     String("d"),
+		Privacy:         String("p"),
+		Permission:      String("per"),
+		MembersURL:      String("mu"),
+		RepositoriesURL: String("ru"),
+	}
+
+	want := `{
+		"id": 1,
+		"ldap_dn": "ldapdn",
+		"url": "u",
+		"name": "n",
+		"slug": "s",
+		"description": "d",
+		"privacy": "p",
+		"permission": "per",
+		"members_url": "mu",
+		"repositories_url": "ru"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestUserLDAPMapping_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserLDAPMapping{}, "{}")
+
+	u := &UserLDAPMapping{
+		ID:                Int64(1),
+		LDAPDN:            String("ldapdn"),
+		Login:             String("l"),
+		AvatarURL:         String("au"),
+		GravatarID:        String("gi"),
+		Type:              String("t"),
+		SiteAdmin:         Bool(true),
+		URL:               String("u"),
+		EventsURL:         String("eu"),
+		FollowingURL:      String("fu"),
+		FollowersURL:      String("fu"),
+		GistsURL:          String("gu"),
+		OrganizationsURL:  String("ou"),
+		ReceivedEventsURL: String("reu"),
+		ReposURL:          String("ru"),
+		StarredURL:        String("su"),
+		SubscriptionsURL:  String("subu"),
+	}
+
+	want := `{
+		"id": 1,
+		"ldap_dn": "ldapdn",
+		"login": "l",
+		"avatar_url": "au",
+		"gravatar_id": "gi",
+		"type": "t",
+		"site_admin": true,
+		"url": "u",
+		"events_url": "eu",
+		"following_url": "fu",
+		"followers_url": "fu",
+		"gists_url": "gu",
+		"organizations_url": "ou",
+		"received_events_url": "reu",
+		"repos_url": "ru",
+		"starred_url": "su",
+		"subscriptions_url": "subu"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestEnterprise_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Enterprise{}, "{}")
+
+	u := &Enterprise{
+		ID:          Int(1),
+		Slug:        String("s"),
+		Name:        String("n"),
+		NodeID:      String("nid"),
+		AvatarURL:   String("au"),
+		Description: String("d"),
+		WebsiteURL:  String("wu"),
+		HTMLURL:     String("hu"),
+		CreatedAt:   &Timestamp{referenceTime},
+		UpdatedAt:   &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"id": 1,
+		"slug": "s",
+		"name": "n",
+		"node_id": "nid",
+		"avatar_url": "au",
+		"description": "d",
+		"website_url": "wu",
+		"html_url": "hu",
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/admin_users_test.go b/github/admin_users_test.go
index 253ddf6f..cd008c37 100644
--- a/github/admin_users_test.go
+++ b/github/admin_users_test.go
@@ -175,3 +175,99 @@ func TestUserImpersonation_Delete(t *testing.T) {
 		return client.Admin.DeleteUserImpersonation(ctx, "github")
 	})
 }
+
+func TestCreateUserRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &createUserRequest{}, "{}")
+
+	u := &createUserRequest{
+		Login: String("l"),
+		Email: String("e"),
+	}
+
+	want := `{
+		"login": "l",
+		"email": "e"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestImpersonateUserOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ImpersonateUserOptions{}, "{}")
+
+	u := &ImpersonateUserOptions{
+		Scopes: []string{
+			"s",
+		},
+	}
+
+	want := `{
+		"scopes": ["s"]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestOAuthAPP_Marshal(t *testing.T) {
+	testJSONMarshal(t, &OAuthAPP{}, "{}")
+
+	u := &OAuthAPP{
+		URL:      String("u"),
+		Name:     String("n"),
+		ClientID: String("cid"),
+	}
+
+	want := `{
+		"url": "u",
+		"name": "n",
+		"client_id": "cid"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestUserAuthorization_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserAuthorization{}, "{}")
+
+	u := &UserAuthorization{
+		ID:  Int64(1),
+		URL: String("u"),
+		Scopes: []string{
+			"s",
+		},
+		Token:          String("t"),
+		TokenLastEight: String("tle"),
+		HashedToken:    String("ht"),
+		App: &OAuthAPP{
+			URL:      String("u"),
+			Name:     String("n"),
+			ClientID: String("cid"),
+		},
+		Note:        String("n"),
+		NoteURL:     String("nu"),
+		UpdatedAt:   &Timestamp{referenceTime},
+		CreatedAt:   &Timestamp{referenceTime},
+		Fingerprint: String("f"),
+	}
+
+	want := `{
+		"id": 1,
+		"url": "u",
+		"scopes": ["s"],
+		"token": "t",
+		"token_last_eight": "tle",
+		"hashed_token": "ht",
+		"app": {
+			"url": "u",
+			"name": "n",
+			"client_id": "cid"
+		},
+		"note": "n",
+		"note_url": "nu",
+		"updated_at": ` + referenceTimeStr + `,
+		"created_at": ` + referenceTimeStr + `,
+		"fingerprint": "f"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/apps_installation_test.go b/github/apps_installation_test.go
index 563e0d2f..56f0ad9e 100644
--- a/github/apps_installation_test.go
+++ b/github/apps_installation_test.go
@@ -173,3 +173,29 @@ func TestAppsService_RevokeInstallationToken(t *testing.T) {
 		return client.Apps.RevokeInstallationToken(ctx)
 	})
 }
+
+func TestListRepositories_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ListRepositories{}, "{}")
+
+	u := &ListRepositories{
+		TotalCount: Int(1),
+		Repositories: []*Repository{
+			{
+				ID:   Int64(1),
+				URL:  String("u"),
+				Name: String("n"),
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 1,
+		"repositories": [{
+			"id":1,
+			"name":"n",
+			"url":"u"
+			}]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/apps_manifest_test.go b/github/apps_manifest_test.go
index 5fbe9ff1..a5d230d0 100644
--- a/github/apps_manifest_test.go
+++ b/github/apps_manifest_test.go
@@ -66,3 +66,79 @@ func TestGetConfig(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestAppConfig_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AppConfig{}, "{}")
+
+	u := &AppConfig{
+		ID:     Int64(1),
+		NodeID: String("nid"),
+		Owner: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+		Name:          String("n"),
+		Description:   String("d"),
+		ExternalURL:   String("eu"),
+		HTMLURL:       String("hu"),
+		CreatedAt:     &Timestamp{referenceTime},
+		UpdatedAt:     &Timestamp{referenceTime},
+		ClientID:      String("ci"),
+		ClientSecret:  String("cs"),
+		WebhookSecret: String("ws"),
+		PEM:           String("pem"),
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "nid",
+		"owner": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"name": "n",
+		"description": "d",
+		"external_url": "eu",
+		"html_url": "hu",
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"client_id": "ci",
+		"client_secret": "cs",
+		"webhook_secret": "ws",
+		"pem": "pem"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/apps_marketplace_test.go b/github/apps_marketplace_test.go
index 10c7dea1..dcf5eb89 100644
--- a/github/apps_marketplace_test.go
+++ b/github/apps_marketplace_test.go
@@ -235,3 +235,251 @@ func TestMarketplaceService_Stubbed_ListMarketplacePurchasesForUser(t *testing.T
 		t.Errorf("Marketplace.ListMarketplacePurchasesForUser returned %+v, want %+v", purchases, want)
 	}
 }
+
+func TestMarketplacePlan_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MarketplacePlan{}, "{}")
+
+	u := &MarketplacePlan{
+		URL:                 String("u"),
+		AccountsURL:         String("au"),
+		ID:                  Int64(1),
+		Number:              Int(1),
+		Name:                String("n"),
+		Description:         String("d"),
+		MonthlyPriceInCents: Int(1),
+		YearlyPriceInCents:  Int(1),
+		PriceModel:          String("pm"),
+		UnitName:            String("un"),
+		Bullets:             &[]string{"b"},
+		State:               String("s"),
+		HasFreeTrial:        Bool(false),
+	}
+
+	want := `{
+		"url": "u",
+		"accounts_url": "au",
+		"id": 1,
+		"number": 1,
+		"name": "n",
+		"description": "d",
+		"monthly_price_in_cents": 1,
+		"yearly_price_in_cents": 1,
+		"price_model": "pm",
+		"unit_name": "un",
+		"bullets": ["b"],
+		"state": "s",
+		"has_free_trial": false
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestMarketplacePurchase_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MarketplacePurchase{}, "{}")
+
+	u := &MarketplacePurchase{
+		BillingCycle:    String("bc"),
+		NextBillingDate: &Timestamp{referenceTime},
+		UnitCount:       Int(1),
+		Plan: &MarketplacePlan{
+			URL:                 String("u"),
+			AccountsURL:         String("au"),
+			ID:                  Int64(1),
+			Number:              Int(1),
+			Name:                String("n"),
+			Description:         String("d"),
+			MonthlyPriceInCents: Int(1),
+			YearlyPriceInCents:  Int(1),
+			PriceModel:          String("pm"),
+			UnitName:            String("un"),
+			Bullets:             &[]string{"b"},
+			State:               String("s"),
+			HasFreeTrial:        Bool(false),
+		},
+		OnFreeTrial:     Bool(false),
+		FreeTrialEndsOn: &Timestamp{referenceTime},
+		UpdatedAt:       &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"billing_cycle": "bc",
+		"next_billing_date": ` + referenceTimeStr + `,
+		"unit_count": 1,
+		"plan": {
+			"url": "u",
+			"accounts_url": "au",
+			"id": 1,
+			"number": 1,
+			"name": "n",
+			"description": "d",
+			"monthly_price_in_cents": 1,
+			"yearly_price_in_cents": 1,
+			"price_model": "pm",
+			"unit_name": "un",
+			"bullets": ["b"],
+			"state": "s",
+			"has_free_trial": false
+			},
+		"on_free_trial": false,
+		"free_trial_ends_on": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestMarketplacePendingChange_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MarketplacePendingChange{}, "{}")
+
+	u := &MarketplacePendingChange{
+		EffectiveDate: &Timestamp{referenceTime},
+		UnitCount:     Int(1),
+		ID:            Int64(1),
+		Plan: &MarketplacePlan{
+			URL:                 String("u"),
+			AccountsURL:         String("au"),
+			ID:                  Int64(1),
+			Number:              Int(1),
+			Name:                String("n"),
+			Description:         String("d"),
+			MonthlyPriceInCents: Int(1),
+			YearlyPriceInCents:  Int(1),
+			PriceModel:          String("pm"),
+			UnitName:            String("un"),
+			Bullets:             &[]string{"b"},
+			State:               String("s"),
+			HasFreeTrial:        Bool(false),
+		},
+	}
+
+	want := `{
+		"effective_date": ` + referenceTimeStr + `,
+		"unit_count": 1,
+		"id": 1,
+		"plan": {
+			"url": "u",
+			"accounts_url": "au",
+			"id": 1,
+			"number": 1,
+			"name": "n",
+			"description": "d",
+			"monthly_price_in_cents": 1,
+			"yearly_price_in_cents": 1,
+			"price_model": "pm",
+			"unit_name": "un",
+			"bullets": ["b"],
+			"state": "s",
+			"has_free_trial": false
+			}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestMarketplacePlanAccount_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MarketplacePlanAccount{}, "{}")
+
+	u := &MarketplacePlanAccount{
+		URL:                      String("u"),
+		Type:                     String("t"),
+		ID:                       Int64(1),
+		Login:                    String("l"),
+		OrganizationBillingEmail: String("obe"),
+		MarketplacePurchase: &MarketplacePurchase{
+			BillingCycle:    String("bc"),
+			NextBillingDate: &Timestamp{referenceTime},
+			UnitCount:       Int(1),
+			Plan: &MarketplacePlan{
+				URL:                 String("u"),
+				AccountsURL:         String("au"),
+				ID:                  Int64(1),
+				Number:              Int(1),
+				Name:                String("n"),
+				Description:         String("d"),
+				MonthlyPriceInCents: Int(1),
+				YearlyPriceInCents:  Int(1),
+				PriceModel:          String("pm"),
+				UnitName:            String("un"),
+				Bullets:             &[]string{"b"},
+				State:               String("s"),
+				HasFreeTrial:        Bool(false),
+			},
+			OnFreeTrial:     Bool(false),
+			FreeTrialEndsOn: &Timestamp{referenceTime},
+			UpdatedAt:       &Timestamp{referenceTime},
+		},
+		MarketplacePendingChange: &MarketplacePendingChange{
+			EffectiveDate: &Timestamp{referenceTime},
+			UnitCount:     Int(1),
+			ID:            Int64(1),
+			Plan: &MarketplacePlan{
+				URL:                 String("u"),
+				AccountsURL:         String("au"),
+				ID:                  Int64(1),
+				Number:              Int(1),
+				Name:                String("n"),
+				Description:         String("d"),
+				MonthlyPriceInCents: Int(1),
+				YearlyPriceInCents:  Int(1),
+				PriceModel:          String("pm"),
+				UnitName:            String("un"),
+				Bullets:             &[]string{"b"},
+				State:               String("s"),
+				HasFreeTrial:        Bool(false),
+			},
+		},
+	}
+
+	want := `{
+		"url": "u",
+		"type": "t",
+		"id": 1,
+		"login": "l",
+		"organization_billing_email": "obe",
+		"marketplace_purchase": {
+			"billing_cycle": "bc",
+			"next_billing_date": ` + referenceTimeStr + `,
+			"unit_count": 1,
+			"plan": {
+				"url": "u",
+				"accounts_url": "au",
+				"id": 1,
+				"number": 1,
+				"name": "n",
+				"description": "d",
+				"monthly_price_in_cents": 1,
+				"yearly_price_in_cents": 1,
+				"price_model": "pm",
+				"unit_name": "un",
+				"bullets": ["b"],
+				"state": "s",
+				"has_free_trial": false
+				},
+			"on_free_trial": false,
+			"free_trial_ends_on": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `
+		},
+		"marketplace_pending_change": {
+			"effective_date": ` + referenceTimeStr + `,
+			"unit_count": 1,
+			"id": 1,
+			"plan": {
+				"url": "u",
+				"accounts_url": "au",
+				"id": 1,
+				"number": 1,
+				"name": "n",
+				"description": "d",
+				"monthly_price_in_cents": 1,
+				"yearly_price_in_cents": 1,
+				"price_model": "pm",
+				"unit_name": "un",
+				"bullets": ["b"],
+				"state": "s",
+				"has_free_trial": false
+			}
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/apps_test.go b/github/apps_test.go
index 841fe173..5079d416 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -594,3 +594,633 @@ func TestAppsService_FindUserInstallation(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestContentReference_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ContentReference{}, "{}")
+
+	u := &ContentReference{
+		ID:        Int64(1),
+		NodeID:    String("nid"),
+		Reference: String("r"),
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "nid",
+		"reference": "r"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestAttachment_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Attachment{}, "{}")
+
+	u := &Attachment{
+		ID:    Int64(1),
+		Title: String("t"),
+		Body:  String("b"),
+	}
+
+	want := `{
+		"id": 1,
+		"title": "t",
+		"body": "b"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestInstallationPermissions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &InstallationPermissions{}, "{}")
+
+	u := &InstallationPermissions{
+		Actions:                       String("a"),
+		Administration:                String("ad"),
+		Checks:                        String("c"),
+		Contents:                      String("co"),
+		ContentReferences:             String("cr"),
+		Deployments:                   String("d"),
+		Environments:                  String("e"),
+		Issues:                        String("i"),
+		Metadata:                      String("md"),
+		Members:                       String("m"),
+		OrganizationAdministration:    String("oa"),
+		OrganizationHooks:             String("oh"),
+		OrganizationPlan:              String("op"),
+		OrganizationPreReceiveHooks:   String("opr"),
+		OrganizationProjects:          String("op"),
+		OrganizationSecrets:           String("os"),
+		OrganizationSelfHostedRunners: String("osh"),
+		OrganizationUserBlocking:      String("oub"),
+		Packages:                      String("pkg"),
+		Pages:                         String("pg"),
+		PullRequests:                  String("pr"),
+		RepositoryHooks:               String("rh"),
+		RepositoryProjects:            String("rp"),
+		RepositoryPreReceiveHooks:     String("rprh"),
+		Secrets:                       String("s"),
+		SecretScanningAlerts:          String("ssa"),
+		SecurityEvents:                String("se"),
+		SingleFile:                    String("sf"),
+		Statuses:                      String("s"),
+		TeamDiscussions:               String("td"),
+		VulnerabilityAlerts:           String("va"),
+		Workflows:                     String("w"),
+	}
+
+	want := `{
+		"actions": "a",
+		"administration": "ad",
+		"checks": "c",
+		"contents": "co",
+		"content_references": "cr",
+		"deployments": "d",
+		"environments": "e",
+		"issues": "i",
+		"metadata": "md",
+		"members": "m",
+		"organization_administration": "oa",
+		"organization_hooks": "oh",
+		"organization_plan": "op",
+		"organization_pre_receive_hooks": "opr",
+		"organization_projects": "op",
+		"organization_secrets": "os",
+		"organization_self_hosted_runners": "osh",
+		"organization_user_blocking": "oub",
+		"packages": "pkg",
+		"pages": "pg",
+		"pull_requests": "pr",
+		"repository_hooks": "rh",
+		"repository_projects": "rp",
+		"repository_pre_receive_hooks": "rprh",
+		"secrets": "s",
+		"secret_scanning_alerts": "ssa",
+		"security_events": "se",
+		"single_file": "sf",
+		"statuses": "s",
+		"team_discussions": "td",
+		"vulnerability_alerts":"va",
+		"workflows": "w"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestInstallation_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Installation{}, "{}")
+
+	u := &Installation{
+		ID:       Int64(1),
+		NodeID:   String("nid"),
+		AppID:    Int64(1),
+		AppSlug:  String("as"),
+		TargetID: Int64(1),
+		Account: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+		AccessTokensURL:     String("atu"),
+		RepositoriesURL:     String("ru"),
+		HTMLURL:             String("hu"),
+		TargetType:          String("tt"),
+		SingleFileName:      String("sfn"),
+		RepositorySelection: String("rs"),
+		Events:              []string{"e"},
+		SingleFilePaths:     []string{"s"},
+		Permissions: &InstallationPermissions{
+			Actions:                       String("a"),
+			Administration:                String("ad"),
+			Checks:                        String("c"),
+			Contents:                      String("co"),
+			ContentReferences:             String("cr"),
+			Deployments:                   String("d"),
+			Environments:                  String("e"),
+			Issues:                        String("i"),
+			Metadata:                      String("md"),
+			Members:                       String("m"),
+			OrganizationAdministration:    String("oa"),
+			OrganizationHooks:             String("oh"),
+			OrganizationPlan:              String("op"),
+			OrganizationPreReceiveHooks:   String("opr"),
+			OrganizationProjects:          String("op"),
+			OrganizationSecrets:           String("os"),
+			OrganizationSelfHostedRunners: String("osh"),
+			OrganizationUserBlocking:      String("oub"),
+			Packages:                      String("pkg"),
+			Pages:                         String("pg"),
+			PullRequests:                  String("pr"),
+			RepositoryHooks:               String("rh"),
+			RepositoryProjects:            String("rp"),
+			RepositoryPreReceiveHooks:     String("rprh"),
+			Secrets:                       String("s"),
+			SecretScanningAlerts:          String("ssa"),
+			SecurityEvents:                String("se"),
+			SingleFile:                    String("sf"),
+			Statuses:                      String("s"),
+			TeamDiscussions:               String("td"),
+			VulnerabilityAlerts:           String("va"),
+			Workflows:                     String("w"),
+		},
+		CreatedAt:              &Timestamp{referenceTime},
+		UpdatedAt:              &Timestamp{referenceTime},
+		HasMultipleSingleFiles: Bool(false),
+		SuspendedBy: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+		SuspendedAt: &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "nid",
+		"app_id": 1,
+		"app_slug": "as",
+		"target_id": 1,
+		"account": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"access_tokens_url": "atu",
+		"repositories_url": "ru",
+		"html_url": "hu",
+		"target_type": "tt",
+		"single_file_name": "sfn",
+		"repository_selection": "rs",
+		"events": [
+			"e"
+		],
+		"single_file_paths": [
+			"s"
+		],
+		"permissions": {
+			"actions": "a",
+			"administration": "ad",
+			"checks": "c",
+			"contents": "co",
+			"content_references": "cr",
+			"deployments": "d",
+			"environments": "e",
+			"issues": "i",
+			"metadata": "md",
+			"members": "m",
+			"organization_administration": "oa",
+			"organization_hooks": "oh",
+			"organization_plan": "op",
+			"organization_pre_receive_hooks": "opr",
+			"organization_projects": "op",
+			"organization_secrets": "os",
+			"organization_self_hosted_runners": "osh",
+			"organization_user_blocking": "oub",
+			"packages": "pkg",
+			"pages": "pg",
+			"pull_requests": "pr",
+			"repository_hooks": "rh",
+			"repository_projects": "rp",
+			"repository_pre_receive_hooks": "rprh",
+			"secrets": "s",
+			"secret_scanning_alerts": "ssa",
+			"security_events": "se",
+			"single_file": "sf",
+			"statuses": "s",
+			"team_discussions": "td",
+			"vulnerability_alerts": "va",
+			"workflows": "w"
+		},
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"has_multiple_single_files": false,
+		"suspended_by": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"suspended_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestInstallationTokenOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &InstallationTokenOptions{}, "{}")
+
+	u := &InstallationTokenOptions{
+		RepositoryIDs: []int64{1},
+		Permissions: &InstallationPermissions{
+			Actions:                       String("a"),
+			Administration:                String("ad"),
+			Checks:                        String("c"),
+			Contents:                      String("co"),
+			ContentReferences:             String("cr"),
+			Deployments:                   String("d"),
+			Environments:                  String("e"),
+			Issues:                        String("i"),
+			Metadata:                      String("md"),
+			Members:                       String("m"),
+			OrganizationAdministration:    String("oa"),
+			OrganizationHooks:             String("oh"),
+			OrganizationPlan:              String("op"),
+			OrganizationPreReceiveHooks:   String("opr"),
+			OrganizationProjects:          String("op"),
+			OrganizationSecrets:           String("os"),
+			OrganizationSelfHostedRunners: String("osh"),
+			OrganizationUserBlocking:      String("oub"),
+			Packages:                      String("pkg"),
+			Pages:                         String("pg"),
+			PullRequests:                  String("pr"),
+			RepositoryHooks:               String("rh"),
+			RepositoryProjects:            String("rp"),
+			RepositoryPreReceiveHooks:     String("rprh"),
+			Secrets:                       String("s"),
+			SecretScanningAlerts:          String("ssa"),
+			SecurityEvents:                String("se"),
+			SingleFile:                    String("sf"),
+			Statuses:                      String("s"),
+			TeamDiscussions:               String("td"),
+			VulnerabilityAlerts:           String("va"),
+			Workflows:                     String("w"),
+		},
+	}
+
+	want := `{
+		"repository_ids": [1],
+		"permissions": {
+			"actions": "a",
+			"administration": "ad",
+			"checks": "c",
+			"contents": "co",
+			"content_references": "cr",
+			"deployments": "d",
+			"environments": "e",
+			"issues": "i",
+			"metadata": "md",
+			"members": "m",
+			"organization_administration": "oa",
+			"organization_hooks": "oh",
+			"organization_plan": "op",
+			"organization_pre_receive_hooks": "opr",
+			"organization_projects": "op",
+			"organization_secrets": "os",
+			"organization_self_hosted_runners": "osh",
+			"organization_user_blocking": "oub",
+			"packages": "pkg",
+			"pages": "pg",
+			"pull_requests": "pr",
+			"repository_hooks": "rh",
+			"repository_projects": "rp",
+			"repository_pre_receive_hooks": "rprh",
+			"secrets": "s",
+			"secret_scanning_alerts": "ssa",
+			"security_events": "se",
+			"single_file": "sf",
+			"statuses": "s",
+			"team_discussions": "td",
+			"vulnerability_alerts": "va",
+			"workflows": "w"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestInstallationToken_Marshal(t *testing.T) {
+	testJSONMarshal(t, &InstallationToken{}, "{}")
+
+	u := &InstallationToken{
+		Token:     String("t"),
+		ExpiresAt: &referenceTime,
+		Permissions: &InstallationPermissions{
+			Actions:                       String("a"),
+			Administration:                String("ad"),
+			Checks:                        String("c"),
+			Contents:                      String("co"),
+			ContentReferences:             String("cr"),
+			Deployments:                   String("d"),
+			Environments:                  String("e"),
+			Issues:                        String("i"),
+			Metadata:                      String("md"),
+			Members:                       String("m"),
+			OrganizationAdministration:    String("oa"),
+			OrganizationHooks:             String("oh"),
+			OrganizationPlan:              String("op"),
+			OrganizationPreReceiveHooks:   String("opr"),
+			OrganizationProjects:          String("op"),
+			OrganizationSecrets:           String("os"),
+			OrganizationSelfHostedRunners: String("osh"),
+			OrganizationUserBlocking:      String("oub"),
+			Packages:                      String("pkg"),
+			Pages:                         String("pg"),
+			PullRequests:                  String("pr"),
+			RepositoryHooks:               String("rh"),
+			RepositoryProjects:            String("rp"),
+			RepositoryPreReceiveHooks:     String("rprh"),
+			Secrets:                       String("s"),
+			SecretScanningAlerts:          String("ssa"),
+			SecurityEvents:                String("se"),
+			SingleFile:                    String("sf"),
+			Statuses:                      String("s"),
+			TeamDiscussions:               String("td"),
+			VulnerabilityAlerts:           String("va"),
+			Workflows:                     String("w"),
+		},
+		Repositories: []*Repository{
+			{
+				ID:   Int64(1),
+				URL:  String("u"),
+				Name: String("n"),
+			},
+		},
+	}
+
+	want := `{
+		"token": "t",
+		"expires_at": ` + referenceTimeStr + `,
+		"permissions": {
+			"actions": "a",
+			"administration": "ad",
+			"checks": "c",
+			"contents": "co",
+			"content_references": "cr",
+			"deployments": "d",
+			"environments": "e",
+			"issues": "i",
+			"metadata": "md",
+			"members": "m",
+			"organization_administration": "oa",
+			"organization_hooks": "oh",
+			"organization_plan": "op",
+			"organization_pre_receive_hooks": "opr",
+			"organization_projects": "op",
+			"organization_secrets": "os",
+			"organization_self_hosted_runners": "osh",
+			"organization_user_blocking": "oub",
+			"packages": "pkg",
+			"pages": "pg",
+			"pull_requests": "pr",
+			"repository_hooks": "rh",
+			"repository_projects": "rp",
+			"repository_pre_receive_hooks": "rprh",
+			"secrets": "s",
+			"secret_scanning_alerts": "ssa",
+			"security_events": "se",
+			"single_file": "sf",
+			"statuses": "s",
+			"team_discussions": "td",
+			"vulnerability_alerts": "va",
+			"workflows": "w"
+		},
+		"repositories": [
+			{
+				"id": 1,
+				"url": "u",
+				"name": "n"
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestApp_Marshal(t *testing.T) {
+	testJSONMarshal(t, &App{}, "{}")
+
+	u := &App{
+		ID:     Int64(1),
+		Slug:   String("s"),
+		NodeID: String("nid"),
+		Owner: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+		Name:        String("n"),
+		Description: String("d"),
+		ExternalURL: String("eu"),
+		HTMLURL:     String("hu"),
+		CreatedAt:   &Timestamp{referenceTime},
+		UpdatedAt:   &Timestamp{referenceTime},
+		Permissions: &InstallationPermissions{
+			Actions:                       String("a"),
+			Administration:                String("ad"),
+			Checks:                        String("c"),
+			Contents:                      String("co"),
+			ContentReferences:             String("cr"),
+			Deployments:                   String("d"),
+			Environments:                  String("e"),
+			Issues:                        String("i"),
+			Metadata:                      String("md"),
+			Members:                       String("m"),
+			OrganizationAdministration:    String("oa"),
+			OrganizationHooks:             String("oh"),
+			OrganizationPlan:              String("op"),
+			OrganizationPreReceiveHooks:   String("opr"),
+			OrganizationProjects:          String("op"),
+			OrganizationSecrets:           String("os"),
+			OrganizationSelfHostedRunners: String("osh"),
+			OrganizationUserBlocking:      String("oub"),
+			Packages:                      String("pkg"),
+			Pages:                         String("pg"),
+			PullRequests:                  String("pr"),
+			RepositoryHooks:               String("rh"),
+			RepositoryProjects:            String("rp"),
+			RepositoryPreReceiveHooks:     String("rprh"),
+			Secrets:                       String("s"),
+			SecretScanningAlerts:          String("ssa"),
+			SecurityEvents:                String("se"),
+			SingleFile:                    String("sf"),
+			Statuses:                      String("s"),
+			TeamDiscussions:               String("td"),
+			VulnerabilityAlerts:           String("va"),
+			Workflows:                     String("w"),
+		},
+		Events: []string{"s"},
+	}
+
+	want := `{
+		"id": 1,
+		"slug": "s",
+		"node_id": "nid",
+		"owner": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"name": "n",
+		"description": "d",
+		"external_url": "eu",
+		"html_url": "hu",
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"permissions": {
+			"actions": "a",
+			"administration": "ad",
+			"checks": "c",
+			"contents": "co",
+			"content_references": "cr",
+			"deployments": "d",
+			"environments": "e",
+			"issues": "i",
+			"metadata": "md",
+			"members": "m",
+			"organization_administration": "oa",
+			"organization_hooks": "oh",
+			"organization_plan": "op",
+			"organization_pre_receive_hooks": "opr",
+			"organization_projects": "op",
+			"organization_secrets": "os",
+			"organization_self_hosted_runners": "osh",
+			"organization_user_blocking": "oub",
+			"packages": "pkg",
+			"pages": "pg",
+			"pull_requests": "pr",
+			"repository_hooks": "rh",
+			"repository_projects": "rp",
+			"repository_pre_receive_hooks": "rprh",
+			"secrets": "s",
+			"secret_scanning_alerts": "ssa",
+			"security_events": "se",
+			"single_file": "sf",
+			"statuses": "s",
+			"team_discussions": "td",
+			"vulnerability_alerts": "va",
+			"workflows": "w"
+		},
+		"events": ["s"]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/authorizations_test.go b/github/authorizations_test.go
index b1b3ed6c..bd7ff29d 100644
--- a/github/authorizations_test.go
+++ b/github/authorizations_test.go
@@ -203,3 +203,185 @@ func TestAuthorizationsService_DeleteImpersonation(t *testing.T) {
 		return client.Authorizations.DeleteImpersonation(ctx, "u")
 	})
 }
+
+func TestAuthorizationUpdateRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AuthorizationUpdateRequest{}, "{}")
+
+	u := &AuthorizationUpdateRequest{
+		Scopes:       []string{"s"},
+		AddScopes:    []string{"a"},
+		RemoveScopes: []string{"r"},
+		Note:         String("n"),
+		NoteURL:      String("nu"),
+		Fingerprint:  String("f"),
+	}
+
+	want := `{
+		"scopes": ["s"],
+		"add_scopes": ["a"],
+		"remove_scopes": ["r"],
+		"note": "n",
+		"note_url": "nu",
+		"fingerprint": "f"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestAuthorizationRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AuthorizationRequest{}, "{}")
+
+	u := &AuthorizationRequest{
+		Scopes:       []Scope{"s"},
+		ClientID:     String("cid"),
+		ClientSecret: String("cs"),
+		Note:         String("n"),
+		NoteURL:      String("nu"),
+		Fingerprint:  String("f"),
+	}
+
+	want := `{
+		"scopes": ["s"],
+		"client_id": "cid",
+		"client_secret": "cs",
+		"note": "n",
+		"note_url": "nu",
+		"fingerprint": "f"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestAuthorizationApp_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AuthorizationApp{}, "{}")
+
+	u := &AuthorizationApp{
+		URL:      String("u"),
+		Name:     String("n"),
+		ClientID: String("cid"),
+	}
+
+	want := `{
+		"url": "u",
+		"name": "n",
+		"client_id": "cid"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestGrant_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Grant{}, "{}")
+
+	u := &Grant{
+		ID:  Int64(1),
+		URL: String("u"),
+		App: &AuthorizationApp{
+			URL:      String("u"),
+			Name:     String("n"),
+			ClientID: String("cid"),
+		},
+		CreatedAt: &Timestamp{referenceTime},
+		UpdatedAt: &Timestamp{referenceTime},
+		Scopes:    []string{"s"},
+	}
+
+	want := `{
+		"id": 1,
+		"url": "u",
+		"app": {
+			"url": "u",
+			"name": "n",
+			"client_id": "cid"
+		},
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"scopes": ["s"]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestAuthorization_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Authorization{}, "{}")
+
+	u := &Authorization{
+		ID:             Int64(1),
+		URL:            String("u"),
+		Scopes:         []Scope{"s"},
+		Token:          String("t"),
+		TokenLastEight: String("tle"),
+		HashedToken:    String("ht"),
+		App: &AuthorizationApp{
+			URL:      String("u"),
+			Name:     String("n"),
+			ClientID: String("cid"),
+		},
+		Note:        String("n"),
+		NoteURL:     String("nu"),
+		UpdatedAt:   &Timestamp{referenceTime},
+		CreatedAt:   &Timestamp{referenceTime},
+		Fingerprint: String("f"),
+		User: &User{
+			Login:           String("l"),
+			ID:              Int64(1),
+			URL:             String("u"),
+			AvatarURL:       String("a"),
+			GravatarID:      String("g"),
+			Name:            String("n"),
+			Company:         String("c"),
+			Blog:            String("b"),
+			Location:        String("l"),
+			Email:           String("e"),
+			Hireable:        Bool(true),
+			Bio:             String("b"),
+			TwitterUsername: String("t"),
+			PublicRepos:     Int(1),
+			Followers:       Int(1),
+			Following:       Int(1),
+			CreatedAt:       &Timestamp{referenceTime},
+			SuspendedAt:     &Timestamp{referenceTime},
+		},
+	}
+
+	want := `{
+		"id": 1,
+		"url": "u",
+		"scopes": ["s"],
+		"token": "t",
+		"token_last_eight": "tle",
+		"hashed_token": "ht",
+		"app": {
+			"url": "u",
+			"name": "n",
+			"client_id": "cid"
+		},
+		"note": "n",
+		"note_url": "nu",
+		"updated_at": ` + referenceTimeStr + `,
+		"created_at": ` + referenceTimeStr + `,
+		"fingerprint": "f",
+		"user": {
+			"login": "l",
+			"id": 1,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"bio": "b",
+			"twitter_username": "t",
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `,
+			"url": "u"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/billing_test.go b/github/billing_test.go
index 92fada80..7d1c2a1d 100644
--- a/github/billing_test.go
+++ b/github/billing_test.go
@@ -297,3 +297,85 @@ func TestBillingService_GetStorageBillingUser_invalidUser(t *testing.T) {
 	_, _, err := client.Billing.GetStorageBillingUser(ctx, "%")
 	testURLParseError(t, err)
 }
+
+func TestMinutesUsedBreakdown_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MinutesUsedBreakdown{}, "{}")
+
+	u := &MinutesUsedBreakdown{
+		Ubuntu:  1,
+		MacOS:   1,
+		Windows: 1,
+	}
+
+	want := `{
+		"UBUNTU": 1,
+		"MACOS": 1,
+		"WINDOWS": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestActionBilling_Marshal(t *testing.T) {
+	testJSONMarshal(t, &MinutesUsedBreakdown{}, "{}")
+
+	u := &ActionBilling{
+		TotalMinutesUsed:     1,
+		TotalPaidMinutesUsed: 1,
+		IncludedMinutes:      1,
+		MinutesUsedBreakdown: MinutesUsedBreakdown{
+			Ubuntu:  1,
+			MacOS:   1,
+			Windows: 1,
+		},
+	}
+
+	want := `{
+		"total_minutes_used": 1,
+		"total_paid_minutes_used": 1,
+		"included_minutes": 1,
+		"minutes_used_breakdown": {
+			"UBUNTU": 1,
+			"MACOS": 1,
+			"WINDOWS": 1
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestPackageBilling_Marshal(t *testing.T) {
+	testJSONMarshal(t, &PackageBilling{}, "{}")
+
+	u := &PackageBilling{
+		TotalGigabytesBandwidthUsed:     1,
+		TotalPaidGigabytesBandwidthUsed: 1,
+		IncludedGigabytesBandwidth:      1,
+	}
+
+	want := `{
+		"total_gigabytes_bandwidth_used": 1,
+		"total_paid_gigabytes_bandwidth_used": 1,
+		"included_gigabytes_bandwidth": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestStorageBilling_Marshal(t *testing.T) {
+	testJSONMarshal(t, &StorageBilling{}, "{}")
+
+	u := &StorageBilling{
+		DaysLeftInBillingCycle:       1,
+		EstimatedPaidStorageForMonth: 1,
+		EstimatedStorageForMonth:     1,
+	}
+
+	want := `{
+		"days_left_in_billing_cycle": 1,
+		"estimated_paid_storage_for_month": 1,
+		"estimated_storage_for_month": 1
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/code-scanning_test.go b/github/code-scanning_test.go
index be9fb3de..2e898565 100644
--- a/github/code-scanning_test.go
+++ b/github/code-scanning_test.go
@@ -64,7 +64,11 @@ func TestActionsService_ListAlertsForRepo(t *testing.T) {
 				"rule_id":"js/trivial-conditional",
 				"rule_severity":"warning",
 				"rule_description":"Useless conditional",
-				"tool":"CodeQL",
+				"tool": {
+					"name": "CodeQL",
+					"guid": null,
+					"version": "1.4.0"
+				},
 				"created_at":"2020-05-06T12:00:00Z",
 				"open":true,
 				"closed_by":null,
@@ -76,7 +80,11 @@ func TestActionsService_ListAlertsForRepo(t *testing.T) {
 				"rule_id":"js/useless-expression",
 				"rule_severity":"warning",
 				"rule_description":"Expression has no effect",
-				"tool":"CodeQL",
+				"tool": {
+					"name": "CodeQL",
+					"guid": null,
+					"version": "1.4.0"
+				},
 				"created_at":"2020-05-06T12:00:00Z",
 				"open":true,
 				"closed_by":null,
@@ -99,7 +107,7 @@ func TestActionsService_ListAlertsForRepo(t *testing.T) {
 			RuleID:          String("js/trivial-conditional"),
 			RuleSeverity:    String("warning"),
 			RuleDescription: String("Useless conditional"),
-			Tool:            String("CodeQL"),
+			Tool:            &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
 			CreatedAt:       &date,
 			Open:            Bool(true),
 			ClosedBy:        nil,
@@ -111,7 +119,7 @@ func TestActionsService_ListAlertsForRepo(t *testing.T) {
 			RuleID:          String("js/useless-expression"),
 			RuleSeverity:    String("warning"),
 			RuleDescription: String("Expression has no effect"),
-			Tool:            String("CodeQL"),
+			Tool:            &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
 			CreatedAt:       &date,
 			Open:            Bool(true),
 			ClosedBy:        nil,
@@ -148,7 +156,11 @@ func TestActionsService_GetAlert(t *testing.T) {
 		fmt.Fprint(w, `{"rule_id":"js/useless-expression",
 				"rule_severity":"warning",
 				"rule_description":"Expression has no effect",
-				"tool":"CodeQL",
+				"tool": {
+					"name": "CodeQL",
+					"guid": null,
+					"version": "1.4.0"
+				},
 				"created_at":"2019-01-02T15:04:05Z",
 				"open":true,
 				"closed_by":null,
@@ -168,7 +180,7 @@ func TestActionsService_GetAlert(t *testing.T) {
 		RuleID:          String("js/useless-expression"),
 		RuleSeverity:    String("warning"),
 		RuleDescription: String("Expression has no effect"),
-		Tool:            String("CodeQL"),
+		Tool:            &Tool{Name: String("CodeQL"), GUID: nil, Version: String("1.4.0")},
 		CreatedAt:       &date,
 		Open:            Bool(true),
 		ClosedBy:        nil,
diff --git a/github/event_types_test.go b/github/event_types_test.go
index 986d9719..7c98c80b 100644
--- a/github/event_types_test.go
+++ b/github/event_types_test.go
@@ -12,16 +12,12 @@ import (
 func TestEditChange_Marshal_TitleChange(t *testing.T) {
 	testJSONMarshal(t, &EditChange{}, "{}")
 
-	TitleFrom := struct {
-		From *string `json:"from,omitempty"`
-	}{
-		From: String("TitleFrom"),
-	}
-
 	u := &EditChange{
-		Title: &TitleFrom,
-		Body:  nil,
-		Base:  nil,
+		Title: &EditTitle{
+			From: String("TitleFrom"),
+		},
+		Body: nil,
+		Base: nil,
 	}
 
 	want := `{
@@ -36,16 +32,12 @@ func TestEditChange_Marshal_TitleChange(t *testing.T) {
 func TestEditChange_Marshal_BodyChange(t *testing.T) {
 	testJSONMarshal(t, &EditChange{}, "{}")
 
-	BodyFrom := struct {
-		From *string `json:"from,omitempty"`
-	}{
-		From: String("BodyFrom"),
-	}
-
 	u := &EditChange{
 		Title: nil,
-		Body:  &BodyFrom,
-		Base:  nil,
+		Body: &EditBody{
+			From: String("BodyFrom"),
+		},
+		Base: nil,
 	}
 
 	want := `{
@@ -60,28 +52,13 @@ func TestEditChange_Marshal_BodyChange(t *testing.T) {
 func TestEditChange_Marshal_BaseChange(t *testing.T) {
 	testJSONMarshal(t, &EditChange{}, "{}")
 
-	RefFrom := struct {
-		From *string `json:"from,omitempty"`
-	}{
-		From: String("BaseRefFrom"),
-	}
-
-	SHAFrom := struct {
-		From *string `json:"from,omitempty"`
-	}{
-		From: String("BaseSHAFrom"),
-	}
-
-	Base := struct {
-		Ref *struct {
-			From *string `json:"from,omitempty"`
-		} `json:"ref,omitempty"`
-		SHA *struct {
-			From *string `json:"from,omitempty"`
-		} `json:"sha,omitempty"`
-	}{
-		Ref: &RefFrom,
-		SHA: &SHAFrom,
+	Base := EditBase{
+		Ref: &EditRef{
+			From: String("BaseRefFrom"),
+		},
+		SHA: &EditSHA{
+			From: String("BaseSHAFrom"),
+		},
 	}
 
 	u := &EditChange{
@@ -103,3 +80,69 @@ func TestEditChange_Marshal_BaseChange(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestProjectChange_Marshal_NameChange(t *testing.T) {
+	testJSONMarshal(t, &ProjectChange{}, "{}")
+
+	u := &ProjectChange{
+		Name: &ProjectName{From: String("NameFrom")},
+		Body: nil,
+	}
+
+	want := `{
+		"name": {
+			"from": "NameFrom"
+		  }
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestProjectChange_Marshal_BodyChange(t *testing.T) {
+	testJSONMarshal(t, &ProjectChange{}, "{}")
+
+	u := &ProjectChange{
+		Name: nil,
+		Body: &ProjectBody{From: String("BodyFrom")},
+	}
+
+	want := `{
+		"body": {
+			"from": "BodyFrom"
+		  }
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestProjectCardChange_Marshal_NoteChange(t *testing.T) {
+	testJSONMarshal(t, &ProjectCardChange{}, "{}")
+
+	u := &ProjectCardChange{
+		Note: &ProjectCardNote{From: String("NoteFrom")},
+	}
+
+	want := `{
+		"note": {
+			"from": "NoteFrom"
+		  }
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestProjectColumnChange_Marshal_NameChange(t *testing.T) {
+	testJSONMarshal(t, &ProjectColumnChange{}, "{}")
+
+	u := &ProjectColumnChange{
+		Name: &ProjectColumnName{From: String("NameFrom")},
+	}
+
+	want := `{
+		"name": {
+			"from": "NameFrom"
+		  }
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 750c6a40..fc3bdd4d 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -231,10 +231,7 @@ func TestAlert_GetRuleSeverity(tt *testing.T) {
 }
 
 func TestAlert_GetTool(tt *testing.T) {
-	var zeroValue string
-	a := &Alert{Tool: &zeroValue}
-	a.GetTool()
-	a = &Alert{}
+	a := &Alert{}
 	a.GetTool()
 	a = nil
 	a.GetTool()
@@ -4244,6 +4241,81 @@ func TestDraftReviewComment_GetStartSide(tt *testing.T) {
 	d.GetStartSide()
 }
 
+func TestEditBase_GetRef(tt *testing.T) {
+	e := &EditBase{}
+	e.GetRef()
+	e = nil
+	e.GetRef()
+}
+
+func TestEditBase_GetSHA(tt *testing.T) {
+	e := &EditBase{}
+	e.GetSHA()
+	e = nil
+	e.GetSHA()
+}
+
+func TestEditBody_GetFrom(tt *testing.T) {
+	var zeroValue string
+	e := &EditBody{From: &zeroValue}
+	e.GetFrom()
+	e = &EditBody{}
+	e.GetFrom()
+	e = nil
+	e.GetFrom()
+}
+
+func TestEditChange_GetBase(tt *testing.T) {
+	e := &EditChange{}
+	e.GetBase()
+	e = nil
+	e.GetBase()
+}
+
+func TestEditChange_GetBody(tt *testing.T) {
+	e := &EditChange{}
+	e.GetBody()
+	e = nil
+	e.GetBody()
+}
+
+func TestEditChange_GetTitle(tt *testing.T) {
+	e := &EditChange{}
+	e.GetTitle()
+	e = nil
+	e.GetTitle()
+}
+
+func TestEditRef_GetFrom(tt *testing.T) {
+	var zeroValue string
+	e := &EditRef{From: &zeroValue}
+	e.GetFrom()
+	e = &EditRef{}
+	e.GetFrom()
+	e = nil
+	e.GetFrom()
+}
+
+func TestEditSHA_GetFrom(tt *testing.T) {
+	var zeroValue string
+	e := &EditSHA{From: &zeroValue}
+	e.GetFrom()
+	e = &EditSHA{}
+	e.GetFrom()
+	e = nil
+	e.GetFrom()
+}
+
+func TestEditTitle_GetFrom(tt *testing.T) {
+	var zeroValue string
+	e := &EditTitle{From: &zeroValue}
+	e.GetFrom()
+	e = &EditTitle{}
+	e.GetFrom()
+	e = nil
+	e.GetFrom()
+}
+
 func TestEnterprise_GetAvatarURL(tt *testing.T) {
 	var zeroValue string
 	e := &Enterprise{AvatarURL: &zeroValue}
@@ -4491,6 +4563,23 @@ func TestEnvReviewers_GetType(tt *testing.T) {
 	e.GetType()
 }
 
+func TestErrorBlock_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	e := &ErrorBlock{CreatedAt: &zeroValue}
+	e.GetCreatedAt()
+	e = &ErrorBlock{}
+	e.GetCreatedAt()
+	e = nil
+	e.GetCreatedAt()
+}
+
+func TestErrorResponse_GetBlock(tt *testing.T) {
+	e := &ErrorResponse{}
+	e.GetBlock()
+	e = nil
+	e.GetBlock()
+}
+
 func TestEvent_GetActor(tt *testing.T) {
 	e := &Event{}
 	e.GetActor()
@@ -4582,6 +4671,48 @@ func TestFeedLink_GetType(tt *testing.T) {
 	f.GetType()
 }
 
+func TestFeedLinks_GetCurrentUser(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetCurrentUser()
+	f = nil
+	f.GetCurrentUser()
+}
+
+func TestFeedLinks_GetCurrentUserActor(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetCurrentUserActor()
+	f = nil
+	f.GetCurrentUserActor()
+}
+
+func TestFeedLinks_GetCurrentUserOrganization(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetCurrentUserOrganization()
+	f = nil
+	f.GetCurrentUserOrganization()
+}
+
+func TestFeedLinks_GetCurrentUserPublic(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetCurrentUserPublic()
+	f = nil
+	f.GetCurrentUserPublic()
+}
+
+func TestFeedLinks_GetTimeline(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetTimeline()
+	f = nil
+	f.GetTimeline()
+}
+
+func TestFeedLinks_GetUser(tt *testing.T) {
+	f := &FeedLinks{}
+	f.GetUser()
+	f = nil
+	f.GetUser()
+}
+
 func TestFeeds_GetCurrentUserActorURL(tt *testing.T) {
 	var zeroValue string
 	f := &Feeds{CurrentUserActorURL: &zeroValue}
@@ -4622,6 +4753,13 @@ func TestFeeds_GetCurrentUserURL(tt *testing.T) {
 	f.GetCurrentUserURL()
 }
 
+func TestFeeds_GetLinks(tt *testing.T) {
+	f := &Feeds{}
+	f.GetLinks()
+	f = nil
+	f.GetLinks()
+}
+
 func TestFeeds_GetTimelineURL(tt *testing.T) {
 	var zeroValue string
 	f := &Feeds{TimelineURL: &zeroValue}
@@ -10953,6 +11091,16 @@ func TestProject_GetURL(tt *testing.T) {
 	p.GetURL()
 }
 
+func TestProjectBody_GetFrom(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectBody{From: &zeroValue}
+	p.GetFrom()
+	p = &ProjectBody{}
+	p.GetFrom()
+	p = nil
+	p.GetFrom()
+}
+
 func TestProjectCard_GetArchived(tt *testing.T) {
 	var zeroValue bool
 	p := &ProjectCard{Archived: &zeroValue}
@@ -11100,6 +11248,13 @@ func TestProjectCard_GetURL(tt *testing.T) {
 	p.GetURL()
 }
 
+func TestProjectCardChange_GetNote(tt *testing.T) {
+	p := &ProjectCardChange{}
+	p.GetNote()
+	p = nil
+	p.GetNote()
+}
+
 func TestProjectCardEvent_GetAction(tt *testing.T) {
 	var zeroValue string
 	p := &ProjectCardEvent{Action: &zeroValue}
@@ -11172,6 +11327,16 @@ func TestProjectCardListOptions_GetArchivedState(tt *testing.T) {
 	p.GetArchivedState()
 }
 
+func TestProjectCardNote_GetFrom(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectCardNote{From: &zeroValue}
+	p.GetFrom()
+	p = &ProjectCardNote{}
+	p.GetFrom()
+	p = nil
+	p.GetFrom()
+}
+
 func TestProjectCardOptions_GetArchived(tt *testing.T) {
 	var zeroValue bool
 	p := &ProjectCardOptions{Archived: &zeroValue}
@@ -11182,6 +11347,20 @@ func TestProjectCardOptions_GetArchived(tt *testing.T) {
 	p.GetArchived()
 }
 
+func TestProjectChange_GetBody(tt *testing.T) {
+	p := &ProjectChange{}
+	p.GetBody()
+	p = nil
+	p.GetBody()
+}
+
+func TestProjectChange_GetName(tt *testing.T) {
+	p := &ProjectChange{}
+	p.GetName()
+	p = nil
+	p.GetName()
+}
+
 func TestProjectCollaboratorOptions_GetPermission(tt *testing.T) {
 	var zeroValue string
 	p := &ProjectCollaboratorOptions{Permission: &zeroValue}
@@ -11272,6 +11451,13 @@ func TestProjectColumn_GetURL(tt *testing.T) {
 	p.GetURL()
 }
 
+func TestProjectColumnChange_GetName(tt *testing.T) {
+	p := &ProjectColumnChange{}
+	p.GetName()
+	p = nil
+	p.GetName()
+}
+
 func TestProjectColumnEvent_GetAction(tt *testing.T) {
 	var zeroValue string
 	p := &ProjectColumnEvent{Action: &zeroValue}
@@ -11334,6 +11520,16 @@ func TestProjectColumnEvent_GetSender(tt *testing.T) {
 	p.GetSender()
 }
 
+func TestProjectColumnName_GetFrom(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectColumnName{From: &zeroValue}
+	p.GetFrom()
+	p = &ProjectColumnName{}
+	p.GetFrom()
+	p = nil
+	p.GetFrom()
+}
+
 func TestProjectEvent_GetAction(tt *testing.T) {
 	var zeroValue string
 	p := &ProjectEvent{Action: &zeroValue}
@@ -11386,6 +11582,16 @@ func TestProjectEvent_GetSender(tt *testing.T) {
 	p.GetSender()
 }
 
+func TestProjectName_GetFrom(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectName{From: &zeroValue}
+	p.GetFrom()
+	p = &ProjectName{}
+	p.GetFrom()
+	p = nil
+	p.GetFrom()
+}
+
 func TestProjectOptions_GetBody(tt *testing.T) {
 	var zeroValue string
 	p := &ProjectOptions{Body: &zeroValue}
@@ -11671,6 +11877,13 @@ func TestPullRequest_GetAuthorAssociation(tt *testing.T) {
 	p.GetAuthorAssociation()
 }
 
+func TestPullRequest_GetAutoMerge(tt *testing.T) {
+	p := &PullRequest{}
+	p.GetAutoMerge()
+	p = nil
+	p.GetAutoMerge()
+}
+
 func TestPullRequest_GetBase(tt *testing.T) {
 	p := &PullRequest{}
 	p.GetBase()
@@ -12043,6 +12256,43 @@ func TestPullRequest_GetUser(tt *testing.T) {
 	p.GetUser()
 }
 
+func TestPullRequestAutoMerge_GetCommitMessage(tt *testing.T) {
+	var zeroValue string
+	p := &PullRequestAutoMerge{CommitMessage: &zeroValue}
+	p.GetCommitMessage()
+	p = &PullRequestAutoMerge{}
+	p.GetCommitMessage()
+	p = nil
+	p.GetCommitMessage()
+}
+
+func TestPullRequestAutoMerge_GetCommitTitle(tt *testing.T) {
+	var zeroValue string
+	p := &PullRequestAutoMerge{CommitTitle: &zeroValue}
+	p.GetCommitTitle()
+	p = &PullRequestAutoMerge{}
+	p.GetCommitTitle()
+	p = nil
+	p.GetCommitTitle()
+}
+
+func TestPullRequestAutoMerge_GetEnabledBy(tt *testing.T) {
+	p := &PullRequestAutoMerge{}
+	p.GetEnabledBy()
+	p = nil
+	p.GetEnabledBy()
+}
+
+func TestPullRequestAutoMerge_GetMergeMethod(tt *testing.T) {
+	var zeroValue string
+	p := &PullRequestAutoMerge{MergeMethod: &zeroValue}
+	p.GetMergeMethod()
+	p = &PullRequestAutoMerge{}
+	p.GetMergeMethod()
+	p = nil
+	p.GetMergeMethod()
+}
+
 func TestPullRequestBranch_GetLabel(tt *testing.T) {
 	var zeroValue string
 	p := &PullRequestBranch{Label: &zeroValue}
@@ -14592,6 +14842,16 @@ func TestRepository_GetNotificationsURL(tt *testing.T) {
 	r.GetNotificationsURL()
 }
 
+func TestRepository_GetOpenIssues(tt *testing.T) {
+	var zeroValue int
+	r := &Repository{OpenIssues: &zeroValue}
+	r.GetOpenIssues()
+	r = &Repository{}
+	r.GetOpenIssues()
+	r = nil
+	r.GetOpenIssues()
+}
+
 func TestRepository_GetOpenIssuesCount(tt *testing.T) {
 	var zeroValue int
 	r := &Repository{OpenIssuesCount: &zeroValue}
@@ -14847,6 +15107,16 @@ func TestRepository_GetVisibility(tt *testing.T) {
 	r.GetVisibility()
 }
 
+func TestRepository_GetWatchers(tt *testing.T) {
+	var zeroValue int
+	r := &Repository{Watchers: &zeroValue}
+	r.GetWatchers()
+	r = &Repository{}
+	r.GetWatchers()
+	r = nil
+	r.GetWatchers()
+}
+
 func TestRepository_GetWatchersCount(tt *testing.T) {
 	var zeroValue int
 	r := &Repository{WatchersCount: &zeroValue}
@@ -15745,6 +16015,123 @@ func TestRepositoryTag_GetZipballURL(tt *testing.T) {
 	r.GetZipballURL()
 }
 
+func TestRepositoryVulnerabilityAlert_GetAffectedPackageName(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{AffectedPackageName: &zeroValue}
+	r.GetAffectedPackageName()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetAffectedPackageName()
+	r = nil
+	r.GetAffectedPackageName()
+}
+
+func TestRepositoryVulnerabilityAlert_GetAffectedRange(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{AffectedRange: &zeroValue}
+	r.GetAffectedRange()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetAffectedRange()
+	r = nil
+	r.GetAffectedRange()
+}
+
+func TestRepositoryVulnerabilityAlert_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	r := &RepositoryVulnerabilityAlert{CreatedAt: &zeroValue}
+	r.GetCreatedAt()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetCreatedAt()
+	r = nil
+	r.GetCreatedAt()
+}
+
+func TestRepositoryVulnerabilityAlert_GetDismissedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	r := &RepositoryVulnerabilityAlert{DismissedAt: &zeroValue}
+	r.GetDismissedAt()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetDismissedAt()
+	r = nil
+	r.GetDismissedAt()
+}
+
+func TestRepositoryVulnerabilityAlert_GetDismisser(tt *testing.T) {
+	r := &RepositoryVulnerabilityAlert{}
+	r.GetDismisser()
+	r = nil
+	r.GetDismisser()
+}
+
+func TestRepositoryVulnerabilityAlert_GetDismissReason(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{DismissReason: &zeroValue}
+	r.GetDismissReason()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetDismissReason()
+	r = nil
+	r.GetDismissReason()
+}
+
+func TestRepositoryVulnerabilityAlert_GetExternalIdentifier(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{ExternalIdentifier: &zeroValue}
+	r.GetExternalIdentifier()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetExternalIdentifier()
+	r = nil
+	r.GetExternalIdentifier()
+}
+
+func TestRepositoryVulnerabilityAlert_GetExternalReference(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{ExternalReference: &zeroValue}
+	r.GetExternalReference()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetExternalReference()
+	r = nil
+	r.GetExternalReference()
+}
+
+func TestRepositoryVulnerabilityAlert_GetFixedIn(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{FixedIn: &zeroValue}
+	r.GetFixedIn()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetFixedIn()
+	r = nil
+	r.GetFixedIn()
+}
+
+func TestRepositoryVulnerabilityAlert_GetGitHubSecurityAdvisoryID(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{GitHubSecurityAdvisoryID: &zeroValue}
+	r.GetGitHubSecurityAdvisoryID()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetGitHubSecurityAdvisoryID()
+	r = nil
+	r.GetGitHubSecurityAdvisoryID()
+}
+
+func TestRepositoryVulnerabilityAlert_GetID(tt *testing.T) {
+	var zeroValue int64
+	r := &RepositoryVulnerabilityAlert{ID: &zeroValue}
+	r.GetID()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetID()
+	r = nil
+	r.GetID()
+}
+
+func TestRepositoryVulnerabilityAlert_GetSeverity(tt *testing.T) {
+	var zeroValue string
+	r := &RepositoryVulnerabilityAlert{Severity: &zeroValue}
+	r.GetSeverity()
+	r = &RepositoryVulnerabilityAlert{}
+	r.GetSeverity()
+	r = nil
+	r.GetSeverity()
+}
+
 func TestRepositoryVulnerabilityAlertEvent_GetAction(tt *testing.T) {
 	var zeroValue string
 	r := &RepositoryVulnerabilityAlertEvent{Action: &zeroValue}
@@ -15755,6 +16142,13 @@ func TestRepositoryVulnerabilityAlertEvent_GetAction(tt *testing.T) {
 	r.GetAction()
 }
 
+func TestRepositoryVulnerabilityAlertEvent_GetAlert(tt *testing.T) {
+	r := &RepositoryVulnerabilityAlertEvent{}
+	r.GetAlert()
+	r = nil
+	r.GetAlert()
+}
+
 func TestRepositoryVulnerabilityAlertEvent_GetRepository(tt *testing.T) {
 	r := &RepositoryVulnerabilityAlertEvent{}
 	r.GetRepository()
@@ -16946,6 +17340,44 @@ func TestTeamAddEvent_GetTeam(tt *testing.T) {
 	t.GetTeam()
 }
 
+func TestTeamChange_GetDescription(tt *testing.T) {
+	t := &TeamChange{}
+	t.GetDescription()
+	t = nil
+	t.GetDescription()
+}
+
+func TestTeamChange_GetName(tt *testing.T) {
+	t := &TeamChange{}
+	t.GetName()
+	t = nil
+	t.GetName()
+}
+
+func TestTeamChange_GetPrivacy(tt *testing.T) {
+	t := &TeamChange{}
+	t.GetPrivacy()
+	t = nil
+	t.GetPrivacy()
+}
+
+func TestTeamChange_GetRepository(tt *testing.T) {
+	t := &TeamChange{}
+	t.GetRepository()
+	t = nil
+	t.GetRepository()
+}
+
+func TestTeamDescription_GetFrom(tt *testing.T) {
+	var zeroValue string
+	t := &TeamDescription{From: &zeroValue}
+	t.GetFrom()
+	t = &TeamDescription{}
+	t.GetFrom()
+	t = nil
+	t.GetFrom()
+}
+
 func TestTeamDiscussion_GetAuthor(tt *testing.T) {
 	t := &TeamDiscussion{}
 	t.GetAuthor()
@@ -17272,6 +17704,63 @@ func TestTeamLDAPMapping_GetURL(tt *testing.T) {
 	t.GetURL()
 }
 
+func TestTeamName_GetFrom(tt *testing.T) {
+	var zeroValue string
+	t := &TeamName{From: &zeroValue}
+	t.GetFrom()
+	t = &TeamName{}
+	t.GetFrom()
+	t = nil
+	t.GetFrom()
+}
+
+func TestTeamPermissions_GetFrom(tt *testing.T) {
+	t := &TeamPermissions{}
+	t.GetFrom()
+	t = nil
+	t.GetFrom()
+}
+
+func TestTeamPermissionsFrom_GetAdmin(tt *testing.T) {
+	var zeroValue bool
+	t := &TeamPermissionsFrom{Admin: &zeroValue}
+	t.GetAdmin()
+	t = &TeamPermissionsFrom{}
+	t.GetAdmin()
+	t = nil
+	t.GetAdmin()
+}
+
+func TestTeamPermissionsFrom_GetPull(tt *testing.T) {
+	var zeroValue bool
+	t := &TeamPermissionsFrom{Pull: &zeroValue}
+	t.GetPull()
+	t = &TeamPermissionsFrom{}
+	t.GetPull()
+	t = nil
+	t.GetPull()
+}
+
+func TestTeamPermissionsFrom_GetPush(tt *testing.T) {
+	var zeroValue bool
+	t := &TeamPermissionsFrom{Push: &zeroValue}
+	t.GetPush()
+	t = &TeamPermissionsFrom{}
+	t.GetPush()
+	t = nil
+	t.GetPush()
+}
+
+func TestTeamPrivacy_GetFrom(tt *testing.T) {
+	var zeroValue string
+	t := &TeamPrivacy{From: &zeroValue}
+	t.GetFrom()
+	t = &TeamPrivacy{}
+	t.GetFrom()
+	t = nil
+	t.GetFrom()
+}
+
 func TestTeamProjectOptions_GetPermission(tt *testing.T) {
 	var zeroValue string
 	t := &TeamProjectOptions{Permission: &zeroValue}
@@ -17282,6 +17771,13 @@ func TestTeamProjectOptions_GetPermission(tt *testing.T) {
 	t.GetPermission()
 }
 
+func TestTeamRepository_GetPermissions(tt *testing.T) {
+	t := &TeamRepository{}
+	t.GetPermissions()
+	t = nil
+	t.GetPermissions()
+}
+
 func TestTemplateRepoRequest_GetDescription(tt *testing.T) {
 	var zeroValue string
 	t := &TemplateRepoRequest{Description: &zeroValue}
@@ -17471,6 +17967,16 @@ func TestTimeline_GetSource(tt *testing.T) {
 	t.GetSource()
 }
 
+func TestTimeline_GetState(tt *testing.T) {
+	var zeroValue string
+	t := &Timeline{State: &zeroValue}
+	t.GetState()
+	t = &Timeline{}
+	t.GetState()
+	t = nil
+	t.GetState()
+}
+
 func TestTimeline_GetURL(tt *testing.T) {
 	var zeroValue string
 	t := &Timeline{URL: &zeroValue}
@@ -17481,6 +17987,36 @@ func TestTimeline_GetURL(tt *testing.T) {
 	t.GetURL()
 }
 
+func TestTool_GetGUID(tt *testing.T) {
+	var zeroValue string
+	t := &Tool{GUID: &zeroValue}
+	t.GetGUID()
+	t = &Tool{}
+	t.GetGUID()
+	t = nil
+	t.GetGUID()
+}
+
+func TestTool_GetName(tt *testing.T) {
+	var zeroValue string
+	t := &Tool{Name: &zeroValue}
+	t.GetName()
+	t = &Tool{}
+	t.GetName()
+	t = nil
+	t.GetName()
+}
+
+func TestTool_GetVersion(tt *testing.T) {
+	var zeroValue string
+	t := &Tool{Version: &zeroValue}
+	t.GetVersion()
+	t = &Tool{}
+	t.GetVersion()
+	t = nil
+	t.GetVersion()
+}
+
 func TestTopicResult_GetCreatedAt(tt *testing.T) {
 	var zeroValue Timestamp
 	t := &TopicResult{CreatedAt: &zeroValue}
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index cf0c7ebe..952176a6 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -1129,12 +1129,13 @@ func TestPullRequest_String(t *testing.T) {
 		MaintainerCanModify: Bool(false),
 		AuthorAssociation:   String(""),
 		NodeID:              String(""),
+		AutoMerge:           &PullRequestAutoMerge{},
 		Links:               &PRLinks{},
 		Head:                &PullRequestBranch{},
 		Base:                &PullRequestBranch{},
 		ActiveLockReason:    String(""),
 	}
-	want := `github.PullRequest{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", User:github.User{}, Draft:false, Merged:false, Mergeable:false, MergeableState:"", MergedBy:github.User{}, MergeCommitSHA:"", Rebaseable:false, Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", ReviewComments:0, Assignee:github.User{}, Milestone:github.Milestone{}, MaintainerCanModify:false, AuthorAssociation:"", NodeID:"", Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}`
+	want := `github.PullRequest{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", User:github.User{}, Draft:false, Merged:false, Mergeable:false, MergeableState:"", MergedBy:github.User{}, MergeCommitSHA:"", Rebaseable:false, Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", ReviewComments:0, Assignee:github.User{}, Milestone:github.Milestone{}, MaintainerCanModify:false, AuthorAssociation:"", NodeID:"", AutoMerge:github.PullRequestAutoMerge{}, Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}`
 	if got := v.String(); got != want {
 		t.Errorf("PullRequest.String = %v, want %v", got, want)
 	}
@@ -1381,9 +1382,11 @@ func TestRepository_String(t *testing.T) {
 		ForksCount:          Int(0),
 		NetworkCount:        Int(0),
 		OpenIssuesCount:     Int(0),
+		OpenIssues:          Int(0),
 		StargazersCount:     Int(0),
 		SubscribersCount:    Int(0),
 		WatchersCount:       Int(0),
+		Watchers:            Int(0),
 		Size:                Int(0),
 		AutoInit:            Bool(false),
 		Parent:              &Repository{},
@@ -1446,7 +1449,7 @@ func TestRepository_String(t *testing.T) {
 		TeamsURL:            String(""),
 		Visibility:          String(""),
 	}
-	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}`
+	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, OpenIssues:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Watchers:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Repository.String = %v, want %v", got, want)
 	}
diff --git a/github/github_test.go b/github/github_test.go
index 828898fd..158510ab 100644
--- a/github/github_test.go
+++ b/github/github_test.go
@@ -201,6 +201,9 @@ func testNewRequestAndDoFailure(t *testing.T, methodName string, client *Client,
 	client.BaseURL.Path = "/api-v3/"
 	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
 	resp, err = f()
+	if bypass := resp.Request.Context().Value(bypassRateLimitCheck); bypass != nil {
+		return
+	}
 	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
 		if resp != nil {
 			t.Errorf("rate.Reset.Time > now %v resp = %#v, want StatusCode=%v", methodName, resp.Response, want)
@@ -1091,10 +1094,7 @@ func TestCheckResponse(t *testing.T) {
 		Response: res,
 		Message:  "m",
 		Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
-		Block: &struct {
-			Reason    string     `json:"reason,omitempty"`
-			CreatedAt *Timestamp `json:"created_at,omitempty"`
-		}{
+		Block: &ErrorBlock{
 			Reason:    "dmca",
 			CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 		},
@@ -1194,10 +1194,7 @@ func TestErrorResponse_Is(t *testing.T) {
 		Response: &http.Response{},
 		Message:  "m",
 		Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
-		Block: &struct {
-			Reason    string     `json:"reason,omitempty"`
-			CreatedAt *Timestamp `json:"created_at,omitempty"`
-		}{
+		Block: &ErrorBlock{
 			Reason:    "r",
 			CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 		},
@@ -1213,10 +1210,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1229,10 +1223,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m1",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1245,10 +1236,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1260,10 +1248,7 @@ func TestErrorResponse_Is(t *testing.T) {
 			otherError: &ErrorResponse{
 				Errors:  []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message: "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1276,10 +1261,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r1", Field: "f1", Code: "c1"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1292,10 +1274,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1317,10 +1296,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r1",
 					CreatedAt: &Timestamp{time.Date(2016, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1333,10 +1309,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: nil,
 				},
@@ -1349,10 +1322,7 @@ func TestErrorResponse_Is(t *testing.T) {
 				Response: &http.Response{},
 				Errors:   []Error{{Resource: "r", Field: "f", Code: "c"}},
 				Message:  "m",
-				Block: &struct {
-					Reason    string     `json:"reason,omitempty"`
-					CreatedAt *Timestamp `json:"created_at,omitempty"`
-				}{
+				Block: &ErrorBlock{
 					Reason:    "r",
 					CreatedAt: &Timestamp{time.Date(2017, time.March, 17, 15, 39, 46, 0, time.UTC)},
 				},
@@ -1711,6 +1681,52 @@ func TestRateLimits_coverage(t *testing.T) {
 	})
 }
 
+func TestRateLimits_overQuota(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	client.rateLimits[coreCategory] = Rate{
+		Limit:     1,
+		Remaining: 0,
+		Reset:     Timestamp{time.Now().Add(time.Hour).Local()},
+	}
+	mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) {
+		fmt.Fprint(w, `{"resources":{
+			"core": {"limit":2,"remaining":1,"reset":1372700873},
+			"search": {"limit":3,"remaining":2,"reset":1372700874}
+		}}`)
+	})
+
+	ctx := context.Background()
+	rate, _, err := client.RateLimits(ctx)
+	if err != nil {
+		t.Errorf("RateLimits returned error: %v", err)
+	}
+
+	want := &RateLimits{
+		Core: &Rate{
+			Limit:     2,
+			Remaining: 1,
+			Reset:     Timestamp{time.Date(2013, time.July, 1, 17, 47, 53, 0, time.UTC).Local()},
+		},
+		Search: &Rate{
+			Limit:     3,
+			Remaining: 2,
+			Reset:     Timestamp{time.Date(2013, time.July, 1, 17, 47, 54, 0, time.UTC).Local()},
+		},
+	}
+	if !cmp.Equal(rate, want) {
+		t.Errorf("RateLimits returned %+v, want %+v", rate, want)
+	}
+
+	if got, want := client.rateLimits[coreCategory], *want.Core; got != want {
+		t.Errorf("client.rateLimits[coreCategory] is %+v, want %+v", got, want)
+	}
+	if got, want := client.rateLimits[searchCategory], *want.Search; got != want {
+		t.Errorf("client.rateLimits[searchCategory] is %+v, want %+v", got, want)
+	}
+}
+
 func TestSetCredentialsAsHeaders(t *testing.T) {
 	req := new(http.Request)
 	id, secret := "id", "secret"
@@ -1997,3 +2013,10 @@ func TestBareDo_returnsOpenBody(t *testing.T) {
 		t.Fatalf("resp.Body.Close() returned error: %v", err)
 	}
 }
+
+// roundTripperFunc creates a mock RoundTripper (transport)
+type roundTripperFunc func(*http.Request) (*http.Response, error)
+
+func (fn roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
+	return fn(r)
+}
diff --git a/github/messages_test.go b/github/messages_test.go
index a13e5a99..5fed4a2d 100644
--- a/github/messages_test.go
+++ b/github/messages_test.go
@@ -229,6 +229,33 @@ func TestValidatePayload_BadRequestBody(t *testing.T) {
 	}
 }
 
+func TestValidatePayload_InvalidContentTypeParams(t *testing.T) {
+	req, err := http.NewRequest("POST", "http://localhost/event", nil)
+	if err != nil {
+		t.Fatalf("NewRequest: %v", err)
+	}
+	req.Header.Set("Content-Type", "application/json; charset=")
+	if _, err = ValidatePayload(req, nil); err == nil {
+		t.Error("ValidatePayload = nil, want err")
+	}
+}
+
+func TestValidatePayload_ValidContentTypeParams(t *testing.T) {
+	var requestBody = `{"yo":true}`
+	buf := bytes.NewBufferString(requestBody)
+
+	req, err := http.NewRequest("POST", "http://localhost/event", buf)
+	if err != nil {
+		t.Fatalf("NewRequest: %v", err)
+	}
+	req.Header.Set("Content-Type", "application/json; charset=UTF-8")
+
+	_, err = ValidatePayload(req, nil)
+	if err != nil {
+		t.Error("ValidatePayload = nil, want err")
+	}
+}
+
 func TestParseWebHook(t *testing.T) {
 	tests := []struct {
 		payload     interface{}
diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go
index a5883332..c5874669 100644
--- a/github/repos_contents_test.go
+++ b/github/repos_contents_test.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -690,6 +691,15 @@ func TestRepositoriesService_GetArchiveLink(t *testing.T) {
 		_, _, err = client.Repositories.GetArchiveLink(ctx, "\n", "\n", Tarball, &RepositoryContentGetOptions{}, true)
 		return err
 	})
+
+	// Add custom round tripper
+	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
+		return nil, errors.New("failed to get archive link")
+	})
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.GetArchiveLink(ctx, "o", "r", Tarball, &RepositoryContentGetOptions{}, true)
+		return err
+	})
 }
 
 func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
diff --git a/github/repos_test.go b/github/repos_test.go
index 7e42229e..3e7eed3f 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -8,8 +8,10 @@ package github
 import (
 	"context"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"net/http"
+	"net/url"
 	"strings"
 	"testing"
 
@@ -886,7 +888,7 @@ func TestRepositoriesService_GetBranch(t *testing.T) {
 	})
 
 	ctx := context.Background()
-	branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b")
+	branch, _, err := client.Repositories.GetBranch(ctx, "o", "r", "b", false)
 	if err != nil {
 		t.Errorf("Repositories.GetBranch returned error: %v", err)
 	}
@@ -908,16 +910,74 @@ func TestRepositoriesService_GetBranch(t *testing.T) {
 
 	const methodName = "GetBranch"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n")
+		_, _, err = client.Repositories.GetBranch(ctx, "\n", "\n", "\n", false)
 		return err
 	})
+}
 
-	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
-		got, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b")
-		if got != nil {
-			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
-		}
-		return resp, err
+func TestRepositoriesService_GetBranch_StatusMovedPermanently_followRedirects(t *testing.T) {
+	client, mux, serverURL, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/repos/o/r/branches/br")
+		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
+	})
+	mux.HandleFunc("/repos/o/r/branches/br", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"name":"n", "commit":{"sha":"s","commit":{"message":"m"}}, "protected":true}`)
+	})
+	ctx := context.Background()
+	branch, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
+	if err != nil {
+		t.Errorf("Repositories.GetBranch returned error: %v", err)
+	}
+	if resp.StatusCode != http.StatusOK {
+		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusOK)
+	}
+
+	want := &Branch{
+		Name: String("n"),
+		Commit: &RepositoryCommit{
+			SHA: String("s"),
+			Commit: &Commit{
+				Message: String("m"),
+			},
+		},
+		Protected: Bool(true),
+	}
+	if !cmp.Equal(branch, want) {
+		t.Errorf("Repositories.GetBranch returned %+v, want %+v", branch, want)
+	}
+}
+
+func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		http.Error(w, "branch not found", http.StatusNotFound)
+	})
+	ctx := context.Background()
+	_, resp, err := client.Repositories.GetBranch(ctx, "o", "r", "b", true)
+	if err == nil {
+		t.Error("Repositories.GetBranch returned error: nil")
+	}
+	if resp.StatusCode != http.StatusNotFound {
+		t.Errorf("Repositories.GetBranch returned status: %d, want %d", resp.StatusCode, http.StatusNotFound)
+	}
+
+	// Add custom round tripper
+	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
+		return nil, errors.New("failed to get branch")
+	})
+
+	const methodName = "GetBranch"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.GetBranch(ctx, "o", "r", "b", true)
+		return err
 	})
 }
 
diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go
index bfc6657e..5bbd762f 100644
--- a/test/integration/repos_test.go
+++ b/test/integration/repos_test.go
@@ -70,7 +70,7 @@ func TestRepositories_BranchesTags(t *testing.T) {
 		t.Fatalf("Repositories.ListBranches('git', 'git') returned no branches")
 	}
 
-	_, _, err = client.Repositories.GetBranch(context.Background(), "git", "git", *branches[0].Name)
+	_, _, err = client.Repositories.GetBranch(context.Background(), "git", "git", *branches[0].Name, false)
 	if err != nil {
 		t.Fatalf("Repositories.GetBranch() returned error: %v", err)
 	}
@@ -102,7 +102,7 @@ func TestRepositories_EditBranches(t *testing.T) {
 		t.Fatalf("createRandomTestRepository returned error: %v", err)
 	}
 
-	branch, _, err := client.Repositories.GetBranch(context.Background(), *repo.Owner.Login, *repo.Name, "master")
+	branch, _, err := client.Repositories.GetBranch(context.Background(), *repo.Owner.Login, *repo.Name, "master", false)
 	if err != nil {
 		t.Fatalf("Repositories.GetBranch() returned error: %v", err)
 	}