github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/plugins/reward-owners/reward-owners_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package rewardowners
    18  
    19  import (
    20  	"testing"
    21  
    22  	"sigs.k8s.io/prow/pkg/github/fakegithub"
    23  
    24  	"k8s.io/apimachinery/pkg/util/sets"
    25  	"sigs.k8s.io/prow/pkg/layeredsets"
    26  
    27  	"sigs.k8s.io/prow/pkg/plugins/ownersconfig"
    28  	"sigs.k8s.io/prow/pkg/repoowners"
    29  
    30  	"github.com/sirupsen/logrus"
    31  	"sigs.k8s.io/prow/pkg/git/localgit"
    32  	"sigs.k8s.io/prow/pkg/github"
    33  )
    34  
    35  type fakeOwnersClient struct{}
    36  
    37  func (f *fakeOwnersClient) LoadRepoOwnersSha(org, repo, base, sha string, updateCache bool) (repoowners.RepoOwner, error) {
    38  	return &fakeRepoOwners{sha: sha}, nil
    39  }
    40  
    41  type fakeRepoOwners struct {
    42  	sha string
    43  }
    44  
    45  func (f *fakeRepoOwners) Filenames() ownersconfig.Filenames               { return ownersconfig.Filenames{} }
    46  func (f *fakeRepoOwners) FindApproverOwnersForFile(path string) string    { return "" }
    47  func (f *fakeRepoOwners) FindReviewersOwnersForFile(path string) string   { return "" }
    48  func (f *fakeRepoOwners) FindLabelsForFile(path string) sets.Set[string]  { return nil }
    49  func (f *fakeRepoOwners) IsNoParentOwners(path string) bool               { return false }
    50  func (f *fakeRepoOwners) IsAutoApproveUnownedSubfolders(path string) bool { return false }
    51  func (f *fakeRepoOwners) LeafApprovers(path string) sets.Set[string]      { return nil }
    52  func (f *fakeRepoOwners) Approvers(path string) layeredsets.String        { return layeredsets.String{} }
    53  func (f *fakeRepoOwners) LeafReviewers(path string) sets.Set[string]      { return nil }
    54  func (f *fakeRepoOwners) ParseSimpleConfig(path string) (repoowners.SimpleConfig, error) {
    55  	return repoowners.SimpleConfig{}, nil
    56  }
    57  func (f *fakeRepoOwners) ParseFullConfig(path string) (repoowners.FullConfig, error) {
    58  	return repoowners.FullConfig{}, nil
    59  }
    60  func (f *fakeRepoOwners) Reviewers(path string) layeredsets.String       { return layeredsets.String{} }
    61  func (f *fakeRepoOwners) RequiredReviewers(path string) sets.Set[string] { return nil }
    62  func (f *fakeRepoOwners) TopLevelApprovers() sets.Set[string]            { return nil }
    63  
    64  func (f *fakeRepoOwners) AllApprovers() sets.Set[string] {
    65  	return ownersBySha[f.sha]
    66  }
    67  
    68  func (f *fakeRepoOwners) AllOwners() sets.Set[string] {
    69  	return ownersBySha[f.sha]
    70  }
    71  
    72  func (f *fakeRepoOwners) AllReviewers() sets.Set[string] {
    73  	return ownersBySha[f.sha]
    74  }
    75  
    76  var ownersBySha = map[string]sets.Set[string]{
    77  	"base":         sets.New[string]("alice", "bob"),
    78  	"add cole":     sets.New[string]("alice", "bob", "cole"),
    79  	"remove alice": sets.New[string]("bob"),
    80  }
    81  
    82  func makeChanges(files []string) map[string]string {
    83  	changes := make(map[string]string, len(files))
    84  	for _, f := range files {
    85  		changes[f] = "foo"
    86  	}
    87  	return changes
    88  }
    89  
    90  func newFakeGitHubClient(changed map[string]string, pr int) *fakegithub.FakeClient {
    91  	var changes []github.PullRequestChange
    92  	for file, patch := range changed {
    93  		changes = append(changes, github.PullRequestChange{Filename: file, Patch: patch})
    94  	}
    95  	return &fakegithub.FakeClient{
    96  		PullRequestChanges: map[int][]github.PullRequestChange{pr: changes},
    97  		Reviews:            map[int][]github.Review{},
    98  		Collaborators:      []string{"alice", "bob", "jdoe"},
    99  		IssueComments:      map[int][]github.IssueComment{},
   100  	}
   101  }
   102  
   103  func TestHandleV2(t *testing.T) {
   104  	testHandle(localgit.NewV2, t)
   105  }
   106  
   107  func testHandle(clients localgit.Clients, t *testing.T) {
   108  	var tests = []struct {
   109  		name          string
   110  		filesChanged  []string
   111  		sha           string
   112  		expectComment bool
   113  	}{
   114  		{
   115  			name:          "no OWNERS file",
   116  			filesChanged:  []string{"a.go", "b.go"},
   117  			expectComment: false,
   118  		},
   119  		{
   120  			name:          "add user to OWNERS",
   121  			filesChanged:  []string{"OWNERS", "b.go"},
   122  			sha:           "add cole",
   123  			expectComment: true,
   124  		},
   125  		{
   126  			name:          "add user to OWNERS_ALIASES",
   127  			filesChanged:  []string{"OWNERS_ALIASES", "b.go"},
   128  			sha:           "add cole",
   129  			expectComment: true,
   130  		},
   131  		{
   132  			name:          "remove user from OWNERS",
   133  			filesChanged:  []string{"OWNERS", "b.go"},
   134  			sha:           "remove alice",
   135  			expectComment: false,
   136  		},
   137  		{
   138  			name:          "remove user from OWNERS_ALIASES",
   139  			filesChanged:  []string{"OWNERS_ALIASES", "b.go"},
   140  			sha:           "remove alice",
   141  			expectComment: false,
   142  		},
   143  		{
   144  			name:          "move user from OWNERS_ALIASES to OWNERS",
   145  			filesChanged:  []string{"OWNERS", "OWNERS_ALIASES"},
   146  			sha:           "head",
   147  			expectComment: false,
   148  		},
   149  	}
   150  	lg, c, err := clients()
   151  	if err != nil {
   152  		t.Fatalf("Making localgit: %v", err)
   153  	}
   154  	defer func() {
   155  		if err := lg.Clean(); err != nil {
   156  			t.Errorf("Cleaning up localgit: %v", err)
   157  		}
   158  		if err := c.Clean(); err != nil {
   159  			t.Errorf("Cleaning up client: %v", err)
   160  		}
   161  	}()
   162  	if err := lg.MakeFakeRepo("org", "repo"); err != nil {
   163  		t.Fatalf("Making fake repo: %v", err)
   164  	}
   165  	for i, test := range tests {
   166  		t.Run(test.name, func(t *testing.T) {
   167  			pr := i + 1
   168  
   169  			changes := makeChanges(test.filesChanged)
   170  			fghc := newFakeGitHubClient(changes, pr)
   171  			oc := &fakeOwnersClient{}
   172  
   173  			prInfo := info{
   174  				base: github.PullRequestBranch{
   175  					Ref: "master",
   176  					SHA: "base",
   177  				},
   178  				head: github.PullRequestBranch{
   179  					Ref: "master",
   180  					SHA: test.sha,
   181  				},
   182  				number:       pr,
   183  				org:          "org",
   184  				repo:         "repo",
   185  				repoFullName: "org/repo",
   186  			}
   187  
   188  			if err := handle(fghc, oc, logrus.WithField("plugin", PluginName), prInfo, ownersconfig.FakeResolver); err != nil {
   189  				t.Fatalf("Handle PR: %v", err)
   190  			}
   191  			numComments := len(fghc.IssueCommentsAdded)
   192  			if numComments > 1 {
   193  				t.Fatalf("did not expect multiple comments for any test case and got %d comments", numComments)
   194  			}
   195  			if numComments == 0 && test.expectComment {
   196  				t.Fatalf("expected a comment for case '%s' and got none", test.name)
   197  			} else if numComments > 0 && !test.expectComment {
   198  				t.Fatalf("did not expect comments for case '%s' and got %d comments", test.name, numComments)
   199  			}
   200  		})
   201  	}
   202  }