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 }