...

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

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

     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 disapproval
    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  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/predicate"
    33  )
    34  
    35  func TestIsDisapproved(t *testing.T) {
    36  	logger := zerolog.New(os.Stdout)
    37  	ctx := logger.WithContext(context.Background())
    38  
    39  	prctx := &pulltest.Context{
    40  		TitleValue: "test: add disapproval predicate test",
    41  		CommentsValue: []*pull.Comment{
    42  			{
    43  				Author:    "disapprover-1",
    44  				Body:      "me no like :-1:",
    45  				CreatedAt: date(0),
    46  			},
    47  			{
    48  				Author:    "disapprover-1",
    49  				Body:      "nah, is fine :+1:",
    50  				CreatedAt: date(1),
    51  			},
    52  			{
    53  				Author:    "disapprover-2",
    54  				Body:      "me also no like :-1:",
    55  				CreatedAt: date(2),
    56  			},
    57  			{
    58  				Author:    "disapprover-3",
    59  				Body:      "and me :-1:",
    60  				CreatedAt: date(3),
    61  			},
    62  			{
    63  				Author:    "revoker-1",
    64  				Body:      "you all wrong :+1:",
    65  				CreatedAt: date(4),
    66  			},
    67  		},
    68  		ReviewsValue: []*pull.Review{
    69  			{
    70  				Author:    "disapprover-4",
    71  				State:     pull.ReviewChangesRequested,
    72  				CreatedAt: date(5),
    73  			},
    74  			{
    75  				Author:    "revoker-2",
    76  				State:     pull.ReviewApproved,
    77  				CreatedAt: date(6),
    78  			},
    79  		},
    80  	}
    81  
    82  	assertDisapproved := func(t *testing.T, p *Policy, expected string) {
    83  		res := p.Evaluate(ctx, prctx)
    84  
    85  		require.NoError(t, res.Error)
    86  
    87  		if assert.Equal(t, common.StatusDisapproved, res.Status, "pull request was not disapproved") {
    88  			assert.Equal(t, expected, res.StatusDescription)
    89  		}
    90  	}
    91  
    92  	assertSkipped := func(t *testing.T, p *Policy, expected string) {
    93  		res := p.Evaluate(ctx, prctx)
    94  
    95  		require.NoError(t, res.Error)
    96  
    97  		if assert.Equal(t, common.StatusSkipped, res.Status, "pull request was incorrectly disapproved") {
    98  			assert.Equal(t, expected, res.StatusDescription)
    99  		}
   100  	}
   101  
   102  	t.Run("skippedWithNoRequires", func(t *testing.T) {
   103  		p := &Policy{}
   104  		assertSkipped(t, p, "No disapproval policy is specified or the policy is empty")
   105  	})
   106  
   107  	t.Run("singleUserDisapproves", func(t *testing.T) {
   108  		p := &Policy{}
   109  		p.Requires.Users = []string{"disapprover-2"}
   110  
   111  		assertDisapproved(t, p, "Disapproved by disapprover-2")
   112  	})
   113  
   114  	t.Run("singleUserDisapprovesAndRevokes", func(t *testing.T) {
   115  		p := &Policy{}
   116  		p.Requires.Users = []string{"disapprover-1"}
   117  
   118  		assertSkipped(t, p, "Disapproval revoked by disapprover-1")
   119  	})
   120  
   121  	t.Run("multipleUsersDisapprove", func(t *testing.T) {
   122  		p := &Policy{}
   123  		p.Requires.Users = []string{"disapprover-2", "disapprover-3"}
   124  
   125  		assertDisapproved(t, p, "Disapproved by disapprover-3")
   126  	})
   127  
   128  	t.Run("otherUserRevokes", func(t *testing.T) {
   129  		p := &Policy{}
   130  		p.Requires.Users = []string{"disapprover-2", "disapprover-3", "revoker-1"}
   131  
   132  		assertSkipped(t, p, "Disapproval revoked by revoker-1")
   133  	})
   134  
   135  	t.Run("singleUserDisapprovesWithReview", func(t *testing.T) {
   136  		p := &Policy{}
   137  		p.Requires.Users = []string{"disapprover-4"}
   138  
   139  		assertDisapproved(t, p, "Disapproved by disapprover-4")
   140  	})
   141  
   142  	t.Run("otherUserRevokesWithReview", func(t *testing.T) {
   143  		p := &Policy{}
   144  		p.Requires.Users = []string{"disapprover-4", "revoker-2"}
   145  
   146  		assertSkipped(t, p, "Disapproval revoked by revoker-2")
   147  	})
   148  
   149  	t.Run("reviewsInteractWithComments", func(t *testing.T) {
   150  		p := &Policy{}
   151  		p.Requires.Users = []string{"disapprover-1", "revoker-1", "disapprover-4"}
   152  
   153  		assertDisapproved(t, p, "Disapproved by disapprover-4")
   154  	})
   155  
   156  	t.Run("predicateDisapproves", func(t *testing.T) {
   157  		p := &Policy{}
   158  		p.Predicates = predicate.Predicates{
   159  			Title: &predicate.Title{
   160  				NotMatches: []common.Regexp{
   161  					common.NewCompiledRegexp(regexp.MustCompile("^(fix|feat|docs)")),
   162  				},
   163  			},
   164  		}
   165  
   166  		assertDisapproved(t, p, "PR Title doesn't match a NotMatch pattern")
   167  	})
   168  
   169  	t.Run("predicateDoesNotDisapprove", func(t *testing.T) {
   170  		p := &Policy{}
   171  		p.Predicates = predicate.Predicates{
   172  			Title: &predicate.Title{
   173  				NotMatches: []common.Regexp{
   174  					common.NewCompiledRegexp(regexp.MustCompile("^(fix|feat|docs|test)")),
   175  				},
   176  			},
   177  		}
   178  
   179  		assertSkipped(t, p, "No disapproval policy is specified or the policy is empty")
   180  	})
   181  }
   182  
   183  func date(hour int) time.Time {
   184  	return time.Date(2018, 6, 29, hour, 0, 0, 0, time.UTC)
   185  }
   186  

View as plain text