github.com/abayer/test-infra@v0.0.5/prow/plugins/cla/cla_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 cla 18 19 import ( 20 "fmt" 21 "reflect" 22 "testing" 23 24 "github.com/sirupsen/logrus" 25 26 "k8s.io/test-infra/prow/github" 27 "k8s.io/test-infra/prow/github/fakegithub" 28 ) 29 30 func TestCLALabels(t *testing.T) { 31 var testcases = []struct { 32 name string 33 context string 34 state string 35 statusSHA string 36 issues []github.Issue 37 pullRequests []github.PullRequest 38 labels []string 39 addedLabels []string 40 removedLabels []string 41 }{ 42 { 43 name: "unrecognized status context has no effect", 44 context: "unknown", 45 state: "success", 46 addedLabels: nil, 47 removedLabels: nil, 48 }, 49 { 50 name: "cla/linuxfoundation status pending has no effect", 51 context: "cla/linuxfoundation", 52 state: "pending", 53 addedLabels: nil, 54 removedLabels: nil, 55 }, 56 { 57 name: "cla/linuxfoundation status success does not add/remove labels " + 58 "when not the head commit in a PR", 59 context: "cla/linuxfoundation", 60 state: "success", 61 statusSHA: "a", 62 issues: []github.Issue{ 63 {Number: 3, State: "open", Labels: []github.Label{}}, 64 }, 65 pullRequests: []github.PullRequest{ 66 {Number: 3, Head: github.PullRequestBranch{SHA: "b"}}, 67 }, 68 addedLabels: nil, 69 removedLabels: nil, 70 }, 71 { 72 name: "cla/linuxfoundation status failure does not add/remove labels " + 73 "when not the head commit in a PR", 74 context: "cla/linuxfoundation", 75 state: "failure", 76 statusSHA: "a", 77 issues: []github.Issue{ 78 {Number: 3, State: "open", Labels: []github.Label{{Name: claYesLabel}}}, 79 }, 80 pullRequests: []github.PullRequest{ 81 {Number: 3, Head: github.PullRequestBranch{SHA: "b"}}, 82 }, 83 addedLabels: nil, 84 removedLabels: nil, 85 }, 86 { 87 name: "cla/linuxfoundation status on head commit of PR adds the cla-yes label when its state is \"success\"", 88 context: "cla/linuxfoundation", 89 state: "success", 90 statusSHA: "a", 91 issues: []github.Issue{ 92 {Number: 3, State: "open", Labels: []github.Label{}}, 93 }, 94 pullRequests: []github.PullRequest{ 95 {Number: 3, Head: github.PullRequestBranch{SHA: "a"}}, 96 }, 97 addedLabels: []string{fmt.Sprintf("/#3:%s", claYesLabel)}, 98 removedLabels: nil, 99 }, 100 { 101 name: "cla/linuxfoundation status on head commit of PR does nothing when pending", 102 context: "cla/linuxfoundation", 103 state: "pending", 104 statusSHA: "a", 105 issues: []github.Issue{ 106 {Number: 3, State: "open", Labels: []github.Label{}}, 107 }, 108 pullRequests: []github.PullRequest{ 109 {Number: 3, Head: github.PullRequestBranch{SHA: "a"}}, 110 }, 111 addedLabels: nil, 112 removedLabels: nil, 113 }, 114 { 115 name: "cla/linuxfoundation status success removes \"cncf-cla: no\" label", 116 context: "cla/linuxfoundation", 117 state: "success", 118 statusSHA: "a", 119 issues: []github.Issue{ 120 {Number: 3, State: "open", Labels: []github.Label{{Name: claNoLabel}}}, 121 }, 122 pullRequests: []github.PullRequest{ 123 {Number: 3, Head: github.PullRequestBranch{SHA: "a"}}, 124 }, 125 addedLabels: []string{fmt.Sprintf("/#3:%s", claYesLabel)}, 126 removedLabels: []string{fmt.Sprintf("/#3:%s", claNoLabel)}, 127 }, 128 { 129 name: "cla/linuxfoundation status failure removes \"cncf-cla: yes\" label", 130 context: "cla/linuxfoundation", 131 state: "failure", 132 statusSHA: "a", 133 issues: []github.Issue{ 134 {Number: 3, State: "open", Labels: []github.Label{{Name: claYesLabel}}}, 135 }, 136 pullRequests: []github.PullRequest{ 137 {Number: 3, Head: github.PullRequestBranch{SHA: "a"}}, 138 }, 139 addedLabels: []string{fmt.Sprintf("/#3:%s", claNoLabel)}, 140 removedLabels: []string{fmt.Sprintf("/#3:%s", claYesLabel)}, 141 }, 142 } 143 for _, tc := range testcases { 144 pullRequests := make(map[int]*github.PullRequest) 145 for _, pr := range tc.pullRequests { 146 pullRequests[pr.Number] = &pr 147 } 148 149 fc := &fakegithub.FakeClient{ 150 PullRequests: pullRequests, 151 Issues: tc.issues, 152 IssueComments: make(map[int][]github.IssueComment), 153 } 154 se := github.StatusEvent{ 155 Context: tc.context, 156 SHA: tc.statusSHA, 157 State: tc.state, 158 } 159 if err := handle(fc, logrus.WithField("plugin", pluginName), se); err != nil { 160 t.Errorf("For case %s, didn't expect error from cla plugin: %v", tc.name, err) 161 continue 162 } 163 164 if !reflect.DeepEqual(fc.LabelsAdded, tc.addedLabels) { 165 t.Errorf("Expected: %#v, Got %#v in case %s.", tc.addedLabels, fc.LabelsAdded, tc.name) 166 } 167 168 if !reflect.DeepEqual(fc.LabelsRemoved, tc.removedLabels) { 169 t.Errorf("Expected: %#v, Got %#v in case %s.", tc.removedLabels, fc.LabelsRemoved, tc.name) 170 } 171 } 172 } 173 174 func TestCheckCLA(t *testing.T) { 175 var testcases = []struct { 176 name string 177 context string 178 state string 179 issueState string 180 SHA string 181 action string 182 body string 183 pullRequests []github.PullRequest 184 hasCLAYes bool 185 hasCLANo bool 186 187 addedLabel string 188 removedLabel string 189 }{ 190 { 191 name: "ignore non cla/linuxfoundation context", 192 context: "random/context", 193 state: "success", 194 issueState: "open", 195 SHA: "sha", 196 action: "created", 197 body: "/check-cla", 198 pullRequests: []github.PullRequest{ 199 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 200 }, 201 }, 202 { 203 name: "ignore non open PRs", 204 context: "cla/linuxfoundation", 205 state: "success", 206 issueState: "closed", 207 SHA: "sha", 208 action: "created", 209 body: "/check-cla", 210 pullRequests: []github.PullRequest{ 211 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 212 }, 213 }, 214 { 215 name: "ignore non /check-cla comments", 216 context: "cla/linuxfoundation", 217 state: "success", 218 issueState: "open", 219 SHA: "sha", 220 action: "created", 221 body: "/shrug", 222 pullRequests: []github.PullRequest{ 223 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 224 }, 225 }, 226 { 227 name: "do nothing on when status state is \"pending\"", 228 context: "cla/linuxfoundation", 229 state: "pending", 230 issueState: "open", 231 SHA: "sha", 232 action: "created", 233 body: "/shrug", 234 pullRequests: []github.PullRequest{ 235 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 236 }, 237 }, 238 { 239 name: "cla/linuxfoundation status adds the cla-yes label when its state is \"success\"", 240 context: "cla/linuxfoundation", 241 state: "success", 242 issueState: "open", 243 SHA: "sha", 244 action: "created", 245 body: "/check-cla", 246 pullRequests: []github.PullRequest{ 247 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 248 }, 249 250 addedLabel: fmt.Sprintf("/#3:%s", claYesLabel), 251 }, 252 { 253 name: "cla/linuxfoundation status adds the cla-yes label and removes cla-no label when its state is \"success\"", 254 context: "cla/linuxfoundation", 255 state: "success", 256 issueState: "open", 257 SHA: "sha", 258 action: "created", 259 body: "/check-cla", 260 pullRequests: []github.PullRequest{ 261 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 262 }, 263 hasCLANo: true, 264 265 addedLabel: fmt.Sprintf("/#3:%s", claYesLabel), 266 removedLabel: fmt.Sprintf("/#3:%s", claNoLabel), 267 }, 268 { 269 name: "cla/linuxfoundation status adds the cla-no label when its state is \"failure\"", 270 context: "cla/linuxfoundation", 271 state: "failure", 272 issueState: "open", 273 SHA: "sha", 274 action: "created", 275 body: "/check-cla", 276 pullRequests: []github.PullRequest{ 277 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 278 }, 279 280 addedLabel: fmt.Sprintf("/#3:%s", claNoLabel), 281 }, 282 { 283 name: "cla/linuxfoundation status adds the cla-no label and removes cla-yes label when its state is \"failure\"", 284 context: "cla/linuxfoundation", 285 state: "failure", 286 issueState: "open", 287 SHA: "sha", 288 action: "created", 289 body: "/check-cla", 290 pullRequests: []github.PullRequest{ 291 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 292 }, 293 hasCLAYes: true, 294 295 addedLabel: fmt.Sprintf("/#3:%s", claNoLabel), 296 removedLabel: fmt.Sprintf("/#3:%s", claYesLabel), 297 }, 298 { 299 name: "cla/linuxfoundation status retains the cla-yes label and removes cla-no label when its state is \"success\"", 300 context: "cla/linuxfoundation", 301 state: "success", 302 issueState: "open", 303 SHA: "sha", 304 action: "created", 305 body: "/check-cla", 306 pullRequests: []github.PullRequest{ 307 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 308 }, 309 hasCLANo: true, 310 hasCLAYes: true, 311 312 removedLabel: fmt.Sprintf("/#3:%s", claNoLabel), 313 }, 314 { 315 name: "cla/linuxfoundation status retains the cla-no label and removes cla-yes label when its state is \"failure\"", 316 context: "cla/linuxfoundation", 317 state: "failure", 318 issueState: "open", 319 SHA: "sha", 320 action: "created", 321 body: "/check-cla", 322 pullRequests: []github.PullRequest{ 323 {Number: 3, Head: github.PullRequestBranch{SHA: "sha"}}, 324 }, 325 hasCLANo: true, 326 hasCLAYes: true, 327 328 removedLabel: fmt.Sprintf("/#3:%s", claYesLabel), 329 }, 330 } 331 for _, tc := range testcases { 332 t.Run(tc.name, func(t *testing.T) { 333 pullRequests := make(map[int]*github.PullRequest) 334 for _, pr := range tc.pullRequests { 335 pullRequests[pr.Number] = &pr 336 } 337 fc := &fakegithub.FakeClient{ 338 CreatedStatuses: make(map[string][]github.Status), 339 PullRequests: pullRequests, 340 } 341 e := &github.GenericCommentEvent{ 342 Action: github.GenericCommentEventAction(tc.action), 343 Body: tc.body, 344 Number: 3, 345 IssueState: tc.issueState, 346 } 347 fc.CreatedStatuses["sha"] = []github.Status{ 348 { 349 State: tc.state, 350 Context: tc.context, 351 }, 352 } 353 if tc.hasCLAYes { 354 fc.LabelsAdded = append(fc.LabelsAdded, fmt.Sprintf("/#3:%s", claYesLabel)) 355 } 356 if tc.hasCLANo { 357 fc.LabelsAdded = append(fc.LabelsAdded, fmt.Sprintf("/#3:%s", claNoLabel)) 358 } 359 if err := handleComment(fc, logrus.WithField("plugin", pluginName), e); err != nil { 360 t.Errorf("For case %s, didn't expect error from cla plugin: %v", tc.name, err) 361 } 362 ok := tc.addedLabel == "" 363 if !ok { 364 for _, label := range fc.LabelsAdded { 365 if reflect.DeepEqual(tc.addedLabel, label) { 366 ok = true 367 break 368 } 369 } 370 } 371 if !ok { 372 t.Errorf("Expected to add: %#v, Got %#v in case %s.", tc.addedLabel, fc.LabelsAdded, tc.name) 373 } 374 ok = tc.removedLabel == "" 375 if !ok { 376 for _, label := range fc.LabelsRemoved { 377 if reflect.DeepEqual(tc.removedLabel, label) { 378 ok = true 379 break 380 } 381 } 382 } 383 if !ok { 384 t.Errorf("Expected to remove: %#v, Got %#v in case %s.", tc.removedLabel, fc.LabelsRemoved, tc.name) 385 } 386 }) 387 } 388 }