From cb6d90d6e2cc0c58b1db3fe5377eba7c2b4c7481 Mon Sep 17 00:00:00 2001 From: Zelalem Mekonen Date: Thu, 24 Nov 2022 15:13:07 +0300 Subject: [PATCH] feat: improve assign reviewer command (#433) --- engine/commands/assignReviewer.go | 64 ++++++++++---- engine/commands/assignReviewer_test.go | 118 +++++++++++++++---------- engine/commands/commands.go | 32 ++++++- engine/exec.go | 51 ++++++++--- engine/exec_test.go | 20 +++-- go.mod | 5 +- go.sum | 11 +-- utils/pr.go | 13 ++- utils/pr_test.go | 52 +++++++++++ 9 files changed, 270 insertions(+), 96 deletions(-) diff --git a/engine/commands/assignReviewer.go b/engine/commands/assignReviewer.go index 5e574dbd7..495584414 100644 --- a/engine/commands/assignReviewer.go +++ b/engine/commands/assignReviewer.go @@ -8,39 +8,69 @@ import ( "errors" "fmt" "regexp" - "strconv" "strings" + + "github.com/spf13/cobra" ) -var assignReviewerRegex = regexp.MustCompile(`^\/reviewpad assign-reviewers\s+((?:[a-zA-Z0-9\-]+[a-zA-Z0-9])(?:,\s*[a-zA-Z0-9\-]+[a-zA-Z0-9])*)(?:\s+(\d+))?(?:\s+(random|round-robin|reviewpad))?$`) +func AssignReviewerCmd() *cobra.Command { + assignReviewerCmd := &cobra.Command{ + Use: "assign-reviewers", + Short: "Assign reviewers to a pull request", + Long: "Assigns a defined amount of reviewers to the pull request from the provided list of reviewers.", + SilenceUsage: true, + SilenceErrors: true, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("accepts 1 arg(s), received %d", len(args)) + } -func AssignReviewer(matches []string) ([]string, error) { - var err error + if !regexp.MustCompile(`^([a-zA-Z0-9\-]+[a-zA-Z0-9])(,[a-zA-Z0-9\-]+[a-zA-Z0-9])*$`).MatchString(args[0]) { + return errors.New("reviewers must be a list of comma separated valid github usernames") + } - if len(matches) < 2 { - return nil, errors.New("invalid assign reviewer command") + return nil + }, + RunE: AssignReviewer, } - reviewersList := strings.Split(strings.ReplaceAll(matches[1], " ", ""), ",") + flags := assignReviewerCmd.Flags() + + flags.StringP("review-policy", "p", "reviewpad", "The policy followed for reviewer assignment. The valid values can only be: random, round-robin, reviewpad. By default, the policy is reviewpad.") + + flags.Uint8P("total-reviewers", "t", 0, "The total number of reviewers to assign to. By default, it assigns to all reviewers.") + + return assignReviewerCmd +} + +func AssignReviewer(cmd *cobra.Command, args []string) error { + flags := cmd.Flags() + + reviewersList := strings.Split(strings.ReplaceAll(args[0], " ", ""), ",") availableReviewers := `"` + strings.Join(reviewersList, `","`) + `"` - totalRequiredReviewers := len(reviewersList) + totalRequiredReviewers, err := flags.GetUint8("total-reviewers") + if err != nil { + return err + } - if len(matches) > 2 && matches[2] != "" { - totalRequiredReviewers, err = strconv.Atoi(matches[2]) - if err != nil { - return nil, err - } + if totalRequiredReviewers == 0 { + totalRequiredReviewers = uint8(len(reviewersList)) } - policy := "reviewpad" + policy, err := flags.GetString("review-policy") + if err != nil { + return err + } - if len(matches) > 3 && matches[3] != "" { - policy = matches[3] + if policy != "reviewpad" && policy != "round-robin" && policy != "random" { + return fmt.Errorf("invalid review policy specified: %s", policy) } action := fmt.Sprintf(`$assignReviewer([%s], %d, %q)`, availableReviewers, totalRequiredReviewers, policy) - return []string{action}, nil + cmd.Print(action) + + return nil } diff --git a/engine/commands/assignReviewer_test.go b/engine/commands/assignReviewer_test.go index e758863e9..5ca417923 100644 --- a/engine/commands/assignReviewer_test.go +++ b/engine/commands/assignReviewer_test.go @@ -5,8 +5,8 @@ package commands_test import ( + "bytes" "errors" - "strconv" "testing" "github.com/reviewpad/reviewpad/v3/engine/commands" @@ -15,82 +15,108 @@ import ( func TestAssignReviewer(t *testing.T) { testCases := map[string]struct { - matches []string - wantActions []string - wantErr error + args []string + wantAction string + wantErr error }{ - "when arguments are empty": { - matches: []string{}, - wantErr: errors.New("invalid assign reviewer command"), - }, "when invalid number of arguments": { - matches: []string{ - "/reviewpad assign-reviewers", + args: []string{ + "john", + "jane", + }, + wantErr: errors.New("accepts 1 arg(s), received 2"), + }, + "when list of reviewers has invalid github username": { + args: []string{ + "john2,jane-", }, - wantErr: errors.New("invalid assign reviewer command"), + wantErr: errors.New("reviewers must be a list of comma separated valid github usernames"), + }, + "when review policy is invalid": { + args: []string{ + "jane,john", + "--total-reviewers=1", + "--review-policy=unknown", + }, + wantErr: errors.New("invalid review policy specified: unknown"), }, "when number of reviewers is not a number": { - matches: []string{ - "/reviewpad assign-reviewers john, jane, john2, jane27 z random", - "john, jane, john2, jane27", - "z", - "random", + args: []string{ + "john,jane,john2,jane27", + "--total-reviewers=z", }, - wantErr: &strconv.NumError{Func: "Atoi", Num: "z", Err: errors.New("invalid syntax")}, + wantErr: errors.New("invalid argument \"z\" for \"-t, --total-reviewers\" flag: strconv.ParseUint: parsing \"z\": invalid syntax"), }, "when missing number of reviewers and policy": { - matches: []string{ - "/reviewpad assign-reviewers john", + args: []string{ "john", - "", - "", }, - wantActions: []string{`$assignReviewer(["john"], 1, "reviewpad")`}, + wantAction: `$assignReviewer(["john"], 1, "reviewpad")`, }, "when missing policy": { - matches: []string{ - "/reviewpad assign-reviewers john-123, jane 1", - "john-123, jane", - "1", - "", + args: []string{ + "john-123,jane", + "--total-reviewers=5", }, - wantActions: []string{`$assignReviewer(["john-123","jane"], 1, "reviewpad")`}, + wantAction: `$assignReviewer(["john-123","jane"], 5, "reviewpad")`, }, "when only one reviewer is provided": { - matches: []string{ - "/reviewpad assign-reviewers john-123-jane 1 reviewpad", + args: []string{ "john-123-jane", - "1", - "reviewpad", + "--total-reviewers=1", + "--review-policy=reviewpad", }, - wantActions: []string{`$assignReviewer(["john-123-jane"], 1, "reviewpad")`}, + wantAction: `$assignReviewer(["john-123-jane"], 1, "reviewpad")`, }, - "when only two reviewers is provided": { - matches: []string{ - "/reviewpad assign-reviewers jane, john 2 random", - "jane, john", + "when only two reviewers are provided": { + args: []string{ + "jane,john", + "--total-reviewers", "2", + "--review-policy", "random", }, - wantActions: []string{`$assignReviewer(["jane","john"], 2, "random")`}, + wantAction: `$assignReviewer(["jane","john"], 2, "random")`, }, "when number of provided reviewers is greater than requested reviewers": { - matches: []string{ - "/reviewpad assign-reviewers jane, john 1 reviewpad", - "jane, john", - "1", - "reviewpad", + args: []string{ + "jane,john", + "--total-reviewers=1", + "--review-policy", + "round-robin", }, - wantActions: []string{`$assignReviewer(["jane","john"], 1, "reviewpad")`}, + wantAction: `$assignReviewer(["jane","john"], 1, "round-robin")`, + }, + "when number of provided reviewers is less than requested reviewers": { + args: []string{ + "jane,john,jane123", + "--total-reviewers", + "5", + "--review-policy=round-robin", + }, + wantAction: `$assignReviewer(["jane","john","jane123"], 5, "round-robin")`, + }, + "when missing number of reviewers": { + args: []string{ + "jane,john,jane123", + "--review-policy=reviewpad", + }, + wantAction: `$assignReviewer(["jane","john","jane123"], 3, "reviewpad")`, }, } for name, test := range testCases { t.Run(name, func(t *testing.T) { - actions, err := commands.AssignReviewer(test.matches) + out := new(bytes.Buffer) + cmd := commands.AssignReviewerCmd() + + cmd.SetOut(out) + cmd.SetArgs(test.args) + + err := cmd.Execute() assert.Equal(t, test.wantErr, err) - assert.Equal(t, test.wantActions, actions) + assert.Equal(t, test.wantAction, out.String()) }) } } diff --git a/engine/commands/commands.go b/engine/commands/commands.go index b43f1158a..0917719bd 100644 --- a/engine/commands/commands.go +++ b/engine/commands/commands.go @@ -5,9 +5,35 @@ package commands import ( - "regexp" + "errors" + "io" + + "github.com/spf13/cobra" ) -var Commands = map[*regexp.Regexp]func(matches []string) ([]string, error){ - assignReviewerRegex: AssignReviewer, +func NewCommands(out io.Writer, args []string) *cobra.Command { + root := &cobra.Command{ + Use: "/reviewpad", + Hidden: true, + CompletionOptions: cobra.CompletionOptions{ + DisableDefaultCmd: true, + }, + SilenceUsage: true, + SilenceErrors: true, + RunE: func(cmd *cobra.Command, args []string) error { + cmd.Flags().Lookup("help").Hidden = true + return errors.New(cmd.UsageString()) + }, + DisableFlagParsing: true, + } + + root.SetHelpCommand(&cobra.Command{Hidden: true}) + + root.SetOut(out) + + root.SetArgs(args) + + root.AddCommand(AssignReviewerCmd()) + + return root } diff --git a/engine/exec.go b/engine/exec.go index 172d0fe74..6d4ff106f 100644 --- a/engine/exec.go +++ b/engine/exec.go @@ -5,11 +5,15 @@ package engine import ( + "bytes" "fmt" "log" + "strings" "github.com/google/go-github/v48/github" + "github.com/mattn/go-shellwords" "github.com/reviewpad/reviewpad/v3/engine/commands" + "github.com/reviewpad/reviewpad/v3/utils" "github.com/reviewpad/reviewpad/v3/utils/fmtio" ) @@ -133,21 +137,15 @@ func Eval(file *ReviewpadFile, env *Env) (*Program, error) { program := BuildProgram(make([]*Statement, 0)) // process commands - if env.EventData != nil && env.EventData.EventName == "issue_comment" { - for r, command := range commands.Commands { - matches := r.FindAllStringSubmatch(*env.EventData.Comment.Body, 1) - - if len(matches) == 1 { - actions, err := command(matches[0]) - if err != nil { - return nil, err - } + if utils.IsReviewpadCommand(env.EventData) { + action, err := processCommand(env, *env.EventData.Comment.Body) + if err != nil { + return nil, err + } - program.append(actions) + program.append([]string{action}) - return program, nil - } - } + return program, nil } // process rules @@ -257,3 +255,30 @@ func Eval(file *ReviewpadFile, env *Env) (*Program, error) { return program, nil } + +func processCommand(env *Env, comment string) (string, error) { + out := new(bytes.Buffer) + comment = strings.TrimPrefix(comment, "/reviewpad") + + args, err := shellwords.Parse(comment) + if err != nil { + return "", err + } + + root := commands.NewCommands(out, args) + + err = root.Execute() + if err != nil { + comment := fmt.Sprintf("%s\n```\n🚫 error\n\n%s\n```", *env.EventData.Comment.Body, err.Error()) + + if _, _, err := env.GithubClient.EditComment(env.Ctx, env.TargetEntity.Owner, env.TargetEntity.Repo, *env.EventData.Comment.ID, &github.IssueComment{ + Body: github.String(comment), + }); err != nil { + return "", err + } + + return "", err + } + + return out.String(), nil +} diff --git a/engine/exec_test.go b/engine/exec_test.go index 48d516851..313e78d3f 100644 --- a/engine/exec_test.go +++ b/engine/exec_test.go @@ -239,11 +239,6 @@ func TestEval(t *testing.T) { }, "when invalid assign reviewer command": { inputReviewpadFilePath: "testdata/exec/reviewpad_with_valid_group.yml", - wantProgram: engine.BuildProgram( - []*engine.Statement{ - engine.BuildStatement(`$addLabel("test-valid-group")`), - }, - ), targetEntity: &handler.TargetEntity{ Kind: engine.DefaultMockTargetEntity.Kind, Number: engine.DefaultMockTargetEntity.Number, @@ -258,6 +253,13 @@ func TestEval(t *testing.T) { Body: github.String("/reviewpad assign-reviewers john, jane, 1 random"), }, }, + clientOptions: []mock.MockBackendOption{ + mock.WithRequestMatch( + mock.PatchReposIssuesCommentsByOwnerByRepoByCommentId, + &github.IssueComment{}, + ), + }, + wantErr: "accepts 1 arg(s), received 4", }, "when missing policy in assign reviewer command args": { inputReviewpadFilePath: "testdata/exec/reviewpad_with_valid_group.yml", @@ -277,7 +279,7 @@ func TestEval(t *testing.T) { EventAction: "created", Comment: &github.IssueComment{ ID: github.Int64(1), - Body: github.String("/reviewpad assign-reviewers john 1"), + Body: github.String("/reviewpad assign-reviewers john -t 1"), }, }, clientOptions: []mock.MockBackendOption{ @@ -305,7 +307,7 @@ func TestEval(t *testing.T) { EventAction: "created", Comment: &github.IssueComment{ ID: github.Int64(1), - Body: github.String("/reviewpad assign-reviewers jane-12, john01 1 random"), + Body: github.String("/reviewpad assign-reviewers jane-12,john01 --total-reviewers 1 -p random"), }, }, }, @@ -327,7 +329,7 @@ func TestEval(t *testing.T) { EventAction: "created", Comment: &github.IssueComment{ ID: github.Int64(1), - Body: github.String("/reviewpad assign-reviewers john, jane 1 reviewpad"), + Body: github.String("/reviewpad assign-reviewers john,jane -t 1 --review-policy reviewpad"), }, }, }, @@ -349,7 +351,7 @@ func TestEval(t *testing.T) { EventAction: "created", Comment: &github.IssueComment{ ID: github.Int64(1), - Body: github.String("/reviewpad assign-reviewers john, johnny 1 round-robin"), + Body: github.String("/reviewpad assign-reviewers john,johnny -t 1 -p round-robin"), }, }, }, diff --git a/go.mod b/go.mod index 9a04ad5c1..cbdca19dc 100644 --- a/go.mod +++ b/go.mod @@ -13,13 +13,14 @@ require ( github.com/jarcoal/httpmock v1.2.0 github.com/jinzhu/copier v0.3.5 github.com/libgit2/git2go/v31 v31.7.9 + github.com/mattn/go-shellwords v1.0.12 github.com/migueleliasweb/go-github-mock v0.0.10 github.com/mitchellh/mapstructure v1.5.0 github.com/reviewpad/api/go v0.0.0-20220824160655-7aaf235bcfa2 github.com/reviewpad/go-conventionalcommits v0.10.0 github.com/shurcooL/githubv4 v0.0.0-20220520033151-0b4e3294ff00 github.com/sirupsen/logrus v1.9.0 - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.0 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 @@ -33,7 +34,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 0e608f295..d9d518f82 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= @@ -50,6 +50,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libgit2/git2go/v31 v31.7.9 h1:RUDiYm7+i3GY414acI31oDD8x5P0PZyWeZZfwpPuynE= github.com/libgit2/git2go/v31 v31.7.9/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk= github.com/migueleliasweb/go-github-mock v0.0.10 h1:VTaNa4eYzkRpnZ7Fqop7Jldgh7vsUsgnKWXDOnAvm3k= github.com/migueleliasweb/go-github-mock v0.0.10/go.mod h1:mD5w+9J3oBBMLr7uD6owEYlYBAL8tZd+BA7iGjI4EU8= @@ -70,8 +72,8 @@ github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dk github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -139,7 +141,6 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/utils/pr.go b/utils/pr.go index 10f5558b1..accdff1d5 100644 --- a/utils/pr.go +++ b/utils/pr.go @@ -4,8 +4,19 @@ package utils -import "github.com/reviewpad/reviewpad/v3/handler" +import ( + "strings" + + "github.com/reviewpad/reviewpad/v3/handler" +) func IsPullRequestReadyForReportMetrics(eventData *handler.EventData) bool { return eventData != nil && eventData.EventName == "pull_request" && eventData.EventAction == "closed" } + +func IsReviewpadCommand(eventData *handler.EventData) bool { + return eventData != nil && + eventData.EventName == "issue_comment" && + eventData.Comment.Body != nil && + strings.HasPrefix(*eventData.Comment.Body, "/reviewpad") +} diff --git a/utils/pr_test.go b/utils/pr_test.go index ded1e22e4..0f4509104 100644 --- a/utils/pr_test.go +++ b/utils/pr_test.go @@ -7,6 +7,7 @@ package utils_test import ( "testing" + "github.com/google/go-github/v48/github" "github.com/reviewpad/reviewpad/v3/handler" "github.com/reviewpad/reviewpad/v3/utils" "github.com/stretchr/testify/assert" @@ -49,3 +50,54 @@ func TestIsPullRequestReadyForReportMetrics(t *testing.T) { }) } } + +func TestIsReviewPadCommand(t *testing.T) { + tests := map[string]struct { + eventData *handler.EventData + wantVal bool + }{ + "when target entity is nil": { + wantVal: false, + }, + "when event name is pull request review": { + wantVal: false, + eventData: &handler.EventData{ + EventName: "pull_request_review", + }, + }, + "when comment body is nil": { + wantVal: false, + eventData: &handler.EventData{ + EventName: "issue_comment", + Comment: &github.IssueComment{ + Body: nil, + }, + }, + }, + "when comment body doesn't have /reviewpad prefix": { + wantVal: false, + eventData: &handler.EventData{ + EventName: "issue_comment", + Comment: &github.IssueComment{ + Body: github.String("some comment"), + }, + }, + }, + "when event name is issue comment and body has /reviewpad prefix": { + wantVal: true, + eventData: &handler.EventData{ + EventName: "issue_comment", + Comment: &github.IssueComment{ + Body: github.String("/reviewpad"), + }, + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + val := utils.IsReviewpadCommand(test.eventData) + assert.Equal(t, test.wantVal, val) + }) + } +}