github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/cherrypickunapproved/cherrypick-unapproved_test.go (about)

     1  /*
     2  Copyright 2018 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 cherrypickunapproved
    18  
    19  import (
    20  	"reflect"
    21  	"regexp"
    22  	"testing"
    23  
    24  	"github.com/sirupsen/logrus"
    25  
    26  	"k8s.io/test-infra/prow/github"
    27  	"k8s.io/test-infra/prow/labels"
    28  )
    29  
    30  type fakeClient struct {
    31  	// current labels
    32  	labels []string
    33  	// labels that are added
    34  	added []string
    35  	// labels that are removed
    36  	removed []string
    37  	// commentsAdded tracks the comments in the client
    38  	commentsAdded map[int][]string
    39  }
    40  
    41  // AddLabel adds a label to the specified PR or issue
    42  func (fc *fakeClient) AddLabel(owner, repo string, number int, label string) error {
    43  	fc.added = append(fc.added, label)
    44  	fc.labels = append(fc.labels, label)
    45  	return nil
    46  }
    47  
    48  // RemoveLabel removes the label from the specified PR or issue
    49  func (fc *fakeClient) RemoveLabel(owner, repo string, number int, label string) error {
    50  	fc.removed = append(fc.removed, label)
    51  
    52  	// remove from existing labels
    53  	for k, v := range fc.labels {
    54  		if label == v {
    55  			fc.labels = append(fc.labels[:k], fc.labels[k+1:]...)
    56  			break
    57  		}
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  // GetIssueLabels gets the current labels on the specified PR or issue
    64  func (fc *fakeClient) GetIssueLabels(owner, repo string, number int) ([]github.Label, error) {
    65  	la := []github.Label{}
    66  	for _, l := range fc.labels {
    67  		la = append(la, github.Label{Name: l})
    68  	}
    69  	return la, nil
    70  }
    71  
    72  // CreateComment adds and tracks a comment in the client
    73  func (fc *fakeClient) CreateComment(owner, repo string, number int, comment string) error {
    74  	fc.commentsAdded[number] = append(fc.commentsAdded[number], comment)
    75  	return nil
    76  }
    77  
    78  // NumComments counts the number of tracked comments
    79  func (fc *fakeClient) NumComments() int {
    80  	n := 0
    81  	for _, comments := range fc.commentsAdded {
    82  		n += len(comments)
    83  	}
    84  	return n
    85  }
    86  
    87  type fakePruner struct{}
    88  
    89  func (fp *fakePruner) PruneComments(shouldPrune func(github.IssueComment) bool) {}
    90  
    91  func makeFakePullRequestEvent(action github.PullRequestEventAction, branch string) github.PullRequestEvent {
    92  	return github.PullRequestEvent{
    93  		Action: action,
    94  		PullRequest: github.PullRequest{
    95  			Base: github.PullRequestBranch{
    96  				Ref: branch,
    97  			},
    98  		},
    99  	}
   100  }
   101  
   102  func TestCherryPickUnapprovedLabel(t *testing.T) {
   103  	var testcases = []struct {
   104  		name          string
   105  		branch        string
   106  		action        github.PullRequestEventAction
   107  		labels        []string
   108  		added         []string
   109  		removed       []string
   110  		expectComment bool
   111  	}{
   112  		{
   113  			name:          "unsupported PR action -> no-op",
   114  			branch:        "release-1.10",
   115  			action:        github.PullRequestActionEdited,
   116  			labels:        []string{},
   117  			added:         []string{},
   118  			removed:       []string{},
   119  			expectComment: false,
   120  		},
   121  		{
   122  			name:          "branch that does match regexp -> no-op",
   123  			branch:        "master",
   124  			action:        github.PullRequestActionOpened,
   125  			labels:        []string{},
   126  			added:         []string{},
   127  			removed:       []string{},
   128  			expectComment: false,
   129  		},
   130  		{
   131  			name:          "has cpUnapproved -> no-op",
   132  			branch:        "release-1.10",
   133  			action:        github.PullRequestActionOpened,
   134  			labels:        []string{labels.CpUnapproved},
   135  			added:         []string{},
   136  			removed:       []string{},
   137  			expectComment: false,
   138  		},
   139  		{
   140  			name:          "has both cpApproved and cpUnapproved -> remove cpUnapproved",
   141  			branch:        "release-1.10",
   142  			action:        github.PullRequestActionOpened,
   143  			labels:        []string{labels.CpApproved, labels.CpUnapproved},
   144  			added:         []string{},
   145  			removed:       []string{labels.CpUnapproved},
   146  			expectComment: false,
   147  		},
   148  		{
   149  			name:          "does not have any labels, PR opened against a release branch -> add cpUnapproved and comment",
   150  			branch:        "release-1.10",
   151  			action:        github.PullRequestActionOpened,
   152  			labels:        []string{},
   153  			added:         []string{labels.CpUnapproved},
   154  			removed:       []string{},
   155  			expectComment: true,
   156  		},
   157  		{
   158  			name:          "does not have any labels, PR reopened against a release branch -> add cpUnapproved and comment",
   159  			branch:        "release-1.10",
   160  			action:        github.PullRequestActionReopened,
   161  			labels:        []string{},
   162  			added:         []string{labels.CpUnapproved},
   163  			removed:       []string{},
   164  			expectComment: true,
   165  		},
   166  	}
   167  
   168  	for _, tc := range testcases {
   169  		fc := &fakeClient{
   170  			labels:        tc.labels,
   171  			added:         []string{},
   172  			removed:       []string{},
   173  			commentsAdded: make(map[int][]string, 0),
   174  		}
   175  
   176  		event := makeFakePullRequestEvent(tc.action, tc.branch)
   177  		branchRe := regexp.MustCompile(`^release-.*$`)
   178  		comment := "dummy cumment"
   179  		err := handlePR(fc, logrus.WithField("plugin", "fake-cherrypick-unapproved"), &event, &fakePruner{}, branchRe, comment)
   180  		switch {
   181  		case err != nil:
   182  			t.Errorf("%s: unexpected error: %v", tc.name, err)
   183  		case !reflect.DeepEqual(tc.added, fc.added):
   184  			t.Errorf("%s: added %v != actual %v", tc.name, tc.added, fc.added)
   185  		case !reflect.DeepEqual(tc.removed, fc.removed):
   186  			t.Errorf("%s: removed %v != actual %v", tc.name, tc.removed, fc.removed)
   187  		}
   188  
   189  		// if we expected a comment, verify that a comment was made
   190  		numComments := fc.NumComments()
   191  		if tc.expectComment && numComments != 1 {
   192  			t.Errorf("%s: expected 1 comment but received %d comments", tc.name, numComments)
   193  		}
   194  		if !tc.expectComment && numComments != 0 {
   195  			t.Errorf("%s: expected no comments but received %d comments", tc.name, numComments)
   196  		}
   197  	}
   198  }