github.com/abayer/test-infra@v0.0.5/prow/plugins/lifecycle/close_test.go (about)

     1  /*
     2  Copyright 2016 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 lifecycle
    18  
    19  import (
    20  	"errors"
    21  	"testing"
    22  
    23  	"github.com/sirupsen/logrus"
    24  
    25  	"k8s.io/test-infra/prow/github"
    26  )
    27  
    28  type fakeClientClose struct {
    29  	commented      bool
    30  	closed         bool
    31  	AssigneesAdded []string
    32  	labels         []string
    33  }
    34  
    35  func (c *fakeClientClose) CreateComment(owner, repo string, number int, comment string) error {
    36  	c.commented = true
    37  	return nil
    38  }
    39  
    40  func (c *fakeClientClose) CloseIssue(owner, repo string, number int) error {
    41  	c.closed = true
    42  	return nil
    43  }
    44  
    45  func (c *fakeClientClose) ClosePR(owner, repo string, number int) error {
    46  	c.closed = true
    47  	return nil
    48  }
    49  
    50  func (c *fakeClientClose) IsMember(owner, login string) (bool, error) {
    51  	if login == "non-member" {
    52  		return false, nil
    53  	}
    54  	return true, nil
    55  }
    56  
    57  func (c *fakeClientClose) AssignIssue(owner, repo string, number int, assignees []string) error {
    58  	if assignees[0] == "non-member" || assignees[0] == "non-owner-assign-error" {
    59  		return errors.New("Failed to assign")
    60  	}
    61  	c.AssigneesAdded = append(c.AssigneesAdded, assignees...)
    62  	return nil
    63  }
    64  
    65  func (c *fakeClientClose) GetIssueLabels(owner, repo string, number int) ([]github.Label, error) {
    66  	var labels []github.Label
    67  	for _, l := range c.labels {
    68  		if l == "error" {
    69  			return nil, errors.New("issue label 500")
    70  		}
    71  		labels = append(labels, github.Label{Name: l})
    72  	}
    73  	return labels, nil
    74  }
    75  
    76  func TestCloseComment(t *testing.T) {
    77  	var testcases = []struct {
    78  		name          string
    79  		action        github.GenericCommentEventAction
    80  		state         string
    81  		body          string
    82  		commenter     string
    83  		labels        []string
    84  		shouldClose   bool
    85  		shouldComment bool
    86  		shouldAssign  bool
    87  	}{
    88  		{
    89  			name:          "non-close comment",
    90  			action:        github.GenericCommentActionCreated,
    91  			state:         "open",
    92  			body:          "uh oh",
    93  			commenter:     "o",
    94  			shouldClose:   false,
    95  			shouldComment: false,
    96  		},
    97  		{
    98  			name:          "close by author",
    99  			action:        github.GenericCommentActionCreated,
   100  			state:         "open",
   101  			body:          "/close",
   102  			commenter:     "a",
   103  			shouldClose:   true,
   104  			shouldComment: false,
   105  		},
   106  		{
   107  			name:          "close by author, trailing space.",
   108  			action:        github.GenericCommentActionCreated,
   109  			state:         "open",
   110  			body:          "/close \r",
   111  			commenter:     "a",
   112  			shouldClose:   true,
   113  			shouldComment: false,
   114  		},
   115  		{
   116  			name:          "close by reviewer",
   117  			action:        github.GenericCommentActionCreated,
   118  			state:         "open",
   119  			body:          "/close",
   120  			commenter:     "r1",
   121  			shouldClose:   true,
   122  			shouldComment: false,
   123  		},
   124  		{
   125  			name:          "close edited by author",
   126  			action:        github.GenericCommentActionEdited,
   127  			state:         "open",
   128  			body:          "/close",
   129  			commenter:     "a",
   130  			shouldClose:   false,
   131  			shouldComment: false,
   132  		},
   133  		{
   134  			name:          "close by author on closed issue",
   135  			action:        github.GenericCommentActionCreated,
   136  			state:         "closed",
   137  			body:          "/close",
   138  			commenter:     "a",
   139  			shouldClose:   false,
   140  			shouldComment: false,
   141  		},
   142  		{
   143  			name:          "close by other person, non-member cannot close",
   144  			action:        github.GenericCommentActionCreated,
   145  			state:         "open",
   146  			body:          "/close",
   147  			commenter:     "non-member",
   148  			shouldClose:   false,
   149  			shouldComment: true,
   150  			shouldAssign:  false,
   151  		},
   152  		{
   153  			name:          "close by other person, failed to assign",
   154  			action:        github.GenericCommentActionCreated,
   155  			state:         "open",
   156  			body:          "/close",
   157  			commenter:     "non-owner-assign-error",
   158  			shouldClose:   false,
   159  			shouldComment: true,
   160  			shouldAssign:  false,
   161  		},
   162  		{
   163  			name:          "close by other person, assign and close",
   164  			action:        github.GenericCommentActionCreated,
   165  			state:         "open",
   166  			body:          "/close",
   167  			commenter:     "non-owner",
   168  			shouldClose:   true,
   169  			shouldComment: false,
   170  			shouldAssign:  true,
   171  		},
   172  		{
   173  			name:          "close by other person, stale issue",
   174  			action:        github.GenericCommentActionCreated,
   175  			state:         "open",
   176  			body:          "/close",
   177  			commenter:     "non-member",
   178  			labels:        []string{"lifecycle/stale"},
   179  			shouldClose:   true,
   180  			shouldComment: false,
   181  			shouldAssign:  false,
   182  		},
   183  		{
   184  			name:          "close by other person, rotten issue",
   185  			action:        github.GenericCommentActionCreated,
   186  			state:         "open",
   187  			body:          "/close",
   188  			commenter:     "non-member",
   189  			labels:        []string{"lifecycle/rotten"},
   190  			shouldClose:   true,
   191  			shouldComment: false,
   192  			shouldAssign:  false,
   193  		},
   194  		{
   195  			name:          "cannot close stale issue by other person when list issue fails",
   196  			action:        github.GenericCommentActionCreated,
   197  			state:         "open",
   198  			body:          "/close",
   199  			commenter:     "non-member",
   200  			labels:        []string{"error"},
   201  			shouldClose:   false,
   202  			shouldComment: true,
   203  		},
   204  	}
   205  	for _, tc := range testcases {
   206  		fc := &fakeClientClose{labels: tc.labels}
   207  		e := &github.GenericCommentEvent{
   208  			Action:      tc.action,
   209  			IssueState:  tc.state,
   210  			Body:        tc.body,
   211  			User:        github.User{Login: tc.commenter},
   212  			Number:      5,
   213  			Assignees:   []github.User{{Login: "a"}, {Login: "r1"}, {Login: "r2"}},
   214  			IssueAuthor: github.User{Login: "a"},
   215  		}
   216  		if err := handleClose(fc, logrus.WithField("plugin", "fake-close"), e); err != nil {
   217  			t.Errorf("For case %s, didn't expect error from handle: %v", tc.name, err)
   218  			continue
   219  		}
   220  		if tc.shouldClose && !fc.closed {
   221  			t.Errorf("For case %s, should have closed but didn't.", tc.name)
   222  		} else if !tc.shouldClose && fc.closed {
   223  			t.Errorf("For case %s, should not have closed but did.", tc.name)
   224  		}
   225  		if tc.shouldComment && !fc.commented {
   226  			t.Errorf("For case %s, should have commented but didn't.", tc.name)
   227  		} else if !tc.shouldComment && fc.commented {
   228  			t.Errorf("For case %s, should not have commented but did.", tc.name)
   229  		}
   230  		if tc.shouldAssign && len(fc.AssigneesAdded) != 1 {
   231  			t.Errorf("For case %s, should have assigned but didn't.", tc.name)
   232  		} else if !tc.shouldAssign && len(fc.AssigneesAdded) == 1 {
   233  			t.Errorf("For case %s, should not have assigned but did.", tc.name)
   234  		}
   235  	}
   236  }