diff --git a/github/github-accessors.go b/github/github-accessors.go index 25587473e22..cb4244a2a6c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -38198,6 +38198,70 @@ func (r *RuleCodeScanningTool) GetTool() string { return r.Tool } +// GetDetails returns the Details field if it's non-nil, zero value otherwise. +func (r *RuleEvaluation) GetDetails() string { + if r == nil || r.Details == nil { + return "" + } + return *r.Details +} + +// GetEnforcement returns the Enforcement field if it's non-nil, zero value otherwise. +func (r *RuleEvaluation) GetEnforcement() string { + if r == nil || r.Enforcement == nil { + return "" + } + return *r.Enforcement +} + +// GetResult returns the Result field if it's non-nil, zero value otherwise. +func (r *RuleEvaluation) GetResult() string { + if r == nil || r.Result == nil { + return "" + } + return *r.Result +} + +// GetRuleSource returns the RuleSource field. +func (r *RuleEvaluation) GetRuleSource() *RuleEvaluationSource { + if r == nil { + return nil + } + return r.RuleSource +} + +// GetRuleType returns the RuleType field if it's non-nil, zero value otherwise. +func (r *RuleEvaluation) GetRuleType() string { + if r == nil || r.RuleType == nil { + return "" + } + return *r.RuleType +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (r *RuleEvaluationSource) GetID() int64 { + if r == nil || r.ID == nil { + return 0 + } + return *r.ID +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (r *RuleEvaluationSource) GetName() string { + if r == nil || r.Name == nil { + return "" + } + return *r.Name +} + +// GetType returns the Type field if it's non-nil, zero value otherwise. +func (r *RuleEvaluationSource) GetType() string { + if r == nil || r.Type == nil { + return "" + } + return *r.Type +} + // GetFilePatterns returns the FilePatterns slice if it's non-nil, nil otherwise. func (r *RulesetRequiredReviewer) GetFilePatterns() []string { if r == nil || r.FilePatterns == nil { @@ -38254,6 +38318,102 @@ func (r *RuleStatusCheck) GetIntegrationID() int64 { return *r.IntegrationID } +// GetActorID returns the ActorID field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetActorID() int64 { + if r == nil || r.ActorID == nil { + return 0 + } + return *r.ActorID +} + +// GetActorName returns the ActorName field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetActorName() string { + if r == nil || r.ActorName == nil { + return "" + } + return *r.ActorName +} + +// GetAfterSHA returns the AfterSHA field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetAfterSHA() string { + if r == nil || r.AfterSHA == nil { + return "" + } + return *r.AfterSHA +} + +// GetBeforeSHA returns the BeforeSHA field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetBeforeSHA() string { + if r == nil || r.BeforeSHA == nil { + return "" + } + return *r.BeforeSHA +} + +// GetEvaluationResult returns the EvaluationResult field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetEvaluationResult() string { + if r == nil || r.EvaluationResult == nil { + return "" + } + return *r.EvaluationResult +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetID() int64 { + if r == nil || r.ID == nil { + return 0 + } + return *r.ID +} + +// GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetPushedAt() Timestamp { + if r == nil || r.PushedAt == nil { + return Timestamp{} + } + return *r.PushedAt +} + +// GetRef returns the Ref field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetRef() string { + if r == nil || r.Ref == nil { + return "" + } + return *r.Ref +} + +// GetRepositoryID returns the RepositoryID field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetRepositoryID() int64 { + if r == nil || r.RepositoryID == nil { + return 0 + } + return *r.RepositoryID +} + +// GetRepositoryName returns the RepositoryName field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetRepositoryName() string { + if r == nil || r.RepositoryName == nil { + return "" + } + return *r.RepositoryName +} + +// GetResult returns the Result field if it's non-nil, zero value otherwise. +func (r *RuleSuite) GetResult() string { + if r == nil || r.Result == nil { + return "" + } + return *r.Result +} + +// GetRuleEvaluations returns the RuleEvaluations slice if it's non-nil, nil otherwise. +func (r *RuleSuite) GetRuleEvaluations() []*RuleEvaluation { + if r == nil || r.RuleEvaluations == nil { + return nil + } + return r.RuleEvaluations +} + // GetPath returns the Path field. func (r *RuleWorkflow) GetPath() string { if r == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 9d8632a71d8..922f65b3b12 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -47790,6 +47790,91 @@ func TestRuleCodeScanningTool_GetTool(tt *testing.T) { r.GetTool() } +func TestRuleEvaluation_GetDetails(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluation{Details: &zeroValue} + r.GetDetails() + r = &RuleEvaluation{} + r.GetDetails() + r = nil + r.GetDetails() +} + +func TestRuleEvaluation_GetEnforcement(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluation{Enforcement: &zeroValue} + r.GetEnforcement() + r = &RuleEvaluation{} + r.GetEnforcement() + r = nil + r.GetEnforcement() +} + +func TestRuleEvaluation_GetResult(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluation{Result: &zeroValue} + r.GetResult() + r = &RuleEvaluation{} + r.GetResult() + r = nil + r.GetResult() +} + +func TestRuleEvaluation_GetRuleSource(tt *testing.T) { + tt.Parallel() + r := &RuleEvaluation{} + r.GetRuleSource() + r = nil + r.GetRuleSource() +} + +func TestRuleEvaluation_GetRuleType(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluation{RuleType: &zeroValue} + r.GetRuleType() + r = &RuleEvaluation{} + r.GetRuleType() + r = nil + r.GetRuleType() +} + +func TestRuleEvaluationSource_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + r := &RuleEvaluationSource{ID: &zeroValue} + r.GetID() + r = &RuleEvaluationSource{} + r.GetID() + r = nil + r.GetID() +} + +func TestRuleEvaluationSource_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluationSource{Name: &zeroValue} + r.GetName() + r = &RuleEvaluationSource{} + r.GetName() + r = nil + r.GetName() +} + +func TestRuleEvaluationSource_GetType(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleEvaluationSource{Type: &zeroValue} + r.GetType() + r = &RuleEvaluationSource{} + r.GetType() + r = nil + r.GetType() +} + func TestRulesetRequiredReviewer_GetFilePatterns(tt *testing.T) { tt.Parallel() zeroValue := []string{} @@ -47858,6 +47943,138 @@ func TestRuleStatusCheck_GetIntegrationID(tt *testing.T) { r.GetIntegrationID() } +func TestRuleSuite_GetActorID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + r := &RuleSuite{ActorID: &zeroValue} + r.GetActorID() + r = &RuleSuite{} + r.GetActorID() + r = nil + r.GetActorID() +} + +func TestRuleSuite_GetActorName(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{ActorName: &zeroValue} + r.GetActorName() + r = &RuleSuite{} + r.GetActorName() + r = nil + r.GetActorName() +} + +func TestRuleSuite_GetAfterSHA(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{AfterSHA: &zeroValue} + r.GetAfterSHA() + r = &RuleSuite{} + r.GetAfterSHA() + r = nil + r.GetAfterSHA() +} + +func TestRuleSuite_GetBeforeSHA(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{BeforeSHA: &zeroValue} + r.GetBeforeSHA() + r = &RuleSuite{} + r.GetBeforeSHA() + r = nil + r.GetBeforeSHA() +} + +func TestRuleSuite_GetEvaluationResult(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{EvaluationResult: &zeroValue} + r.GetEvaluationResult() + r = &RuleSuite{} + r.GetEvaluationResult() + r = nil + r.GetEvaluationResult() +} + +func TestRuleSuite_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + r := &RuleSuite{ID: &zeroValue} + r.GetID() + r = &RuleSuite{} + r.GetID() + r = nil + r.GetID() +} + +func TestRuleSuite_GetPushedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + r := &RuleSuite{PushedAt: &zeroValue} + r.GetPushedAt() + r = &RuleSuite{} + r.GetPushedAt() + r = nil + r.GetPushedAt() +} + +func TestRuleSuite_GetRef(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{Ref: &zeroValue} + r.GetRef() + r = &RuleSuite{} + r.GetRef() + r = nil + r.GetRef() +} + +func TestRuleSuite_GetRepositoryID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + r := &RuleSuite{RepositoryID: &zeroValue} + r.GetRepositoryID() + r = &RuleSuite{} + r.GetRepositoryID() + r = nil + r.GetRepositoryID() +} + +func TestRuleSuite_GetRepositoryName(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{RepositoryName: &zeroValue} + r.GetRepositoryName() + r = &RuleSuite{} + r.GetRepositoryName() + r = nil + r.GetRepositoryName() +} + +func TestRuleSuite_GetResult(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RuleSuite{Result: &zeroValue} + r.GetResult() + r = &RuleSuite{} + r.GetResult() + r = nil + r.GetResult() +} + +func TestRuleSuite_GetRuleEvaluations(tt *testing.T) { + tt.Parallel() + zeroValue := []*RuleEvaluation{} + r := &RuleSuite{RuleEvaluations: zeroValue} + r.GetRuleEvaluations() + r = &RuleSuite{} + r.GetRuleEvaluations() + r = nil + r.GetRuleEvaluations() +} + func TestRuleWorkflow_GetPath(tt *testing.T) { tt.Parallel() r := &RuleWorkflow{} diff --git a/github/github-iterators.go b/github/github-iterators.go index 6be130a1ec1..49ffa9b60ae 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -4770,6 +4770,37 @@ func (s *OrganizationsService) ListOrgMembershipsIter(ctx context.Context, opts } } +// ListOrganizationRuleSuitesIter returns an iterator that paginates through all results of ListOrganizationRuleSuites. +func (s *OrganizationsService) ListOrganizationRuleSuitesIter(ctx context.Context, org string, opts *ListOptions) iter.Seq2[*RuleSuite, error] { + return func(yield func(*RuleSuite, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &ListOptions{} + } else { + opts = Ptr(*opts) + } + + for { + results, resp, err := s.ListOrganizationRuleSuites(ctx, org, opts) + if err != nil { + yield(nil, err) + return + } + + for _, item := range results { + if !yield(item, nil) { + return + } + } + + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + } +} + // ListOutsideCollaboratorsIter returns an iterator that paginates through all results of ListOutsideCollaborators. func (s *OrganizationsService) ListOutsideCollaboratorsIter(ctx context.Context, org string, opts *ListOutsideCollaboratorsOptions) iter.Seq2[*User, error] { return func(yield func(*User, error) bool) { diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 00ea4167da9..f2f1577d18e 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -10455,6 +10455,78 @@ func TestOrganizationsService_ListOrgMembershipsIter(t *testing.T) { } } +func TestOrganizationsService_ListOrganizationRuleSuitesIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `[{},{},{}]`) + case 2: + fmt.Fprint(w, `[{},{},{},{}]`) + case 3: + fmt.Fprint(w, `[{},{}]`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `[{},{}]`) + } + }) + + iter := client.Organizations.ListOrganizationRuleSuitesIter(t.Context(), "", nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.Organizations.ListOrganizationRuleSuitesIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &ListOptions{} + iter = client.Organizations.ListOrganizationRuleSuitesIter(t.Context(), "", opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.Organizations.ListOrganizationRuleSuitesIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.Organizations.ListOrganizationRuleSuitesIter(t.Context(), "", nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.Organizations.ListOrganizationRuleSuitesIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.Organizations.ListOrganizationRuleSuitesIter(t.Context(), "", nil) + gotItems = 0 + iter(func(item *RuleSuite, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.Organizations.ListOrganizationRuleSuitesIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestOrganizationsService_ListOutsideCollaboratorsIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/orgs_rulesuites.go b/github/orgs_rulesuites.go new file mode 100644 index 00000000000..f1018b750e8 --- /dev/null +++ b/github/orgs_rulesuites.go @@ -0,0 +1,92 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// RuleSuite represents a GitHub rule suite object returned by the rule-suites API. +type RuleSuite struct { + ID *int64 `json:"id,omitempty"` + ActorID *int64 `json:"actor_id,omitempty"` + ActorName *string `json:"actor_name,omitempty"` + BeforeSHA *string `json:"before_sha,omitempty"` + AfterSHA *string `json:"after_sha,omitempty"` + Ref *string `json:"ref,omitempty"` + RepositoryID *int64 `json:"repository_id,omitempty"` + RepositoryName *string `json:"repository_name,omitempty"` + PushedAt *Timestamp `json:"pushed_at,omitempty"` + Result *string `json:"result,omitempty"` + EvaluationResult *string `json:"evaluation_result,omitempty"` + RuleEvaluations []*RuleEvaluation `json:"rule_evaluations,omitempty"` +} + +// RuleEvaluation represents the result of evaluating a single rule within a suite. +type RuleEvaluation struct { + RuleSource *RuleEvaluationSource `json:"rule_source,omitempty"` + Enforcement *string `json:"enforcement,omitempty"` + Result *string `json:"result,omitempty"` + RuleType *string `json:"rule_type,omitempty"` + Details *string `json:"details,omitempty"` +} + +// RuleEvaluationSource identifies where a rule came from (ruleset, protected_branch, etc.). +type RuleEvaluationSource struct { + Type *string `json:"type,omitempty"` + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +// ListOrganizationRuleSuites lists rule suites for the specified organization. +// +// GitHub API docs: https://docs.github.com/rest/orgs/rule-suites?apiVersion=2022-11-28#list-organization-rule-suites +// +//meta:operation GET /orgs/{org}/rulesets/rule-suites +func (s *OrganizationsService) ListOrganizationRuleSuites(ctx context.Context, org string, opts *ListOptions) ([]*RuleSuite, *Response, error) { + endpoint := fmt.Sprintf("orgs/%v/rulesets/rule-suites", org) + + u, err := addOptions(endpoint, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var suites []*RuleSuite + resp, err := s.client.Do(req, &suites) + if err != nil { + return nil, resp, err + } + + return suites, resp, nil +} + +// GetOrganizationRuleSuite gets a single rule suite for the specified organization. +// +// GitHub API docs: https://docs.github.com/rest/orgs/rule-suites?apiVersion=2022-11-28#get-an-organization-rule-suite +// +//meta:operation GET /orgs/{org}/rulesets/rule-suites/{rule_suite_id} +func (s *OrganizationsService) GetOrganizationRuleSuite(ctx context.Context, org string, ruleSuiteID int64) (*RuleSuite, *Response, error) { + endpoint := fmt.Sprintf("orgs/%v/rulesets/rule-suites/%v", org, ruleSuiteID) + + req, err := s.client.NewRequest(ctx, "GET", endpoint, nil) + if err != nil { + return nil, nil, err + } + + var suite *RuleSuite + resp, err := s.client.Do(req, &suite) + if err != nil { + return nil, resp, err + } + + return suite, resp, nil +} diff --git a/github/orgs_rulesuites_test.go b/github/orgs_rulesuites_test.go new file mode 100644 index 00000000000..77fe0c6ff2a --- /dev/null +++ b/github/orgs_rulesuites_test.go @@ -0,0 +1,202 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/google/go-cmp/cmp" +) + +func TestOrganizationsService_ListOrganizationRuleSuites(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/rulesets/rule-suites", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[ + { + "id": 101, + "actor_id": 12, + "actor_name": "octocat", + "before_sha": "abc123", + "after_sha": "def456", + "ref": "refs/heads/main", + "repository_id": 1, + "repository_name": "repo", + "pushed_at": "2023-07-06T08:43:03Z", + "result": "bypass" + } + ]`) + }) + + ctx := t.Context() + suites, _, err := client.Organizations.ListOrganizationRuleSuites(ctx, "o", nil) + if err != nil { + t.Errorf("Organizations.ListOrganizationRuleSuites returned error: %v", err) + } + + want := []*RuleSuite{{ + ID: Ptr(int64(101)), + ActorID: Ptr(int64(12)), + ActorName: Ptr("octocat"), + BeforeSHA: Ptr("abc123"), + AfterSHA: Ptr("def456"), + Ref: Ptr("refs/heads/main"), + RepositoryID: Ptr(int64(1)), + RepositoryName: Ptr("repo"), + PushedAt: Ptr(Timestamp{time.Date(2023, time.July, 6, 8, 43, 3, 0, time.UTC)}), + Result: Ptr("bypass"), + }} + + if !cmp.Equal(suites, want) { + t.Errorf("Organizations.ListOrganizationRuleSuites returned %+v, want %+v", suites, want) + } + + const methodName = "ListOrganizationRuleSuites" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.ListOrganizationRuleSuites(ctx, "o", nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestOrganizationsService_ListOrganizationRuleSuites_ListOptions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/rulesets/rule-suites", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "page": "2", + "per_page": "35", + }) + fmt.Fprint(w, `[ + { + "id": 201, + "actor_id": 13, + "actor_name": "alice", + "before_sha": "aaa111", + "after_sha": "bbb222", + "ref": "refs/heads/feature", + "repository_id": 2, + "repository_name": "repo2", + "pushed_at": "2023-07-07T08:43:03Z", + "result": "pass" + } + ]`) + }) + + opts := &ListOptions{Page: 2, PerPage: 35} + ctx := t.Context() + suites, _, err := client.Organizations.ListOrganizationRuleSuites(ctx, "o", opts) + if err != nil { + t.Errorf("Organizations.ListOrganizationRuleSuites returned error: %v", err) + } + + want := []*RuleSuite{{ + ID: Ptr(int64(201)), + ActorID: Ptr(int64(13)), + ActorName: Ptr("alice"), + BeforeSHA: Ptr("aaa111"), + AfterSHA: Ptr("bbb222"), + Ref: Ptr("refs/heads/feature"), + RepositoryID: Ptr(int64(2)), + RepositoryName: Ptr("repo2"), + PushedAt: Ptr(Timestamp{time.Date(2023, time.July, 7, 8, 43, 3, 0, time.UTC)}), + Result: Ptr("pass"), + }} + + if !cmp.Equal(suites, want) { + t.Errorf("Organizations.ListOrganizationRuleSuites returned %+v, want %+v", suites, want) + } +} + +func TestOrganizationsService_ListOrganizationRuleSuites_addOptionsError(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.Organizations.ListOrganizationRuleSuites(t.Context(), "\u007F", &ListOptions{}) + if err == nil { + t.Fatal("Organizations.ListOrganizationRuleSuites returned nil error, want non-nil") + } +} + +func TestOrganizationsService_GetOrganizationRuleSuite(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/rulesets/rule-suites/101", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id": 101, + "actor_id": 12, + "actor_name": "octocat", + "before_sha": "abc123", + "after_sha": "def456", + "ref": "refs/heads/main", + "repository_id": 1, + "repository_name": "repo", + "pushed_at": "2023-07-06T08:43:03Z", + "result": "pass", + "evaluation_result": "fail", + "rule_evaluations": [ + { + "rule_source": {"type": "ruleset", "id": 3, "name": "Evaluate commit message pattern"}, + "enforcement": "evaluate", + "result": "fail", + "rule_type": "commit_message_pattern", + "details": "pattern did not match" + } + ] + }`) + }) + + ctx := t.Context() + suite, _, err := client.Organizations.GetOrganizationRuleSuite(ctx, "o", 101) + if err != nil { + t.Errorf("Organizations.GetOrganizationRuleSuite returned error: %v", err) + } + + want := &RuleSuite{ + ID: Ptr(int64(101)), + ActorID: Ptr(int64(12)), + ActorName: Ptr("octocat"), + BeforeSHA: Ptr("abc123"), + AfterSHA: Ptr("def456"), + Ref: Ptr("refs/heads/main"), + RepositoryID: Ptr(int64(1)), + RepositoryName: Ptr("repo"), + PushedAt: Ptr(Timestamp{time.Date(2023, time.July, 6, 8, 43, 3, 0, time.UTC)}), + Result: Ptr("pass"), + EvaluationResult: Ptr("fail"), + RuleEvaluations: []*RuleEvaluation{{ + RuleSource: &RuleEvaluationSource{Type: Ptr("ruleset"), ID: Ptr(int64(3)), Name: Ptr("Evaluate commit message pattern")}, + Enforcement: Ptr("evaluate"), + Result: Ptr("fail"), + RuleType: Ptr("commit_message_pattern"), + Details: Ptr("pattern did not match"), + }}, + } + + if !cmp.Equal(suite, want) { + t.Errorf("Organizations.GetOrganizationRuleSuite returned %+v, want %+v", suite, want) + } + + const methodName = "GetOrganizationRuleSuite" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.GetOrganizationRuleSuite(ctx, "o", 101) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +}