Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More validation #1341

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion flows/actions/add_contact_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type AddContactGroupsAction struct {
baseAction
universalAction

Groups []*assets.GroupReference `json:"groups" validate:"required,dive"`
Groups []*assets.GroupReference `json:"groups" validate:"required,max=100,dive"`
}

// NewAddContactGroups creates a new add to groups action
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/add_input_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type AddInputLabelsAction struct {
baseAction
interactiveAction

Labels []*assets.LabelReference `json:"labels" validate:"required,dive"`
Labels []*assets.LabelReference `json:"labels" validate:"required,max=100,dive"`
}

// NewAddInputLabels creates a new add labels action
Expand Down
6 changes: 3 additions & 3 deletions flows/actions/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ func (a *otherContactsAction) resolveRecipients(run flows.Run, logEvent flows.Ev

// utility struct for actions which create a message
type createMsgAction struct {
Text string `json:"text" validate:"required" engine:"localized,evaluated"`
Attachments []string `json:"attachments,omitempty" validate:"dive,attachment" engine:"localized,evaluated"`
QuickReplies []string `json:"quick_replies,omitempty" engine:"localized,evaluated"`
Text string `json:"text" validate:"required" engine:"localized,evaluated"`
Attachments []string `json:"attachments,omitempty" validate:"max=10,dive,attachment" engine:"localized,evaluated"`
QuickReplies []string `json:"quick_replies,omitempty" validate:"max=10,dive,max=64" engine:"localized,evaluated"`
}

// helper function for actions that have a set of group references that must be resolved to actual groups
Expand Down
2 changes: 1 addition & 1 deletion flows/actions/set_run_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type SetRunLocalAction struct {
baseAction
universalAction

Local string `json:"local" validate:"required,local_ref"`
Local string `json:"local" validate:"required,local_ref"`
Value string `json:"value,omitempty" engine:"evaluated" validate:"max=1000"`
Operation LocalOperation `json:"operation" validate:"required,eq=set|eq=increment|eq=clear"`
}
Expand Down
14 changes: 14 additions & 0 deletions flows/actions/testdata/add_contact_groups.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
[
{
"description": "Read fails when invalid group reference",
"action": {
"type": "add_contact_groups",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"groups": [
{
"uuid": "x",
"name": "1"
}
]
},
"read_error": "field 'groups[0].uuid' must be a valid UUID4"
},
{
"description": "Error event and NOOP for missing group",
"action": {
Expand Down
42 changes: 34 additions & 8 deletions flows/actions/testdata/send_msg.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
[
{
"description": "Read fails when text is empty",
"description": "Read fails when text is empty or too many attachments",
"action": {
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "",
"attachments": [
"image:http://example.com/red.jpg"
"image:http://example.com/1.jpg",
"image:http://example.com/2.jpg",
"image:http://example.com/3.jpg",
"image:http://example.com/4.jpg",
"image:http://example.com/5.jpg",
"image:http://example.com/6.jpg",
"image:http://example.com/7.jpg",
"image:http://example.com/8.jpg",
"image:http://example.com/9.jpg",
"image:http://example.com/10.jpg",
"image:http://example.com/11.jpg"
],
"quick_replies": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11"
]
},
"read_error": "field 'text' is required"
"read_error": "field 'text' is required, field 'attachments' must have a maximum of 10 items, field 'quick_replies' must have a maximum of 10 items"
},
{
"description": "Read fails when topic is invalid",
"description": "Read fails when topic is invalid or a quick reply is too long",
"action": {
"type": "send_msg",
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "hi there",
"topic": "spam"
"topic": "spam",
"quick_replies": [
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
]
},
"read_error": "field 'topic' is not a valid message topic"
"read_error": "field 'quick_replies[0]' must be less than or equal to 64, field 'topic' is not a valid message topic"
},
{
"description": "Error events if msg text, attachments and quick replies have expression errors",
Expand Down Expand Up @@ -197,7 +223,7 @@
"text": "Hi there",
"quick_replies": [
"yes",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
"@(repeat(\"1234567890\", 10))"
]
},
"events": [
Expand All @@ -218,7 +244,7 @@
"text": "yes"
},
{
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed ..."
"text": "1234567890123456789012345678901234567890123456789012345678901..."
}
],
"locale": "eng-US"
Expand Down
14 changes: 11 additions & 3 deletions flows/definition/flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func TestBrokenFlows(t *testing.T) {
path string
err string
}{
{
"invalid_name.json",
"unable to read flow header: field 'name' must be less than or equal to 64",
},
{
"null_node.json",
"field 'nodes[1]' is required",
Expand Down Expand Up @@ -96,7 +100,7 @@ func TestBrokenFlows(t *testing.T) {
},
{
"invalid_case_category.json",
"invalid node[uuid=a58be63b-907d-4a1a-856b-0bb5579d7507]: invalid router: case category 37d8813f-1402-4ad2-9cc2-e9054a96525b is not a valid category",
"invalid node[uuid=a58be63b-907d-4a1a-856b-0bb5579d7507]: invalid router: invalid case[uuid=5d6abc80-39e7-4620-9988-a2447bffe526]: category 37d8813f-1402-4ad2-9cc2-e9054a96525b is not a valid category",
},
{
"invalid_exit_dest.json",
Expand All @@ -116,7 +120,11 @@ func TestBrokenFlows(t *testing.T) {
},
{
"too_many_categories.json",
"invalid node[uuid=a58be63b-907d-4a1a-856b-0bb5579d7507]: invalid router: router can't have more than 100 categories (has 101)",
"invalid node[uuid=a58be63b-907d-4a1a-856b-0bb5579d7507]: invalid router: can't have more than 100 categories (has 101)",
},
{
"too_many_cases.json",
"invalid node[uuid=a58be63b-907d-4a1a-856b-0bb5579d7507]: invalid router: can't have more than 100 cases (has 101)",
},
}

Expand Down Expand Up @@ -399,7 +407,7 @@ func TestReferences(t *testing.T) {
func TestReadFlow(t *testing.T) {
// try reading something without a flow header
_, err := definition.ReadFlow([]byte(`{"nodes":[]}`), nil)
assert.EqualError(t, err, "unable to read flow header: field 'uuid' is required, field 'spec_version' is required")
assert.EqualError(t, err, "unable to read flow header: field 'uuid' is required, field 'name' is required, field 'spec_version' is required")

// try reading a definition with a newer major version
_, err = definition.ReadFlow([]byte(`{
Expand Down
4 changes: 2 additions & 2 deletions flows/definition/migrations/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func Registered() map[*semver.Version]MigrationFunc {

// Header13 is the set of fields common to all 13+ flow spec versions
type Header13 struct {
UUID assets.FlowUUID `json:"uuid" validate:"required,uuid4"`
Name string `json:"name"`
UUID assets.FlowUUID `json:"uuid" validate:"required,uuid4"`
Name string `json:"name" validate:"required,max=64"`
SpecVersion *semver.Version `json:"spec_version" validate:"required"`
}

Expand Down
4 changes: 3 additions & 1 deletion flows/definition/migrations/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,18 @@ func TestMigrateToLatest(t *testing.T) {
assert.Nil(t, migrated)

_, err = migrations.MigrateToLatest([]byte(`{}`), migrations.DefaultConfig)
assert.EqualError(t, err, "unable to read flow header: field 'uuid' is required, field 'spec_version' is required")
assert.EqualError(t, err, "unable to read flow header: field 'uuid' is required, field 'name' is required, field 'spec_version' is required")

migrated, err = migrations.MigrateToLatest([]byte(`{
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02",
"name": "Empty Flow",
"spec_version": "13.0"
}`), migrations.DefaultConfig)
require.NoError(t, err)

expected := fmt.Sprintf(`{
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02",
"name": "Empty Flow",
"spec_version": "%s",
"language": "und"
}`, definition.CurrentSpecVersion)
Expand Down
12 changes: 12 additions & 0 deletions flows/definition/testdata/broken_flows/invalid_name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"flows": [
{
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02",
"name": "Test flow lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
"spec_version": "13.2.0",
"language": "eng",
"type": "messaging",
"nodes": []
}
]
}
Loading