...

Source file src/edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/approval/approve_test.go

Documentation: edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/approval

     1  // Copyright 2018 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package approval
    16  
    17  import (
    18  	"context"
    19  	"os"
    20  	"regexp"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/rs/zerolog"
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  
    28  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull"
    29  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull/pulltest"
    30  
    31  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/common"
    32  )
    33  
    34  func TestIsApproved(t *testing.T) {
    35  	logger := zerolog.New(os.Stdout)
    36  	ctx := logger.WithContext(context.Background())
    37  
    38  	now := time.Now()
    39  	basePullContext := func() *pulltest.Context {
    40  		return &pulltest.Context{
    41  			AuthorValue: "mhaypenny",
    42  			BodyValue: &pull.Body{
    43  				Body:         "/no-platform",
    44  				CreatedAt:    now.Add(10 * time.Second),
    45  				LastEditedAt: now.Add(20 * time.Second),
    46  				Author:       "body-editor",
    47  			},
    48  			CommentsValue: []*pull.Comment{
    49  				{
    50  					CreatedAt:    now.Add(10 * time.Second),
    51  					LastEditedAt: time.Time{},
    52  					Author:       "other-user",
    53  					Body:         "Why did you do this?",
    54  				},
    55  				{
    56  					CreatedAt:    now.Add(20 * time.Second),
    57  					LastEditedAt: time.Time{},
    58  					Author:       "comment-approver",
    59  					Body:         "LGTM :+1: :shipit:",
    60  				},
    61  				{
    62  					CreatedAt:    now.Add(30 * time.Second),
    63  					LastEditedAt: time.Time{},
    64  					Author:       "disapprover",
    65  					Body:         "I don't like things! :-1:",
    66  				},
    67  				{
    68  					CreatedAt:    now.Add(40 * time.Second),
    69  					LastEditedAt: time.Time{},
    70  					Author:       "mhaypenny",
    71  					Body:         ":+1: my stuff is cool",
    72  				},
    73  				{
    74  					CreatedAt:    now.Add(50 * time.Second),
    75  					LastEditedAt: time.Time{},
    76  					Author:       "contributor-author",
    77  					Body:         ":+1: I added to this PR",
    78  				},
    79  				{
    80  					CreatedAt:    now.Add(60 * time.Second),
    81  					LastEditedAt: time.Time{},
    82  					Author:       "contributor-committer",
    83  					Body:         ":+1: I also added to this PR",
    84  				},
    85  				{
    86  					CreatedAt:    now.Add(70 * time.Second),
    87  					LastEditedAt: now.Add(71 * time.Second),
    88  					Author:       "comment-editor",
    89  					Body:         "LGTM :+1: :shipit:",
    90  				},
    91  			},
    92  			ReviewsValue: []*pull.Review{
    93  				{
    94  					CreatedAt:    now.Add(70 * time.Second),
    95  					LastEditedAt: time.Time{},
    96  					Author:       "disapprover",
    97  					State:        pull.ReviewChangesRequested,
    98  					Body:         "I _really_ don't like things!",
    99  				},
   100  				{
   101  					CreatedAt:    now.Add(80 * time.Second),
   102  					LastEditedAt: time.Time{},
   103  					Author:       "review-approver",
   104  					State:        pull.ReviewApproved,
   105  					Body:         "I LIKE THIS",
   106  				},
   107  				{
   108  					CreatedAt:    now.Add(90 * time.Second),
   109  					LastEditedAt: now.Add(91 * time.Second),
   110  					Author:       "review-comment-editor",
   111  					State:        pull.ReviewApproved,
   112  					Body:         "I LIKE THIS",
   113  				},
   114  			},
   115  			CommitsValue: []*pull.Commit{
   116  				{
   117  					PushedAt:  newTime(now.Add(5 * time.Second)),
   118  					SHA:       "c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   119  					Author:    "mhaypenny",
   120  					Committer: "mhaypenny",
   121  				},
   122  				{
   123  					PushedAt:  newTime(now.Add(15 * time.Second)),
   124  					SHA:       "674832587eaaf416371b30f5bc5a47e377f534ec",
   125  					Author:    "contributor-author",
   126  					Committer: "mhaypenny",
   127  				},
   128  				{
   129  					PushedAt:  newTime(now.Add(45 * time.Second)),
   130  					SHA:       "97d5ea26da319a987d80f6db0b7ef759f2f2e441",
   131  					Author:    "mhaypenny",
   132  					Committer: "contributor-committer",
   133  				},
   134  			},
   135  			OrgMemberships: map[string][]string{
   136  				"mhaypenny":             {"everyone"},
   137  				"contributor-author":    {"everyone"},
   138  				"contributor-committer": {"everyone"},
   139  				"comment-approver":      {"everyone", "cool-org"},
   140  				"review-approver":       {"everyone", "even-cooler-org"},
   141  			},
   142  		}
   143  	}
   144  
   145  	assertApproved := func(t *testing.T, prctx pull.Context, r *Rule, expected string) {
   146  		allowedCandidates, err := r.FilteredCandidates(ctx, prctx)
   147  		require.NoError(t, err)
   148  
   149  		approved, msg, err := r.IsApproved(ctx, prctx, allowedCandidates)
   150  		require.NoError(t, err)
   151  
   152  		if assert.True(t, approved, "pull request was not approved") {
   153  			assert.Equal(t, expected, msg)
   154  		}
   155  	}
   156  
   157  	assertPending := func(t *testing.T, prctx pull.Context, r *Rule, expected string) {
   158  		allowedCandidates, err := r.FilteredCandidates(ctx, prctx)
   159  		require.NoError(t, err)
   160  
   161  		approved, msg, err := r.IsApproved(ctx, prctx, allowedCandidates)
   162  		require.NoError(t, err)
   163  
   164  		if assert.False(t, approved, "pull request was incorrectly approved") {
   165  			assert.Equal(t, expected, msg)
   166  		}
   167  	}
   168  
   169  	t.Run("noApprovalRequired", func(t *testing.T) {
   170  		prctx := basePullContext()
   171  		r := &Rule{}
   172  		assertApproved(t, prctx, r, "No approval required")
   173  	})
   174  
   175  	t.Run("singleApprovalRequired", func(t *testing.T) {
   176  		prctx := basePullContext()
   177  		r := &Rule{
   178  			Requires: Requires{
   179  				Count: 1,
   180  			},
   181  		}
   182  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 7 approvals from disqualified users")
   183  	})
   184  
   185  	t.Run("authorCannotApprove", func(t *testing.T) {
   186  		prctx := basePullContext()
   187  		r := &Rule{
   188  			Options: Options{
   189  				AllowAuthor: false,
   190  			},
   191  			Requires: Requires{
   192  				Count: 1,
   193  				Actors: common.Actors{
   194  					Organizations: []string{"everyone"},
   195  				},
   196  			},
   197  		}
   198  		assertApproved(t, prctx, r, "Approved by comment-approver, review-approver")
   199  	})
   200  
   201  	t.Run("authorCanApprove", func(t *testing.T) {
   202  		prctx := basePullContext()
   203  		r := &Rule{
   204  			Options: Options{
   205  				AllowAuthor: true,
   206  			},
   207  			Requires: Requires{
   208  				Count: 1,
   209  				Actors: common.Actors{
   210  					Organizations: []string{"everyone"},
   211  				},
   212  			},
   213  		}
   214  		assertApproved(t, prctx, r, "Approved by comment-approver, mhaypenny, review-approver")
   215  	})
   216  
   217  	t.Run("contributorsCannotApprove", func(t *testing.T) {
   218  		prctx := basePullContext()
   219  		r := &Rule{
   220  			Options: Options{
   221  				AllowContributor: false,
   222  			},
   223  			Requires: Requires{
   224  				Count: 1,
   225  				Actors: common.Actors{
   226  					Organizations: []string{"everyone"},
   227  				},
   228  			},
   229  		}
   230  		assertApproved(t, prctx, r, "Approved by comment-approver, review-approver")
   231  	})
   232  
   233  	t.Run("contributorsIncludingAuthorCanApprove", func(t *testing.T) {
   234  		prctx := basePullContext()
   235  		r := &Rule{
   236  			Options: Options{
   237  				AllowContributor: true,
   238  				AllowAuthor:      false,
   239  			},
   240  			Requires: Requires{
   241  				Count: 1,
   242  				Actors: common.Actors{
   243  					Organizations: []string{"everyone"},
   244  				},
   245  			},
   246  		}
   247  		assertApproved(t, prctx, r, "Approved by comment-approver, mhaypenny, contributor-author, contributor-committer, review-approver")
   248  	})
   249  
   250  	t.Run("contributorsExcludingAuthorCanApprove", func(t *testing.T) {
   251  		prctx := basePullContext()
   252  		r := &Rule{
   253  			Options: Options{
   254  				AllowNonAuthorContributor: true,
   255  			},
   256  			Requires: Requires{
   257  				Count: 1,
   258  				Actors: common.Actors{
   259  					Organizations: []string{"everyone"},
   260  				},
   261  			},
   262  		}
   263  		assertApproved(t, prctx, r, "Approved by comment-approver, contributor-author, contributor-committer, review-approver")
   264  	})
   265  
   266  	t.Run("nonAuthorContributorsAndAuthorCanApprove", func(t *testing.T) {
   267  		prctx := basePullContext()
   268  		r := &Rule{
   269  			Options: Options{
   270  				AllowNonAuthorContributor: true,
   271  				AllowAuthor:               true,
   272  			},
   273  			Requires: Requires{
   274  				Count: 1,
   275  				Actors: common.Actors{
   276  					Organizations: []string{"everyone"},
   277  				},
   278  			},
   279  		}
   280  		assertApproved(t, prctx, r, "Approved by comment-approver, mhaypenny, contributor-author, contributor-committer, review-approver")
   281  	})
   282  
   283  	t.Run("contributorsAndAuthorCanApprove", func(t *testing.T) {
   284  		prctx := basePullContext()
   285  		r := &Rule{
   286  			Options: Options{
   287  				AllowNonAuthorContributor: true,
   288  				AllowContributor:          true,
   289  			},
   290  			Requires: Requires{
   291  				Count: 1,
   292  				Actors: common.Actors{
   293  					Organizations: []string{"everyone"},
   294  				},
   295  			},
   296  		}
   297  		assertApproved(t, prctx, r, "Approved by comment-approver, mhaypenny, contributor-author, contributor-committer, review-approver")
   298  	})
   299  
   300  	t.Run("specificUserApproves", func(t *testing.T) {
   301  		prctx := basePullContext()
   302  		r := &Rule{
   303  			Requires: Requires{
   304  				Count: 1,
   305  				Actors: common.Actors{
   306  					Users: []string{"comment-approver"},
   307  				},
   308  			},
   309  		}
   310  		assertApproved(t, prctx, r, "Approved by comment-approver")
   311  
   312  		r = &Rule{
   313  			Requires: Requires{
   314  				Count: 1,
   315  				Actors: common.Actors{
   316  					Users: []string{"does-not-exist"},
   317  				},
   318  			},
   319  		}
   320  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 7 approvals from disqualified users")
   321  	})
   322  
   323  	t.Run("specificOrgApproves", func(t *testing.T) {
   324  		prctx := basePullContext()
   325  		r := &Rule{
   326  			Requires: Requires{
   327  				Count: 1,
   328  				Actors: common.Actors{
   329  					Organizations: []string{"cool-org"},
   330  				},
   331  			},
   332  		}
   333  		assertApproved(t, prctx, r, "Approved by comment-approver")
   334  
   335  		r = &Rule{
   336  			Requires: Requires{
   337  				Count: 1,
   338  				Actors: common.Actors{
   339  					Organizations: []string{"does-not-exist", "other-org"},
   340  				},
   341  			},
   342  		}
   343  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 7 approvals from disqualified users")
   344  	})
   345  
   346  	t.Run("specificOrgsOrUserApproves", func(t *testing.T) {
   347  		prctx := basePullContext()
   348  		r := &Rule{
   349  			Requires: Requires{
   350  				Count: 2,
   351  				Actors: common.Actors{
   352  					Users:         []string{"review-approver"},
   353  					Organizations: []string{"cool-org"},
   354  				},
   355  			},
   356  		}
   357  		assertApproved(t, prctx, r, "Approved by comment-approver, review-approver")
   358  	})
   359  
   360  	t.Run("invalidateCommentOnPush", func(t *testing.T) {
   361  		prctx := basePullContext()
   362  		prctx.CommitsValue = []*pull.Commit{
   363  			{
   364  				PushedAt:  newTime(now.Add(25 * time.Second)),
   365  				SHA:       "c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   366  				Author:    "mhaypenny",
   367  				Committer: "mhaypenny",
   368  			},
   369  		}
   370  
   371  		r := &Rule{
   372  			Requires: Requires{
   373  				Count: 1,
   374  				Actors: common.Actors{
   375  					Users: []string{"comment-approver"},
   376  				},
   377  			},
   378  		}
   379  		assertApproved(t, prctx, r, "Approved by comment-approver")
   380  
   381  		r.Options.InvalidateOnPush = true
   382  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 6 approvals from disqualified users")
   383  	})
   384  
   385  	t.Run("invalidateReviewOnPush", func(t *testing.T) {
   386  		prctx := basePullContext()
   387  		prctx.CommitsValue = []*pull.Commit{
   388  			{
   389  				PushedAt:  newTime(now.Add(85 * time.Second)),
   390  				SHA:       "c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   391  				Author:    "mhaypenny",
   392  				Committer: "mhaypenny",
   393  			},
   394  		}
   395  
   396  		r := &Rule{
   397  			Requires: Requires{
   398  				Count: 1,
   399  				Actors: common.Actors{
   400  					Users: []string{"review-approver"},
   401  				},
   402  			},
   403  		}
   404  		assertApproved(t, prctx, r, "Approved by review-approver")
   405  
   406  		r.Options.InvalidateOnPush = true
   407  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 1 approval from disqualified users")
   408  	})
   409  
   410  	t.Run("ignoreUpdateMergeAfterReview", func(t *testing.T) {
   411  		prctx := basePullContext()
   412  		prctx.CommitsValue = append(prctx.CommitsValue[:1], &pull.Commit{
   413  			PushedAt:        newTime(now.Add(25 * time.Second)),
   414  			SHA:             "647c5078288f0ea9de27b5c280f25edaf2089045",
   415  			CommittedViaWeb: true,
   416  			Parents: []string{
   417  				"c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   418  				"2e1b0bb6ab144bf7a1b7a1df9d3bdcb0fe85a206",
   419  			},
   420  			Author: "merge-committer",
   421  		})
   422  
   423  		r := &Rule{
   424  			Requires: Requires{
   425  				Count: 1,
   426  				Actors: common.Actors{
   427  					Users: []string{"comment-approver"},
   428  				},
   429  			},
   430  			Options: Options{
   431  				InvalidateOnPush: true,
   432  			},
   433  		}
   434  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 6 approvals from disqualified users")
   435  
   436  		r.Options.IgnoreUpdateMerges = true
   437  		assertApproved(t, prctx, r, "Approved by comment-approver")
   438  	})
   439  
   440  	t.Run("ignoreUpdateMergeContributor", func(t *testing.T) {
   441  		prctx := basePullContext()
   442  		prctx.CommitsValue = append(prctx.CommitsValue[:1], &pull.Commit{
   443  			PushedAt:        newTime(now.Add(25 * time.Second)),
   444  			SHA:             "647c5078288f0ea9de27b5c280f25edaf2089045",
   445  			CommittedViaWeb: true,
   446  			Parents: []string{
   447  				"c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   448  				"2e1b0bb6ab144bf7a1b7a1df9d3bdcb0fe85a206",
   449  			},
   450  			Author: "merge-committer",
   451  		})
   452  		prctx.CommentsValue = append(prctx.CommentsValue, &pull.Comment{
   453  			CreatedAt: now.Add(100 * time.Second),
   454  			Author:    "merge-committer",
   455  			Body:      ":+1:",
   456  		})
   457  
   458  		r := &Rule{
   459  			Requires: Requires{
   460  				Count: 1,
   461  				Actors: common.Actors{
   462  					Users: []string{"merge-committer"},
   463  				},
   464  			},
   465  		}
   466  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 8 approvals from disqualified users")
   467  
   468  		r.Options.IgnoreUpdateMerges = true
   469  		assertApproved(t, prctx, r, "Approved by merge-committer")
   470  	})
   471  
   472  	t.Run("ignoreCommits", func(t *testing.T) {
   473  		prctx := basePullContext()
   474  		prctx.CommitsValue = append(prctx.CommitsValue, &pull.Commit{
   475  			SHA:       "ea9be5fcd016dc41d70dc457dfee2e64a8f951c1",
   476  			Author:    "comment-approver",
   477  			Committer: "comment-approver",
   478  		})
   479  
   480  		r := &Rule{
   481  			Requires: Requires{
   482  				Count: 1,
   483  				Actors: common.Actors{
   484  					Users: []string{"comment-approver"},
   485  				},
   486  			},
   487  		}
   488  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 7 approvals from disqualified users")
   489  
   490  		r.Options.IgnoreCommitsBy = common.Actors{
   491  			Users: []string{"comment-approver"},
   492  		}
   493  		assertApproved(t, prctx, r, "Approved by comment-approver")
   494  	})
   495  
   496  	t.Run("ignoreCommitsMixedAuthorCommiter", func(t *testing.T) {
   497  		prctx := basePullContext()
   498  
   499  		r := &Rule{
   500  			Requires: Requires{
   501  				Count: 1,
   502  				Actors: common.Actors{
   503  					Users: []string{"contributor-author"},
   504  				},
   505  			},
   506  			Options: Options{
   507  				IgnoreCommitsBy: common.Actors{
   508  					Users: []string{"contributor-author"},
   509  				},
   510  			},
   511  		}
   512  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 7 approvals from disqualified users")
   513  	})
   514  
   515  	t.Run("ignoreCommitsInvalidateOnPush", func(t *testing.T) {
   516  		prctx := basePullContext()
   517  		prctx.CommitsValue = []*pull.Commit{
   518  			{
   519  				PushedAt:  newTime(now.Add(25 * time.Second)),
   520  				SHA:       "c6ade256ecfc755d8bc877ef22cc9e01745d46bb",
   521  				Author:    "mhaypenny",
   522  				Committer: "mhaypenny",
   523  			},
   524  		}
   525  
   526  		r := &Rule{
   527  			Requires: Requires{
   528  				Count: 1,
   529  				Actors: common.Actors{
   530  					Users: []string{"comment-approver"},
   531  				},
   532  			},
   533  		}
   534  		assertApproved(t, prctx, r, "Approved by comment-approver")
   535  
   536  		r.Options.InvalidateOnPush = true
   537  		r.Options.IgnoreCommitsBy = common.Actors{
   538  			Users: []string{"mhaypenny"},
   539  		}
   540  		assertApproved(t, prctx, r, "Approved by comment-approver")
   541  	})
   542  
   543  	t.Run("ignoreEditedReviewComments", func(t *testing.T) {
   544  		prctx := basePullContext()
   545  
   546  		r := &Rule{
   547  			Requires: Requires{
   548  				Count: 1,
   549  				Actors: common.Actors{
   550  					Users: []string{"review-comment-editor"},
   551  				},
   552  			},
   553  		}
   554  
   555  		assertApproved(t, prctx, r, "Approved by review-comment-editor")
   556  
   557  		r.Options.IgnoreEditedComments = true
   558  
   559  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 5 approvals from disqualified users")
   560  	})
   561  
   562  	t.Run("ignoreEditedComments", func(t *testing.T) {
   563  		prctx := basePullContext()
   564  
   565  		r := &Rule{
   566  			Requires: Requires{
   567  				Count: 1,
   568  				Actors: common.Actors{
   569  					Users: []string{"comment-editor"},
   570  				},
   571  			},
   572  		}
   573  
   574  		assertApproved(t, prctx, r, "Approved by comment-editor")
   575  
   576  		r.Options.IgnoreEditedComments = true
   577  
   578  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 5 approvals from disqualified users")
   579  	})
   580  
   581  	t.Run("ignoreEditedCommentsWithBodyPattern", func(t *testing.T) {
   582  		prctx := basePullContext()
   583  
   584  		r := &Rule{
   585  			Requires: Requires{
   586  				Count: 1,
   587  				Actors: common.Actors{
   588  					Users: []string{"body-editor"},
   589  				},
   590  			},
   591  			Options: Options{
   592  				Methods: &common.Methods{
   593  					BodyPatterns: []common.Regexp{
   594  						common.NewCompiledRegexp(regexp.MustCompile("/no-platform")),
   595  					},
   596  				},
   597  				IgnoreEditedComments: false,
   598  			},
   599  		}
   600  
   601  		assertApproved(t, prctx, r, "Approved by body-editor")
   602  
   603  		r.Options.IgnoreEditedComments = true
   604  
   605  		assertPending(t, prctx, r, "0/1 approvals required. Ignored 5 approvals from disqualified users")
   606  	})
   607  }
   608  
   609  func TestTrigger(t *testing.T) {
   610  	t.Run("triggerCommitOnRules", func(t *testing.T) {
   611  		r := &Rule{}
   612  
   613  		assert.True(t, r.Trigger().Matches(common.TriggerCommit), "expected %s to match %", r.Trigger(), common.TriggerCommit)
   614  	})
   615  
   616  	t.Run("triggerCommentOnComments", func(t *testing.T) {
   617  		r := &Rule{
   618  			Options: Options{
   619  				Methods: &common.Methods{
   620  					Comments: []string{
   621  						"lgtm",
   622  					},
   623  				},
   624  			},
   625  			Requires: Requires{
   626  				Count: 1,
   627  			},
   628  		}
   629  
   630  		assert.True(t, r.Trigger().Matches(common.TriggerCommit), "expected %s to match %s", r.Trigger(), common.TriggerCommit)
   631  		assert.True(t, r.Trigger().Matches(common.TriggerComment), "expected %s to match %s", r.Trigger(), common.TriggerComment)
   632  	})
   633  
   634  	t.Run("triggerCommentOnCommentPatterns", func(t *testing.T) {
   635  		r := &Rule{
   636  			Options: Options{
   637  				Methods: &common.Methods{
   638  					CommentPatterns: []common.Regexp{
   639  						common.NewCompiledRegexp(regexp.MustCompile("(?i)nice")),
   640  					},
   641  				},
   642  			},
   643  			Requires: Requires{
   644  				Count: 1,
   645  			},
   646  		}
   647  
   648  		assert.True(t, r.Trigger().Matches(common.TriggerCommit), "expected %s to match %s", r.Trigger(), common.TriggerCommit)
   649  		assert.True(t, r.Trigger().Matches(common.TriggerComment), "expected %s to match %s", r.Trigger(), common.TriggerComment)
   650  	})
   651  
   652  	t.Run("triggerReviewForGithubReview", func(t *testing.T) {
   653  		defaultGithubReview := true
   654  		r := &Rule{
   655  			Options: Options{
   656  				Methods: &common.Methods{
   657  					GithubReview: &defaultGithubReview,
   658  				},
   659  			},
   660  			Requires: Requires{
   661  				Count: 1,
   662  			},
   663  		}
   664  
   665  		assert.True(t, r.Trigger().Matches(common.TriggerCommit), "expected %s to match %s", r.Trigger(), common.TriggerCommit)
   666  		assert.True(t, r.Trigger().Matches(common.TriggerReview), "expected %s to match %s", r.Trigger(), common.TriggerReview)
   667  	})
   668  
   669  	t.Run("triggerReviewForGithubReviewCommentPatterns", func(t *testing.T) {
   670  		r := &Rule{
   671  			Options: Options{
   672  				Methods: &common.Methods{
   673  					GithubReviewCommentPatterns: []common.Regexp{
   674  						common.NewCompiledRegexp(regexp.MustCompile("(?i)nice")),
   675  					},
   676  				},
   677  			},
   678  			Requires: Requires{
   679  				Count: 1,
   680  			},
   681  		}
   682  
   683  		assert.True(t, r.Trigger().Matches(common.TriggerCommit), "expected %s to match %s", r.Trigger(), common.TriggerCommit)
   684  		assert.True(t, r.Trigger().Matches(common.TriggerReview), "expected %s to match %s", r.Trigger(), common.TriggerReview)
   685  	})
   686  
   687  	t.Run("triggerPullRequestForBodyPatterns", func(t *testing.T) {
   688  		r := &Rule{
   689  			Options: Options{
   690  				Methods: &common.Methods{
   691  					BodyPatterns: []common.Regexp{
   692  						common.NewCompiledRegexp(regexp.MustCompile("(?i)nice")),
   693  					},
   694  				},
   695  				IgnoreEditedComments: false,
   696  			},
   697  			Requires: Requires{
   698  				Count: 1,
   699  			},
   700  		}
   701  
   702  		assert.True(t, r.Trigger().Matches(common.TriggerPullRequest), "expected %s to match %s", r.Trigger(), common.TriggerPullRequest)
   703  	})
   704  }
   705  
   706  func newTime(t time.Time) *time.Time {
   707  	return &t
   708  }
   709  

View as plain text