1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package predicate
16
17 import (
18 "context"
19 "testing"
20
21 "github.com/stretchr/testify/assert"
22
23 "edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull"
24 "edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull/pulltest"
25
26 "edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/common"
27 )
28
29 func TestHasAuthorIn(t *testing.T) {
30 p := &HasAuthorIn{
31 common.Actors{
32 Teams: []string{"testorg/team"},
33 Users: []string{"mhaypenny"},
34 Organizations: []string{"testorg"},
35 },
36 }
37
38 runAuthorTests(t, p, []AuthorTestCase{
39 {
40 "noMatch",
41 &pulltest.Context{
42 AuthorValue: "ttest",
43 TeamMemberships: map[string][]string{
44 "ttest": {
45 "boringorg/testers",
46 },
47 },
48 OrgMemberships: map[string][]string{
49 "ttest": {
50 "boringorg",
51 },
52 },
53 },
54 &common.PredicateResult{
55 Satisfied: false,
56 Values: []string{"ttest"},
57 ConditionsMap: map[string][]string{
58 "Organizations": p.Organizations,
59 "Teams": p.Teams,
60 "Users": p.Users,
61 },
62 },
63 },
64 {
65 "authorInUsers",
66 &pulltest.Context{
67 AuthorValue: "mhaypenny",
68 },
69 &common.PredicateResult{
70 Satisfied: true,
71 Values: []string{"mhaypenny"},
72 ConditionsMap: map[string][]string{
73 "Organizations": p.Organizations,
74 "Teams": p.Teams,
75 "Users": p.Users,
76 },
77 },
78 },
79 {
80 "authorInTeams",
81 &pulltest.Context{
82 AuthorValue: "mortonh",
83 TeamMemberships: map[string][]string{
84 "mortonh": {
85 "coolorg/approvers",
86 "testorg/team",
87 },
88 },
89 },
90 &common.PredicateResult{
91 Satisfied: true,
92 Values: []string{"mortonh"},
93 ConditionsMap: map[string][]string{
94 "Organizations": p.Organizations,
95 "Teams": p.Teams,
96 "Users": p.Users,
97 },
98 },
99 },
100 {
101 "authorInOrgs",
102 &pulltest.Context{
103 AuthorValue: "mortonh",
104 OrgMemberships: map[string][]string{
105 "mortonh": {
106 "coolorg",
107 "testorg",
108 },
109 },
110 },
111 &common.PredicateResult{
112 Satisfied: true,
113 Values: []string{"mortonh"},
114 ConditionsMap: map[string][]string{
115 "Organizations": p.Organizations,
116 "Teams": p.Teams,
117 "Users": p.Users,
118 },
119 },
120 },
121 })
122 }
123
124 func TestHasContributorIn(t *testing.T) {
125 p := &HasContributorIn{
126 common.Actors{
127 Teams: []string{"testorg/team"},
128 Users: []string{"mhaypenny"},
129 Organizations: []string{"testorg"},
130 },
131 }
132
133 runAuthorTests(t, p, []AuthorTestCase{
134 {
135 "commitAuthorInUsers",
136 &pulltest.Context{
137 AuthorValue: "ttest",
138 CommitsValue: []*pull.Commit{
139 {
140 SHA: "abcdef123456789",
141 Author: "ttest",
142 Committer: "ttest",
143 },
144 {
145 SHA: "abcdef123456789",
146 Author: "mhaypenny",
147 Committer: "mhaypenny",
148 },
149 },
150 },
151 &common.PredicateResult{
152 Satisfied: true,
153 Values: []string{"mhaypenny"},
154 ConditionsMap: map[string][]string{
155 "Organizations": p.Organizations,
156 "Teams": p.Teams,
157 "Users": p.Users,
158 },
159 },
160 },
161 {
162 "commitCommitterInUsers",
163 &pulltest.Context{
164 AuthorValue: "ttest",
165 CommitsValue: []*pull.Commit{
166 {
167 SHA: "abcdef123456789",
168 Author: "ttest",
169 Committer: "ttest",
170 },
171 {
172 SHA: "abcdef123456789",
173 Author: "ttest",
174 Committer: "mhaypenny",
175 },
176 },
177 },
178 &common.PredicateResult{
179 Satisfied: true,
180 Values: []string{"mhaypenny"},
181 ConditionsMap: map[string][]string{
182 "Organizations": p.Organizations,
183 "Teams": p.Teams,
184 "Users": p.Users,
185 },
186 },
187 },
188 {
189 "commitAuthorInTeam",
190 &pulltest.Context{
191 AuthorValue: "ttest",
192 TeamMemberships: map[string][]string{
193 "mhaypenny": {
194 "testorg/team",
195 },
196 },
197 CommitsValue: []*pull.Commit{
198 {
199 SHA: "abcdef123456789",
200 Author: "ttest",
201 Committer: "ttest",
202 },
203 {
204 SHA: "abcdef123456789",
205 Author: "mhaypenny",
206 Committer: "mhaypenny",
207 },
208 },
209 },
210 &common.PredicateResult{
211 Satisfied: true,
212 Values: []string{"mhaypenny"},
213 ConditionsMap: map[string][]string{
214 "Organizations": p.Organizations,
215 "Teams": p.Teams,
216 "Users": p.Users,
217 },
218 },
219 },
220 {
221 "commitAuthorInOrg",
222 &pulltest.Context{
223 AuthorValue: "ttest",
224 OrgMemberships: map[string][]string{
225 "mhaypenny": {
226 "testorg",
227 },
228 },
229 CommitsValue: []*pull.Commit{
230 {
231 SHA: "abcdef123456789",
232 Author: "ttest",
233 Committer: "ttest",
234 },
235 {
236 SHA: "abcdef123456789",
237 Author: "mhaypenny",
238 Committer: "mhaypenny",
239 },
240 },
241 },
242 &common.PredicateResult{
243 Satisfied: true,
244 Values: []string{"mhaypenny"},
245 ConditionsMap: map[string][]string{
246 "Organizations": p.Organizations,
247 "Teams": p.Teams,
248 "Users": p.Users,
249 },
250 },
251 },
252 })
253 }
254
255 func TestOnlyHasContributorsIn(t *testing.T) {
256 p := &OnlyHasContributorsIn{
257 common.Actors{
258 Teams: []string{"testorg/team"},
259 Users: []string{"mhaypenny"},
260 Organizations: []string{"testorg"},
261 },
262 }
263
264 runAuthorTests(t, p, []AuthorTestCase{
265 {
266 "authorNotInList",
267 &pulltest.Context{
268 AuthorValue: "ttest",
269 CommitsValue: []*pull.Commit{
270 {
271 SHA: "abcdef123456789",
272 Author: "mhaypenny",
273 Committer: "mhaypenny",
274 },
275 },
276 },
277 &common.PredicateResult{
278 Satisfied: false,
279 Values: []string{"ttest"},
280 ConditionsMap: map[string][]string{
281 "Organizations": p.Organizations,
282 "Teams": p.Teams,
283 "Users": p.Users,
284 },
285 },
286 },
287 {
288 "containsCommitAuthorNotInList",
289 &pulltest.Context{
290 AuthorValue: "mhaypenny",
291 CommitsValue: []*pull.Commit{
292 {
293 SHA: "abcdef123456789",
294 Author: "mhaypenny",
295 Committer: "mhaypenny",
296 },
297 {
298 SHA: "abcdef123456789",
299 Author: "ttest",
300 Committer: "ttest",
301 },
302 },
303 },
304 &common.PredicateResult{
305 Satisfied: false,
306 Values: []string{"ttest"},
307 ConditionsMap: map[string][]string{
308 "Organizations": p.Organizations,
309 "Teams": p.Teams,
310 "Users": p.Users,
311 },
312 },
313 },
314 {
315 "committersInListButAuthorsAreNot",
316 &pulltest.Context{
317 AuthorValue: "mhaypenny",
318 CommitsValue: []*pull.Commit{
319 {
320 SHA: "abcdef123456789",
321 Author: "ttest1",
322 Committer: "mhaypenny",
323 },
324 {
325 SHA: "abcdef123456789",
326 Author: "ttest2",
327 Committer: "mhaypenny",
328 },
329 },
330 },
331 &common.PredicateResult{
332 Satisfied: false,
333 Values: []string{"ttest1"},
334 ConditionsMap: map[string][]string{
335 "Organizations": p.Organizations,
336 "Teams": p.Teams,
337 "Users": p.Users,
338 },
339 },
340 },
341 {
342 "commitAuthorInTeam",
343 &pulltest.Context{
344 AuthorValue: "ttest",
345 TeamMemberships: map[string][]string{
346 "ttest": {
347 "testorg/team",
348 },
349 },
350 CommitsValue: []*pull.Commit{
351 {
352 SHA: "abcdef123456789",
353 Author: "ttest",
354 Committer: "ttest",
355 },
356 {
357 SHA: "abcdef123456789",
358 Author: "mhaypenny",
359 Committer: "mhaypenny",
360 },
361 },
362 },
363 &common.PredicateResult{
364 Satisfied: true,
365 Values: []string{"mhaypenny", "ttest"},
366 ConditionsMap: map[string][]string{
367 "Organizations": p.Organizations,
368 "Teams": p.Teams,
369 "Users": p.Users,
370 },
371 },
372 },
373 {
374 "commitAuthorInOrg",
375 &pulltest.Context{
376 AuthorValue: "ttest",
377 OrgMemberships: map[string][]string{
378 "ttest": {
379 "testorg",
380 },
381 },
382 CommitsValue: []*pull.Commit{
383 {
384 SHA: "abcdef123456789",
385 Author: "ttest",
386 Committer: "ttest",
387 },
388 {
389 SHA: "abcdef123456789",
390 Author: "mhaypenny",
391 Committer: "mhaypenny",
392 },
393 },
394 },
395 &common.PredicateResult{
396 Satisfied: true,
397 Values: []string{"mhaypenny", "ttest"},
398 ConditionsMap: map[string][]string{
399 "Organizations": p.Organizations,
400 "Teams": p.Teams,
401 "Users": p.Users,
402 },
403 },
404 },
405 })
406 }
407
408 func TestAuthorIsOnlyContributor(t *testing.T) {
409 p := AuthorIsOnlyContributor(true)
410
411 runAuthorTests(t, p, []AuthorTestCase{
412 {
413 "authorIsOnlyContributor",
414 &pulltest.Context{
415 AuthorValue: "mhaypenny",
416 CommitsValue: []*pull.Commit{
417 {
418 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
419 Author: "mhaypenny",
420 Committer: "mhaypenny",
421 },
422 {
423 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
424 Author: "mhaypenny",
425 Committer: "mhaypenny",
426 },
427 },
428 },
429 &common.PredicateResult{
430 Satisfied: true,
431 Values: []string{"mhaypenny"},
432 ConditionValues: []string{"they are the only contributors"},
433 },
434 },
435 {
436 "authorIsOnlyContributorViaWeb",
437 &pulltest.Context{
438 AuthorValue: "mhaypenny",
439 CommitsValue: []*pull.Commit{
440 {
441 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
442 Author: "mhaypenny",
443 Committer: "",
444 CommittedViaWeb: true,
445 },
446 },
447 },
448 &common.PredicateResult{
449 Satisfied: true,
450 Values: []string{"mhaypenny"},
451 ConditionValues: []string{"they are the only contributors"},
452 },
453 },
454 {
455 "authorIsNotOnlyAuthor",
456 &pulltest.Context{
457 AuthorValue: "mhaypenny",
458 CommitsValue: []*pull.Commit{
459 {
460 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
461 Author: "mhaypenny",
462 Committer: "mhaypenny",
463 },
464 {
465 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
466 Author: "ttest",
467 Committer: "mhaypenny",
468 },
469 },
470 },
471 &common.PredicateResult{
472 Satisfied: false,
473 Values: []string{"mhaypenny"},
474 ConditionValues: []string{"they are the only contributors"},
475 },
476 },
477 {
478 "authorIsNotOnlyCommitter",
479 &pulltest.Context{
480 AuthorValue: "mhaypenny",
481 CommitsValue: []*pull.Commit{
482 {
483 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
484 Author: "mhaypenny",
485 Committer: "mhaypenny",
486 },
487 {
488 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
489 Author: "mhaypenny",
490 Committer: "ttest",
491 },
492 },
493 },
494 &common.PredicateResult{
495 Satisfied: false,
496 Values: []string{"mhaypenny"},
497 ConditionValues: []string{"they are the only contributors"},
498 },
499 },
500 })
501 }
502
503 func TestAuthorIsNotOnlyContributor(t *testing.T) {
504 p := AuthorIsOnlyContributor(false)
505
506 runAuthorTests(t, p, []AuthorTestCase{
507 {
508 "authorIsOnlyContributor",
509 &pulltest.Context{
510 AuthorValue: "mhaypenny",
511 CommitsValue: []*pull.Commit{
512 {
513 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
514 Author: "mhaypenny",
515 Committer: "mhaypenny",
516 },
517 {
518 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
519 Author: "mhaypenny",
520 Committer: "mhaypenny",
521 },
522 },
523 },
524 &common.PredicateResult{
525 Satisfied: false,
526 Values: []string{"mhaypenny"},
527 ConditionValues: []string{"they are not the only contributors"},
528 },
529 },
530 {
531 "authorIsNotOnlyAuthor",
532 &pulltest.Context{
533 AuthorValue: "mhaypenny",
534 CommitsValue: []*pull.Commit{
535 {
536 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
537 Author: "mhaypenny",
538 Committer: "mhaypenny",
539 },
540 {
541 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
542 Author: "ttest",
543 Committer: "mhaypenny",
544 },
545 },
546 },
547 &common.PredicateResult{
548 Satisfied: true,
549 Values: []string{"mhaypenny"},
550 ConditionValues: []string{"they are not the only contributors"},
551 },
552 },
553 {
554 "authorIsNotOnlyCommitter",
555 &pulltest.Context{
556 AuthorValue: "mhaypenny",
557 CommitsValue: []*pull.Commit{
558 {
559 SHA: "0cb194c52ee7c6c82110b59ec51b959ecfcb2fa2",
560 Author: "mhaypenny",
561 Committer: "mhaypenny",
562 },
563 {
564 SHA: "9df0f1cee4b58363b534dbb5e9070fceee23fa10",
565 Author: "mhaypenny",
566 Committer: "ttest",
567 },
568 },
569 },
570 &common.PredicateResult{
571 Satisfied: true,
572 Values: []string{"mhaypenny"},
573 ConditionValues: []string{"they are not the only contributors"},
574 },
575 },
576 })
577 }
578
579 type AuthorTestCase struct {
580 Name string
581 Context pull.Context
582 ExpectedPredicateResult *common.PredicateResult
583 }
584
585 func runAuthorTests(t *testing.T, p Predicate, cases []AuthorTestCase) {
586 ctx := context.Background()
587
588 for _, tc := range cases {
589 t.Run(tc.Name, func(t *testing.T) {
590 predicateResult, err := p.Evaluate(ctx, tc.Context)
591 if assert.NoError(t, err, "evaluation failed") {
592 assertPredicateResult(t, tc.ExpectedPredicateResult, predicateResult)
593 }
594 })
595 }
596 }
597
View as plain text