Skip to content

Commit

Permalink
Add custom validators for result name and category and make them matc…
Browse files Browse the repository at this point in the history
…h current floweditor validation
  • Loading branch information
rowanseymour committed Dec 5, 2024
1 parent e8da94f commit 9254c20
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 16 deletions.
2 changes: 1 addition & 1 deletion flows/actions/call_classifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type CallClassifierAction struct {

Classifier *assets.ClassifierReference `json:"classifier" validate:"required"`
Input string `json:"input" validate:"required" engine:"evaluated"`
ResultName string `json:"result_name" validate:"required,max=128"`
ResultName string `json:"result_name" validate:"required,result_name"`
}

// NewCallClassifier creates a new call classifier action
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/call_resthook.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type CallResthookAction struct {
onlineAction

Resthook string `json:"resthook" validate:"required"`
ResultName string `json:"result_name,omitempty" validate:"max=128"`
ResultName string `json:"result_name,omitempty" validate:"omitempty,result_name"`
}

// NewCallResthook creates a new call resthook action
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/call_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ type CallWebhookAction struct {
URL string `json:"url" engine:"evaluated" validate:"required"`
Headers map[string]string `json:"headers,omitempty" engine:"evaluated"`
Body string `json:"body,omitempty" engine:"evaluated"`
ResultName string `json:"result_name,omitempty" validate:"max=128"`
ResultName string `json:"result_name,omitempty" validate:"omitempty,result_name"`
}

// NewCallWebhook creates a new call webhook action
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/open_ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type OpenTicketAction struct {
Topic *assets.TopicReference `json:"topic" validate:"omitempty"`
Body string `json:"body" engine:"evaluated"` // TODO will become "note" in future migration
Assignee *assets.UserReference `json:"assignee" validate:"omitempty"`
ResultName string `json:"result_name" validate:"required,max=128"`
ResultName string `json:"result_name" validate:"required,result_name"`
}

// NewOpenTicket creates a new open ticket action
Expand Down
4 changes: 2 additions & 2 deletions flows/actions/set_run_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ type SetRunResultAction struct {
baseAction
universalAction

Name string `json:"name" validate:"required,max=64"`
Name string `json:"name" validate:"required,result_name"`
Value string `json:"value" engine:"evaluated"`
Category string `json:"category,omitempty" engine:"localized" validate:"max=36"`
Category string `json:"category,omitempty" engine:"localized" validate:"omitempty,result_category"`
}

// NewSetRunResult creates a new set run result action
Expand Down
4 changes: 2 additions & 2 deletions flows/actions/testdata/call_resthook.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"type": "call_resthook",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"resthook": "doesnt-exist",
"result_name": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
"result_name": "12345678901234567890123456789012345678901234567890123456789012345"
},
"read_error": "field 'result_name' must be less than or equal to 128"
"read_error": "field 'result_name' is not a valid result name"
},
{
"description": "NOOP if resthook doesn't exist",
Expand Down
4 changes: 2 additions & 2 deletions flows/actions/testdata/call_webhook.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
"headers": {
"Accept:": "something"
},
"result_name": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
"result_name": "12345678901234567890123456789012345678901234567890123456789012345"
},
"read_error": "field 'result_name' must be less than or equal to 128"
"read_error": "field 'result_name' is not a valid result name"
},
{
"description": "Error events created if URL, header or body contain expression errors",
Expand Down
4 changes: 2 additions & 2 deletions flows/actions/testdata/open_ticket.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
},
"body": "Where are my cookies?",
"assignee": null,
"result_name": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
"result_name": "12345678901234567890123456789012345678901234567890123456789012345"
},
"read_error": "field 'result_name' must be less than or equal to 128"
"read_error": "field 'result_name' is not a valid result name"
},
{
"description": "Error event for invalid topic reference",
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/transfer_airtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type TransferAirtimeAction struct {
onlineAction

Amounts map[string]decimal.Decimal `json:"amounts" validate:"required"`
ResultName string `json:"result_name" validate:"required,max=128"`
ResultName string `json:"result_name" validate:"required,result_name"`
}

// NewTransferAirtime creates a new airtime transfer action
Expand Down
26 changes: 25 additions & 1 deletion flows/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,43 @@ package flows
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"
"time"

"github.com/go-playground/validator/v10"
"github.com/nyaruka/goflow/envs"
"github.com/nyaruka/goflow/excellent/types"
"github.com/nyaruka/goflow/utils"
)

func init() {
resultNameRegex := regexp.MustCompile(`^[a-zA-Z0-9\-_\s]{1,64}$`)
resultCategoryRegex := regexp.MustCompile(`^.{1,36}$`)

utils.RegisterValidatorTag("result_name",
func(fl validator.FieldLevel) bool {
return resultNameRegex.MatchString(fl.Field().String())
},
func(validator.FieldError) string {
return "is not a valid result name"
},
)
utils.RegisterValidatorTag("result_category",
func(fl validator.FieldLevel) bool {
return resultCategoryRegex.MatchString(fl.Field().String())
},
func(validator.FieldError) string {
return "is not a valid result category"
},
)
}

// Result describes a value captured during a run's execution. It might have been implicitly created by a router, or explicitly
// created by a [set_run_result](#action:set_run_result) action.
type Result struct {
Name string `json:"name" validate:"required"`
Name string `json:"name" validate:"required,result_name"`
Value string `json:"value"`
Category string `json:"category,omitempty"`
CategoryLocalized string `json:"category_localized,omitempty"`
Expand Down
4 changes: 2 additions & 2 deletions flows/routers/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ func (r *baseRouter) routeToCategory(run flows.Run, step flows.Step, categoryUUI
type baseRouterEnvelope struct {
Type string `json:"type" validate:"required"`
Wait json.RawMessage `json:"wait,omitempty"`
ResultName string `json:"result_name,omitempty"`
Categories []json.RawMessage `json:"categories,omitempty" validate:"required,min=1"`
ResultName string `json:"result_name,omitempty" validate:"omitempty,result_name"`
Categories []json.RawMessage `json:"categories,omitempty" validate:"required,min=1,dive,result_category"`
}

// ReadRouter reads a router from the given JSON
Expand Down

0 comments on commit 9254c20

Please sign in to comment.