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