github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/plugins/retitle/retitle_test.go (about)

     1  /*
     2  Copyright 2019 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 retitle
    18  
    19  import (
    20  	"errors"
    21  	"testing"
    22  
    23  	"github.com/sirupsen/logrus"
    24  	"k8s.io/apimachinery/pkg/util/diff"
    25  	"sigs.k8s.io/prow/pkg/github"
    26  	"sigs.k8s.io/prow/pkg/github/fakegithub"
    27  )
    28  
    29  func TestHandleGenericComment(t *testing.T) {
    30  	var testCases = []struct {
    31  		name              string
    32  		state             string
    33  		allowClosedIssues bool
    34  		action            github.GenericCommentEventAction
    35  		isPr              bool
    36  		body              string
    37  		trusted           func(string) (bool, error)
    38  		expectedTitle     string
    39  		expectedErr       bool
    40  		expectedComment   string
    41  	}{
    42  		{
    43  			name:              "when closed issues are not allowed, comment on closed issue is ignored",
    44  			state:             "closed",
    45  			allowClosedIssues: false,
    46  			action:            github.GenericCommentActionCreated,
    47  			body:              "/retitle foobar",
    48  		},
    49  		{
    50  			name:              "when closed issues are allowed, trusted user edits PR title on closed issue",
    51  			state:             "closed",
    52  			allowClosedIssues: true,
    53  			action:            github.GenericCommentActionCreated,
    54  			body:              "/retitle foobar",
    55  			isPr:              true,
    56  			trusted: func(user string) (bool, error) {
    57  				return true, nil
    58  			},
    59  			expectedTitle: "foobar",
    60  		},
    61  		{
    62  			name:   "edited comment on open issue is ignored",
    63  			state:  "open",
    64  			action: github.GenericCommentActionEdited,
    65  			body:   "/retitle foobar",
    66  		},
    67  		{
    68  			name:   "new unrelated comment on open issue is ignored",
    69  			state:  "open",
    70  			action: github.GenericCommentActionCreated,
    71  			body:   "whatever else",
    72  		},
    73  		{
    74  			name:   "new comment on open issue returns error when failing to check trusted",
    75  			state:  "open",
    76  			action: github.GenericCommentActionCreated,
    77  			body:   "/retitle foobar",
    78  			trusted: func(user string) (bool, error) {
    79  				return false, errors.New("oops")
    80  			},
    81  			expectedErr: true,
    82  		},
    83  		{
    84  			name:   "new comment on open issue comments when user is not trusted",
    85  			state:  "open",
    86  			action: github.GenericCommentActionCreated,
    87  			body:   "/retitle foobar",
    88  			trusted: func(user string) (bool, error) {
    89  				return false, nil
    90  			},
    91  			expectedComment: `org/repo#1:@user: Re-titling can only be requested by trusted users, like repository collaborators.
    92  
    93  <details>
    94  
    95  In response to [this]():
    96  
    97  >/retitle foobar
    98  
    99  
   100  Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
   101  </details>`,
   102  		},
   103  		{
   104  			name:   "new comment on open issue comments with no title",
   105  			state:  "open",
   106  			action: github.GenericCommentActionCreated,
   107  			body:   "/retitle     ",
   108  			trusted: func(user string) (bool, error) {
   109  				return true, nil
   110  			},
   111  			expectedComment: `org/repo#1:@user: Titles may not be empty.
   112  
   113  <details>
   114  
   115  In response to [this]():
   116  
   117  >/retitle     
   118  
   119  
   120  Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
   121  </details>`,
   122  		},
   123  		{
   124  			name:   "new comment on open issue comments with a title with @mention",
   125  			state:  "open",
   126  			action: github.GenericCommentActionCreated,
   127  			body:   "/retitle Add @mention to OWNERS",
   128  			trusted: func(user string) (bool, error) {
   129  				return true, nil
   130  			},
   131  			expectedComment: `org/repo#1:@user: Titles may not contain [keywords](https://help.github.com/articles/closing-issues-using-keywords) which can automatically close issues and at(@) mentions.
   132  
   133  <details>
   134  
   135  In response to [this]():
   136  
   137  >/retitle Add @mention to OWNERS
   138  
   139  
   140  Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
   141  </details>`,
   142  		},
   143  		{
   144  			name:   "new comment on open issue comments with a title with invalid keyword",
   145  			state:  "open",
   146  			action: github.GenericCommentActionCreated,
   147  			body:   "/retitle Fixes #9999",
   148  			trusted: func(user string) (bool, error) {
   149  				return true, nil
   150  			},
   151  			expectedComment: `org/repo#1:@user: Titles may not contain [keywords](https://help.github.com/articles/closing-issues-using-keywords) which can automatically close issues and at(@) mentions.
   152  
   153  <details>
   154  
   155  In response to [this]():
   156  
   157  >/retitle Fixes #9999
   158  
   159  
   160  Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
   161  </details>`,
   162  		},
   163  		{
   164  			name:   "trusted user edits PR title",
   165  			state:  "open",
   166  			action: github.GenericCommentActionCreated,
   167  			body:   "/retitle foobar",
   168  			isPr:   true,
   169  			trusted: func(user string) (bool, error) {
   170  				return true, nil
   171  			},
   172  			expectedTitle: "foobar",
   173  		},
   174  		{
   175  			name:   "trusted user edits issue title",
   176  			state:  "open",
   177  			action: github.GenericCommentActionCreated,
   178  			body:   "/retitle foobar",
   179  			isPr:   false,
   180  			trusted: func(user string) (bool, error) {
   181  				return true, nil
   182  			},
   183  			expectedTitle: "foobar",
   184  		},
   185  		{
   186  			name:   "carriage return is stripped",
   187  			state:  "open",
   188  			action: github.GenericCommentActionCreated,
   189  			body:   "/retitle foobar\r",
   190  			isPr:   false,
   191  			trusted: func(user string) (bool, error) {
   192  				return true, nil
   193  			},
   194  			expectedTitle: "foobar",
   195  		},
   196  	}
   197  
   198  	for _, testCase := range testCases {
   199  		t.Run(testCase.name, func(t *testing.T) {
   200  			gce := github.GenericCommentEvent{
   201  				Repo: github.Repo{
   202  					Owner: github.User{
   203  						Login: "org",
   204  					},
   205  					Name: "repo",
   206  				},
   207  				User: github.User{
   208  					Login: "user",
   209  				},
   210  				Number:     1,
   211  				IssueState: testCase.state,
   212  				Action:     testCase.action,
   213  				IsPR:       testCase.isPr,
   214  				Body:       testCase.body,
   215  			}
   216  			gc := fakegithub.NewFakeClient()
   217  			gc.Issues = map[int]*github.Issue{1: {Title: "Old"}}
   218  			gc.PullRequests = map[int]*github.PullRequest{1: {Title: "Old"}}
   219  			gc.IssueComments = map[int][]github.IssueComment{}
   220  
   221  			err := handleGenericComment(gc, testCase.trusted, testCase.allowClosedIssues, logrus.WithField("test-case", testCase.name), gce)
   222  			if err == nil && testCase.expectedErr {
   223  				t.Errorf("%s: expected an error but got none", testCase.name)
   224  			}
   225  			if err != nil && !testCase.expectedErr {
   226  				t.Errorf("%s: expected no error but got one: %v", testCase.name, err)
   227  			}
   228  
   229  			var actual string
   230  			if testCase.isPr {
   231  				actual = gc.PullRequests[gce.Number].Title
   232  			} else {
   233  				actual = gc.Issues[gce.Number].Title
   234  			}
   235  
   236  			if testCase.expectedTitle != "" && actual != testCase.expectedTitle {
   237  				t.Errorf("%s: expected title %q, got %q", testCase.name, testCase.expectedTitle, actual)
   238  			}
   239  
   240  			wantedComments := 0
   241  			if testCase.expectedComment != "" {
   242  				wantedComments = 1
   243  			}
   244  			if len(gc.IssueCommentsAdded) != wantedComments {
   245  				t.Errorf("%s: wanted %d comment, got %d: %v", testCase.name, wantedComments, len(gc.IssueCommentsAdded), gc.IssueCommentsAdded)
   246  			}
   247  
   248  			if testCase.expectedComment != "" && len(gc.IssueCommentsAdded) == 1 {
   249  				if testCase.expectedComment != gc.IssueCommentsAdded[0] {
   250  					t.Errorf("%s: got incorrect comment: %v", testCase.name, diff.StringDiff(testCase.expectedComment, gc.IssueCommentsAdded[0]))
   251  				}
   252  			}
   253  		})
   254  	}
   255  }