From 84e6b4492b022162df545cf3ce59d110a5a03027 Mon Sep 17 00:00:00 2001 From: navarrano Date: Thu, 11 May 2017 00:13:53 +0200 Subject: [PATCH 1/7] [#617] Adds pull request reviews enforcement handling --- github/github-accessors.go | 8 +++ github/repos.go | 121 +++++++++++++++++++++++++++++++---- github/repos_test.go | 128 ++++++++++++++++++++++++++++++++++--- 3 files changed, 236 insertions(+), 21 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 082f755d5a3..ee033914039 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -4020,6 +4020,14 @@ func (p *PullRequestReviewRequest) GetEvent() string { return *p.Event } +// GetDismissStaleReviews returns the DismissStaleReviews field if it's non-nil, zero value otherwise. +func (p *PullRequestReviewsEnforcementPatchRequest) GetDismissStaleReviews() bool { + if p == nil || p.DismissStaleReviews == nil { + return false + } + return *p.DismissStaleReviews +} + // GetBase returns the Base field if it's non-nil, zero value otherwise. func (p *pullRequestUpdate) GetBase() string { if p == nil || p.Base == nil { diff --git a/github/repos.go b/github/repos.go index 41b72e3dc8b..c22e7c6ad53 100644 --- a/github/repos.go +++ b/github/repos.go @@ -509,18 +509,18 @@ type Branch struct { // Protection represents a repository branch's protection. type Protection struct { - RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` - RequiredPullRequestReviews *RequiredPullRequestReviews `json:"required_pull_request_reviews"` - EnforceAdmins *AdminEnforcement `json:"enforce_admins"` - Restrictions *BranchRestrictions `json:"restrictions"` + RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` + RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"` + EnforceAdmins *AdminEnforcement `json:"enforce_admins"` + Restrictions *BranchRestrictions `json:"restrictions"` } // ProtectionRequest represents a request to create/edit a branch's protection. type ProtectionRequest struct { - RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` - RequiredPullRequestReviews *RequiredPullRequestReviews `json:"required_pull_request_reviews"` - EnforceAdmins bool `json:"enforce_admins"` - Restrictions *BranchRestrictionsRequest `json:"restrictions"` + RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks"` + RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"` + EnforceAdmins bool `json:"enforce_admins"` + Restrictions *BranchRestrictionsRequest `json:"restrictions"` } // RequiredStatusChecks represents the protection status of a individual branch. @@ -535,11 +535,26 @@ type RequiredStatusChecks struct { Contexts []string `json:"contexts"` } -// RequiredPullRequestReviews represents the protection configuration for pull requests. -type RequiredPullRequestReviews struct { - // Enforce pull request reviews for repository administrators. (Required.) - // Deprecated: Use EnforceAdmins instead. - IncludeAdmins bool `json:"include_admins"` +// PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. +type PullRequestReviewsEnforcement struct { + DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions"` + DismissStaleReviews bool `json:"dismiss_stale_reviews"` +} + +// PullRequestReviewsEnforcementRequest represents request to set the pull request review +// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above +// because the request structure is different from the response structure. +type PullRequestReviewsEnforcementRequest struct { + DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"` + DismissStaleReviews bool `json:"dismiss_stale_reviews"` +} + +// PullRequestReviewsEnforcementPatchRequest represents request to patch the pull request review +// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementPatchRequest above +// because the patch request does not require all fields to be initialized. +type PullRequestReviewsEnforcementPatchRequest struct { + DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` + DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` } // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. @@ -568,6 +583,25 @@ type BranchRestrictionsRequest struct { Teams []string `json:"teams"` } +// DismissalRestrictions specifies which users and teams can dismiss pull request reviews. +type DismissalRestrictions struct { + // The list of users who can dimiss pull request reviews. + Users []*User `json:"users"` + // The list of teams which can dismiss pull request reviews. + Teams []*Team `json:"teams"` +} + +// DismissalRestrictionsRequest represents the request to create/edit the +// restriction to allows only specific users or teams to dimiss pull request reviews. It is +// separate from DismissalRestrictions above because the request structure is +// different from the response structure. +type DismissalRestrictionsRequest struct { + // The list of user logins who can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.) + Users []string `json:"users"` + // The list of team slugs which can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.) + Teams []string `json:"teams"` +} + // ListBranches lists branches for the specified repository. // // GitHub API docs: https://developer.github.com/v3/repos/#list-branches @@ -738,3 +772,64 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) ( return r, resp, nil } + +// GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch +func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + r := new(PullRequestReviewsEnforcement) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch. +// It requires admin access and branch protection to be enabled. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch +func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementPatchRequest) (*PullRequestReviewsEnforcement, *Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + req, err := s.client.NewRequest("PATCH", u, patch) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + r := new(PullRequestReviewsEnforcement) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, err +} + +// RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch +func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + return s.client.Do(ctx, req, nil) +} diff --git a/github/repos_test.go b/github/repos_test.go index 75204d82fdd..bdae7f30b82 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -482,7 +482,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"include_admins":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"u"}],"teams":[{"id":4,"slug":"t"}]},"dismiss_stale_reviews":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") @@ -496,8 +496,16 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { Strict: true, Contexts: []string{"continuous-integration"}, }, - RequiredPullRequestReviews: &RequiredPullRequestReviews{ - IncludeAdmins: true, + RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: &DismissalRestrictions{ + Users: []*User{ + {Login: String("u"), ID: Int(3)}, + }, + Teams: []*Team{ + {Slug: String("t"), ID: Int(4)}, + }, + }, }, EnforceAdmins: &AdminEnforcement{ URL: String("/repos/o/r/branches/b/protection/enforce_admins"), @@ -527,8 +535,12 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { Strict: true, Contexts: []string{"continuous-integration"}, }, - RequiredPullRequestReviews: &RequiredPullRequestReviews{ - IncludeAdmins: true, + RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ + DismissStaleReviews: true, + DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ + Users: []string{"uu"}, + Teams: []string{"tt"}, + }, }, Restrictions: &BranchRestrictionsRequest{ Users: []string{"u"}, @@ -545,7 +557,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { t.Errorf("Request body = %+v, want %+v", v, input) } testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"include_admins":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"uu"}],"teams":[{"id":4,"slug":"tt"}]},"dismiss_stale_reviews":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.UpdateBranchProtection(context.Background(), "o", "r", "b", input) @@ -559,8 +571,16 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { Strict: true, Contexts: []string{"continuous-integration"}, }, - RequiredPullRequestReviews: &RequiredPullRequestReviews{ - IncludeAdmins: true, + RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: &DismissalRestrictions{ + Users: []*User{ + {Login: String("uu"), ID: Int(3)}, + }, + Teams: []*Team{ + {Slug: String("tt"), ID: Int(4)}, + }, + }, }, Restrictions: &BranchRestrictions{ Users: []*User{ @@ -679,3 +699,95 @@ func TestRepositoriesService_ListRequiredStatusChecksContexts(t *testing.T) { t.Errorf("Repositories.ListRequiredStatusChecksContexts returned %+v, want %+v", contexts, want) } } + +func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true}`) + }) + + enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.GetPullRequestReviewEnforcement returned error: %v", err) + } + + want := &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: &DismissalRestrictions{ + Users: []*User{ + {Login: String("u"), ID: Int(1)}, + }, + Teams: []*Team{ + {Slug: String("t"), ID: Int(2)}, + }, + }, + } + + if !reflect.DeepEqual(enforcement, want) { + t.Errorf("Repositories.GetPullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) + } +} + +func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { + setup() + defer teardown() + + input := &PullRequestReviewsEnforcementPatchRequest{ + DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ + Users: []string{"u"}, + Teams: []string{"t"}, + }, + } + + mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { + v := new(PullRequestReviewsEnforcementPatchRequest) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true}`) + }) + + enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(context.Background(), "o", "r", "b", input) + if err != nil { + t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned error: %v", err) + } + + want := &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: &DismissalRestrictions{ + Users: []*User{ + {Login: String("u"), ID: Int(1)}, + }, + Teams: []*Team{ + {Slug: String("t"), ID: Int(2)}, + }, + }, + } + if !reflect.DeepEqual(enforcement, want) { + t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) + } +} + +func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Repositories.RemovePullRequestReviewEnforcement(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) + } +} From 6f90ac15924e0f500a3c439a3dcae21132bdabca Mon Sep 17 00:00:00 2001 From: navarrano Date: Thu, 11 May 2017 00:18:40 +0200 Subject: [PATCH 2/7] [#617] Removes IncludeAdmins --- github/repos.go | 3 --- github/repos_test.go | 26 +++++++++++--------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/github/repos.go b/github/repos.go index c22e7c6ad53..56a601b8816 100644 --- a/github/repos.go +++ b/github/repos.go @@ -525,9 +525,6 @@ type ProtectionRequest struct { // RequiredStatusChecks represents the protection status of a individual branch. type RequiredStatusChecks struct { - // Enforce required status checks for repository administrators. (Required.) - // Deprecated: Use EnforceAdmins instead. - IncludeAdmins bool `json:"include_admins"` // Require branches to be up to date before merging. (Required.) Strict bool `json:"strict"` // The list of status checks to require in order to merge into this diff --git a/github/repos_test.go b/github/repos_test.go index bdae7f30b82..d96ab4e7aa3 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -482,7 +482,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"u"}],"teams":[{"id":4,"slug":"t"}]},"dismiss_stale_reviews":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"u"}],"teams":[{"id":4,"slug":"t"}]},"dismiss_stale_reviews":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") @@ -492,9 +492,8 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { want := &Protection{ RequiredStatusChecks: &RequiredStatusChecks{ - IncludeAdmins: true, - Strict: true, - Contexts: []string{"continuous-integration"}, + Strict: true, + Contexts: []string{"continuous-integration"}, }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, @@ -531,9 +530,8 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { input := &ProtectionRequest{ RequiredStatusChecks: &RequiredStatusChecks{ - IncludeAdmins: true, - Strict: true, - Contexts: []string{"continuous-integration"}, + Strict: true, + Contexts: []string{"continuous-integration"}, }, RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{ DismissStaleReviews: true, @@ -557,7 +555,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { t.Errorf("Request body = %+v, want %+v", v, input) } testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"include_admins":true,"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"uu"}],"teams":[{"id":4,"slug":"tt"}]},"dismiss_stale_reviews":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"uu"}],"teams":[{"id":4,"slug":"tt"}]},"dismiss_stale_reviews":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.UpdateBranchProtection(context.Background(), "o", "r", "b", input) @@ -567,9 +565,8 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { want := &Protection{ RequiredStatusChecks: &RequiredStatusChecks{ - IncludeAdmins: true, - Strict: true, - Contexts: []string{"continuous-integration"}, + Strict: true, + Contexts: []string{"continuous-integration"}, }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, @@ -658,7 +655,7 @@ func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprint(w, `{"include_admins": true,"strict": true,"contexts": ["x","y","z"]}`) + fmt.Fprint(w, `{"strict": true,"contexts": ["x","y","z"]}`) }) checks, _, err := client.Repositories.GetRequiredStatusChecks(context.Background(), "o", "r", "b") @@ -667,9 +664,8 @@ func TestRepositoriesService_GetRequiredStatusChecks(t *testing.T) { } want := &RequiredStatusChecks{ - IncludeAdmins: true, - Strict: true, - Contexts: []string{"x", "y", "z"}, + Strict: true, + Contexts: []string{"x", "y", "z"}, } if !reflect.DeepEqual(checks, want) { t.Errorf("Repositories.GetRequiredStatusChecks returned %+v, want %+v", checks, want) From 3604ffbcfeab27303c7217d5e3f0a047b6e04fb3 Mon Sep 17 00:00:00 2001 From: navarrano Date: Thu, 11 May 2017 01:04:03 +0200 Subject: [PATCH 3/7] [#617] Adds AdminEnforcement API methods --- github/repos.go | 61 +++++++++++++++++++++++++++++++++++++++++ github/repos_test.go | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/github/repos.go b/github/repos.go index 56a601b8816..7635c55bca1 100644 --- a/github/repos.go +++ b/github/repos.go @@ -830,3 +830,64 @@ func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Con return s.client.Do(ctx, req, nil) } + +// GetAdminEnforcement gets admin enforcement information of a protected branch. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-enforcement-of-protected-branch +func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + r := new(AdminEnforcement) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// AddAdminEnforcement adds admin enforcement to a protected branch. +// It requires admin access and branch protection to be enabled. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch +func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + r := new(AdminEnforcement) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, err +} + +// RemoveAdminEnforcement removess admin enforcement from a protected branch. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch +func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + return s.client.Do(ctx, req, nil) +} diff --git a/github/repos_test.go b/github/repos_test.go index d96ab4e7aa3..fad1f4b69ca 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -787,3 +787,68 @@ func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { t.Errorf("Repositories.RemovePullRequestReviewEnforcement returned error: %v", err) } } + +func TestRepositoriesService_GetAdminEnforcement(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) + }) + + enforcement, _, err := client.Repositories.GetAdminEnforcement(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.GetAdminEnforcement returned error: %v", err) + } + + want := &AdminEnforcement{ + URL: String("/repos/o/r/branches/b/protection/enforce_admins"), + Enabled: true, + } + + if !reflect.DeepEqual(enforcement, want) { + t.Errorf("Repositories.GetAdminEnforcement returned %+v, want %+v", enforcement, want) + } +} + +func TestRepositoriesService_AddAdminEnforcement(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + fmt.Fprintf(w, `{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true}`) + }) + + enforcement, _, err := client.Repositories.AddAdminEnforcement(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.AddAdminEnforcement returned error: %v", err) + } + + want := &AdminEnforcement{ + URL: String("/repos/o/r/branches/b/protection/enforce_admins"), + Enabled: true, + } + if !reflect.DeepEqual(enforcement, want) { + t.Errorf("Repositories.AddAdminEnforcement returned %+v, want %+v", enforcement, want) + } +} + +func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/branches/b/protection/enforce_admins", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Repositories.RemoveAdminEnforcement(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) + } +} From 03116cda037d6bd31559f27c196a08f663332faf Mon Sep 17 00:00:00 2001 From: navarrano Date: Thu, 25 May 2017 10:42:42 +0200 Subject: [PATCH 4/7] Adds suggested pull request changes --- github/github-accessors.go | 2 +- github/repos.go | 50 ++++++++++++++++++++++++++++++-------- github/repos_test.go | 28 ++++++++++++++++----- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index ee033914039..a8e1683d51e 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -4021,7 +4021,7 @@ func (p *PullRequestReviewRequest) GetEvent() string { } // GetDismissStaleReviews returns the DismissStaleReviews field if it's non-nil, zero value otherwise. -func (p *PullRequestReviewsEnforcementPatchRequest) GetDismissStaleReviews() bool { +func (p *PullRequestReviewsEnforcementUpdate) GetDismissStaleReviews() bool { if p == nil || p.DismissStaleReviews == nil { return false } diff --git a/github/repos.go b/github/repos.go index 7635c55bca1..c99d91d2ca7 100644 --- a/github/repos.go +++ b/github/repos.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" "strings" ) @@ -534,24 +535,53 @@ type RequiredStatusChecks struct { // PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch. type PullRequestReviewsEnforcement struct { - DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions"` - DismissStaleReviews bool `json:"dismiss_stale_reviews"` + // Specifies which users and teams can dismiss pull requets reviews. + DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"` + // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. + DismissStaleReviews bool `json:"dismiss_stale_reviews"` } // PullRequestReviewsEnforcementRequest represents request to set the pull request review // enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above // because the request structure is different from the response structure. type PullRequestReviewsEnforcementRequest struct { + // Specifies which users and teams should be allowed to dismiss pull requets reviews. Can be nil to disable the restrictions. DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"` - DismissStaleReviews bool `json:"dismiss_stale_reviews"` -} - -// PullRequestReviewsEnforcementPatchRequest represents request to patch the pull request review -// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementPatchRequest above + // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) + DismissStaleReviews bool `json:"dismiss_stale_reviews"` +} + +// MarshalJSON implements the json.Marshaler interface. +// Converts nil value of PullRequestReviewsEnforcementRequest.DismissalRestrictionsRequest to empty array +func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) { + if req.DismissalRestrictionsRequest == nil { + newReq := struct { + R []bool `json:"dismissal_restrictions"` + D bool `json:"dismiss_stale_reviews"` + }{ + R: []bool{}, + D: req.DismissStaleReviews, + } + return json.Marshal(newReq) + } + newReq := struct { + R *DismissalRestrictionsRequest `json:"dismissal_restrictions"` + D bool `json:"dismiss_stale_reviews"` + }{ + R: req.DismissalRestrictionsRequest, + D: req.DismissStaleReviews, + } + return json.Marshal(newReq) +} + +// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review +// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementUpdate above // because the patch request does not require all fields to be initialized. -type PullRequestReviewsEnforcementPatchRequest struct { +type PullRequestReviewsEnforcementUpdate struct { + // Specifies which users and teams can dismiss pull requets reviews. Can be ommitted. DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` - DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` + // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be ommited. + DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` } // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. @@ -796,7 +826,7 @@ func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Contex // It requires admin access and branch protection to be enabled. // // GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch -func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementPatchRequest) (*PullRequestReviewsEnforcement, *Response, error) { +func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, patch) if err != nil { diff --git a/github/repos_test.go b/github/repos_test.go index fad1f4b69ca..54530026db3 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -497,7 +497,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: &DismissalRestrictions{ + DismissalRestrictions: DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int(3)}, }, @@ -570,7 +570,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { }, RequiredPullRequestReviews: &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: &DismissalRestrictions{ + DismissalRestrictions: DismissalRestrictions{ Users: []*User{ {Login: String("uu"), ID: Int(3)}, }, @@ -713,7 +713,7 @@ func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { want := &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: &DismissalRestrictions{ + DismissalRestrictions: DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int(1)}, }, @@ -732,7 +732,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { setup() defer teardown() - input := &PullRequestReviewsEnforcementPatchRequest{ + input := &PullRequestReviewsEnforcementUpdate{ DismissalRestrictionsRequest: &DismissalRestrictionsRequest{ Users: []string{"u"}, Teams: []string{"t"}, @@ -740,7 +740,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { } mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { - v := new(PullRequestReviewsEnforcementPatchRequest) + v := new(PullRequestReviewsEnforcementUpdate) json.NewDecoder(r.Body).Decode(v) testMethod(t, r, "PATCH") @@ -758,7 +758,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { want := &PullRequestReviewsEnforcement{ DismissStaleReviews: true, - DismissalRestrictions: &DismissalRestrictions{ + DismissalRestrictions: DismissalRestrictions{ Users: []*User{ {Login: String("u"), ID: Int(1)}, }, @@ -852,3 +852,19 @@ func TestRepositoriesService_RemoveAdminEnforcement(t *testing.T) { t.Errorf("Repositories.RemoveAdminEnforcement returned error: %v", err) } } + +func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctions(t *testing.T) { + req := PullRequestReviewsEnforcementRequest{} + + json, err := json.Marshal(req) + + if err != nil { + t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) + } + + want := `{"dismissal_restrictions":[],"dismiss_stale_reviews":false}` + + if want != string(json) { + t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(json), want) + } +} From f1e6a0dae19f5642e6426c642aa415d7837c4858 Mon Sep 17 00:00:00 2001 From: navarrano Date: Thu, 25 May 2017 21:41:46 +0200 Subject: [PATCH 5/7] Adds disable dismissal restrictions API method --- github/repos.go | 34 +++++++++++++++++++++++++++++++--- github/repos_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/github/repos.go b/github/repos.go index c99d91d2ca7..997cf2f6730 100644 --- a/github/repos.go +++ b/github/repos.go @@ -556,10 +556,10 @@ type PullRequestReviewsEnforcementRequest struct { func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) { if req.DismissalRestrictionsRequest == nil { newReq := struct { - R []bool `json:"dismissal_restrictions"` - D bool `json:"dismiss_stale_reviews"` + R []interface{} `json:"dismissal_restrictions"` + D bool `json:"dismiss_stale_reviews"` }{ - R: []bool{}, + R: []interface{}{}, D: req.DismissStaleReviews, } return json.Marshal(newReq) @@ -845,6 +845,34 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con return r, resp, err } +// DisableDismissalRestrictions disables dismissal restrictions of a protected branch. +// It requires admin access and branch protection to be enabled. +// +// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch +func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { + u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + + data := struct { + R []interface{} `json:"dismissal_restrictions"` + }{[]interface{}{}} + + req, err := s.client.NewRequest("PATCH", u, data) + if err != nil { + return nil, nil, err + } + + // TODO: remove custom Accept header when this API fully launches + req.Header.Set("Accept", mediaTypeProtectedBranchesPreview) + + r := new(PullRequestReviewsEnforcement) + resp, err := s.client.Do(ctx, req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, err +} + // RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch. // // GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch diff --git a/github/repos_test.go b/github/repos_test.go index 54530026db3..295ed1966f9 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -6,6 +6,7 @@ package github import ( + "bytes" "context" "encoding/json" "fmt" @@ -772,6 +773,43 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { } } +func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { + setup() + defer teardown() + + wantBody := `{"dismissal_restrictions":[]}` + + mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) + + buf := new(bytes.Buffer) + buf.ReadFrom(r.Body) + body := strings.TrimSpace(buf.String()) + if wantBody != body { + t.Errorf("Request body = %+v, want %+v", body, wantBody) + } + + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true}`) + }) + + enforcement, _, err := client.Repositories.DisableDismissalRestrictions(context.Background(), "o", "r", "b") + if err != nil { + t.Errorf("Repositories.DisableDismissalRestrictions returned error: %v", err) + } + + want := &PullRequestReviewsEnforcement{ + DismissStaleReviews: true, + DismissalRestrictions: DismissalRestrictions{ + Users: []*User{}, + Teams: []*Team{}, + }, + } + if !reflect.DeepEqual(enforcement, want) { + t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) + } +} + func TestRepositoriesService_RemovePullRequestReviewEnforcement(t *testing.T) { setup() defer teardown() From 9cc75dc52c8b3c5aea7727b7b97c9c56090611fe Mon Sep 17 00:00:00 2001 From: navarrano Date: Sat, 3 Jun 2017 00:34:30 +0200 Subject: [PATCH 6/7] Removes redudant initial slash from requests repos. Adds small fixes --- github/repos.go | 16 ++++++++-------- github/repos_test.go | 14 +------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/github/repos.go b/github/repos.go index 997cf2f6730..117d22252d2 100644 --- a/github/repos.go +++ b/github/repos.go @@ -575,7 +575,7 @@ func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) { } // PullRequestReviewsEnforcementUpdate represents request to patch the pull request review -// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementUpdate above +// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above // because the patch request does not require all fields to be initialized. type PullRequestReviewsEnforcementUpdate struct { // Specifies which users and teams can dismiss pull requets reviews. Can be ommitted. @@ -804,7 +804,7 @@ func (s *RepositoriesService) License(ctx context.Context, owner, repo string) ( // // GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -827,7 +827,7 @@ func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Contex // // GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("PATCH", u, patch) if err != nil { return nil, nil, err @@ -850,7 +850,7 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con // // GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) data := struct { R []interface{} `json:"dismissal_restrictions"` @@ -877,7 +877,7 @@ func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, // // GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -893,7 +893,7 @@ func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Con // // GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-enforcement-of-protected-branch func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -916,7 +916,7 @@ func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, re // // GitHub API docs: https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, nil, err @@ -938,7 +938,7 @@ func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, re // // GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) { - u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) + u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err diff --git a/github/repos_test.go b/github/repos_test.go index 295ed1966f9..b37d482b6f3 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -6,7 +6,6 @@ package github import ( - "bytes" "context" "encoding/json" "fmt" @@ -777,19 +776,10 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { setup() defer teardown() - wantBody := `{"dismissal_restrictions":[]}` - mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - - buf := new(bytes.Buffer) - buf.ReadFrom(r.Body) - body := strings.TrimSpace(buf.String()) - if wantBody != body { - t.Errorf("Request body = %+v, want %+v", body, wantBody) - } - + testBody(t, r, `{"dismissal_restrictions":[]}`+"\n") fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true}`) }) @@ -895,13 +885,11 @@ func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctio req := PullRequestReviewsEnforcementRequest{} json, err := json.Marshal(req) - if err != nil { t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) } want := `{"dismissal_restrictions":[],"dismiss_stale_reviews":false}` - if want != string(json) { t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(json), want) } From 01a20edc8d210c7c42b96e779e54e651f59948ff Mon Sep 17 00:00:00 2001 From: navarrano Date: Sat, 3 Jun 2017 10:47:11 +0200 Subject: [PATCH 7/7] Fixes typo in RemoveAdminEnforcement documentation --- github/repos.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/repos.go b/github/repos.go index 117d22252d2..632a1ea1225 100644 --- a/github/repos.go +++ b/github/repos.go @@ -934,7 +934,7 @@ func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, re return r, resp, err } -// RemoveAdminEnforcement removess admin enforcement from a protected branch. +// RemoveAdminEnforcement removes admin enforcement from a protected branch. // // GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) {