Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Mar 2, 2018
1 parent 7dad003 commit 331f884
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 32 deletions.
2 changes: 1 addition & 1 deletion cmd/docgen/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func createExampleSession(assetsDef string) (flows.Session, error) {
return nil, err
}

trigger := triggers.NewManualTrigger(nil, contact, flow, time.Now())
trigger := triggers.NewManualTrigger(nil, contact, flow, utils.EmptyJSONFragment, time.Now())

// and start the example flow
err = session.Start(trigger, nil)
Expand Down
2 changes: 1 addition & 1 deletion cmd/flowrunner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func main() {
log.Fatal("error accessing flow: ", err)
}

trigger := triggers.NewManualTrigger(env, contact, flow, time.Now())
trigger := triggers.NewManualTrigger(env, contact, flow, utils.EmptyJSONFragment, time.Now())

// and start our flow
err = session.Start(trigger, nil)
Expand Down
12 changes: 11 additions & 1 deletion flows/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package flows
import (
"encoding/json"
"fmt"

"time"

"github.com/nyaruka/gocommon/urns"
Expand All @@ -23,6 +22,17 @@ type Contact struct {
channel Channel
}

// NewContact returns a new contact
func NewContact(uuid ContactUUID, name string, language utils.Language, timezone *time.Location) *Contact {
return &Contact{
uuid: uuid,
name: name,
language: language,
timezone: timezone,
groups: NewGroupList([]*Group{}),
}
}

// Clone creates a copy of this contact
func (c *Contact) Clone() *Contact {
return &Contact{
Expand Down
2 changes: 1 addition & 1 deletion flows/engine/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package engine

import (
"encoding/json"
"github.com/nyaruka/goflow/flows"
"io/ioutil"
"reflect"
"testing"

"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/flows/actions"
"github.com/stretchr/testify/assert"
)
Expand Down
95 changes: 95 additions & 0 deletions flows/engine/session_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package engine

import (
"encoding/json"
"io/ioutil"
"testing"

"github.com/nyaruka/goflow/excellent"
"github.com/nyaruka/goflow/flows/events"
"github.com/nyaruka/goflow/flows/triggers"
"github.com/nyaruka/goflow/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type testRequest struct {
Trigger *utils.TypedEnvelope `json:"trigger"`
Events []*utils.TypedEnvelope `json:"events"`
}

func TestEvaluateTemplate(t *testing.T) {
tests := []struct {
template string
expected string
hasError bool
}{
{"@contact.uuid", "ba96bf7f-bc2a-4873-a7c7-254d1927c4e3", false},
{"@contact.name", "Ben Haggerty", false},
{"@contact.first_name", "Ben", false},
{"@contact.language", "eng", false},
{"@contact.timezone", "America/Guayaquil", false},
{"@contact.urns", "tel:+12065551212", false}, // TODO should be list
{"@contact.urns.tel", "tel:+12065551212", false},
{"@contact.urns.0", "tel:+12065551212", false},
{"@contact.urns.1", "facebook:1122334455667788", false},
{"@(format_urn(contact.urns.0))", "(206) 555-1212", false},
{"@contact.groups", "Survey Audience", false}, // TODO should be list
{"@contact.fields.state", "Azuay", false},
{"@contact.fields.favorite_icecream", "", false}, // TODO should be error
{"@(has_error(contact.fields.favorite_icecream))", "false", false}, // TODO should be true

{"@run.input", "Hi there\nhttp://s3.amazon.com/bucket/test_en.jpg?a=Azuay", false},
{"@run.input.text", "Hi there", false},
{"@run.input.attachments", "", false}, // TODO should be list
{"@run.input.attachments.0", "http://s3.amazon.com/bucket/test_en.jpg?a=Azuay", false},
{"@run.input.created_on", "2000-01-01T00:00:00.000000Z", false},
{"@run.input.channel.name", "Nexmo", false},
{"@run.results", "", false}, // TODO should be empty dict?
{"@run.results.favorite_icecream", "", false}, // TODO should be error
{"@(has_error(run.results.favorite_icecream))", "false", false}, // TODO should be true
{"@run.exited_on", "", false},

{"@trigger.params", "{\n \"coupons\": [\n {\n \"code\": \"AAA-BBB-CCC\",\n \"expiration\": \"2000-01-01T00:00:00.000000000-00:00\"\n }\n ]\n }", false},
{"@trigger.params.coupons.0.code", "AAA-BBB-CCC", false},
}

assetsJSON, err := ioutil.ReadFile("testdata/assets.json")
require.NoError(t, err)

// build our session
assetCache := NewAssetCache(100, 5, "testing/1.0")
err = assetCache.Include(assetsJSON)
require.NoError(t, err)

session := NewSession(assetCache, NewMockAssetServer())
require.NoError(t, err)

// read trigger from file
requestJSON, err := ioutil.ReadFile("testdata/trigger.json")
require.NoError(t, err)

testRequest := testRequest{}
err = json.Unmarshal(requestJSON, &testRequest)
require.NoError(t, err)

trigger, err := triggers.ReadTrigger(session, testRequest.Trigger)
require.NoError(t, err)

initialEvents, err := events.ReadEvents(testRequest.Events)
require.NoError(t, err)

session.Start(trigger, initialEvents)
run := session.Runs()[0]

for _, test := range tests {
eval, err := excellent.EvaluateTemplateAsString(session.Environment(), run.Context(), test.template, false)
if err != nil {
assert.True(t, test.hasError, "Received error evaluating '%s': %s", test.template, err)
} else {
assert.False(t, test.hasError, "Did not receive error evaluating '%s'", test.template)
}

assert.Equal(t, eval, test.expected, "Actual '%s' does not match expected '%s' evaluating template: '%s'", eval, test.expected, test.template)
}
}
75 changes: 56 additions & 19 deletions flows/engine/testdata/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,46 @@
"name": "Twilio Channel"
}
}
]
],
"wait": {
"type": "msg",
"timeout": 600
}
}
]
}
},
{
"type": "channel",
"url": "http://testserver/assets/channel/57f1078f-88aa-46f4-a59a-948a5739c03d",
"content": {
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d",
"name": "Twilio Channel",
"address": "+12345671111",
"type": "T"
}
"type": "field",
"url": "http://testserver/assets/field",
"content": [
{
"key": "first_name",
"label": "First Name",
"value_type": "text"
},
{
"key": "activation_token",
"label": "Activation Token",
"value_type": "text"
},
{
"key": "gender",
"label": "Gender",
"value_type": "text"
},
{
"key": "state",
"label": "State",
"value_type": "text"
},
{
"key": "birth_date",
"label": "birth Date",
"value_type": "text"
}
],
"is_set": true
},
{
"type": "group",
Expand All @@ -69,21 +95,28 @@
{
"uuid": "2aad21f6-30b7-42c5-bd7f-1b720c154817",
"name": "Survey Audience"
},
{
"uuid": "d7ff4872-9238-452f-9d38-2f558fea89e0",
"name": "Azuay State"
},
{
"uuid": "d7ff4872-9238-452f-9d38-2f558fea89e0",
"name": "Males",
"query": "gender = Male"
}
],
"is_set": true
},
{
"type": "field",
"url": "http://testserver/assets/field",
"content": [
{
"key": "first_name",
"label": "First Name",
"value_type": "text"
}
],
"is_set": true
"type": "channel",
"url": "http://testserver/assets/channel/57f1078f-88aa-46f4-a59a-948a5739c03d",
"content": {
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d",
"name": "Nexmo",
"address": "+12345671111",
"type": "NX"
}
},
{
"type": "label",
Expand All @@ -92,6 +125,10 @@
{
"uuid": "3f65d88a-95dc-4140-9451-943e94e06fea",
"name": "Spam"
},
{
"uuid": "b017c07a-d35b-4da4-8917-3bf8bff80168",
"name": "Azuay Messages"
}
],
"is_set": true
Expand Down
65 changes: 65 additions & 0 deletions flows/engine/testdata/trigger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"events": [
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"msg": {
"uuid": "84f8a3cf-0f2c-4881-9502-2d7b114bf01f",
"channel": {
"name": "Nexmo",
"uuid": "57f1078f-88aa-46f4-a59a-948a5739c03d"
},
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"text": "Hi there",
"attachments": [
"image/jpeg:http://s3.amazon.com/bucket/test_en.jpg?a=Azuay"
],
"urn": "tel:+12065551212"
},
"type": "msg_received"
}
],
"trigger": {
"type": "manual",
"triggered_on": "2000-01-01T00:00:00.000000000-00:00",
"contact": {
"uuid": "ba96bf7f-bc2a-4873-a7c7-254d1927c4e3",
"name": "Ben Haggerty",
"language": "eng",
"timezone": "America/Guayaquil",
"fields": {
"first_name": {
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"value": "Ben"
},
"state": {
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"value": "Azuay"
}
},
"group_uuids": ["d7ff4872-9238-452f-9d38-2f558fea89e0"],
"urns": [
"tel:+12065551212",
"facebook:1122334455667788",
"mailto:ben@macklemore"
]
},
"environment": {
"date_format": "yyyy-MM-dd",
"languages": [],
"time_format": "hh:mm",
"timezone": "America/Los_Angeles"
},
"flow": {
"name": "Test Flow",
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02"
},
"params": {
"coupons": [
{
"code": "AAA-BBB-CCC",
"expiration": "2000-01-01T00:00:00.000000000-00:00"
}
]
}
}
}
14 changes: 6 additions & 8 deletions flows/inputs/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
// TypeMsg is a constant for incoming messages
const TypeMsg string = "msg"

// MsgInput is a message which can be used as input
type MsgInput struct {
baseInput
urn urns.URN
Expand All @@ -36,13 +37,10 @@ func (i *MsgInput) Type() string { return TypeMsg }
// Resolve resolves the passed in key to a value, returning an error if the key is unknown
func (i *MsgInput) Resolve(key string) interface{} {
switch key {

case "urn":
return i.urn

case "text":
return i.text

case "attachments":
return i.attachments
}
Expand All @@ -51,6 +49,11 @@ func (i *MsgInput) Resolve(key string) interface{} {

// Default returns our default value if evaluated in a context, which in this case is the text and attachments combined
func (i *MsgInput) Default() interface{} {
return i
}

// String returns our default value if evaluated in a context, our text in our case
func (i *MsgInput) String() string {
var parts []string
if i.text != "" {
parts = append(parts, i.text)
Expand All @@ -61,11 +64,6 @@ func (i *MsgInput) Default() interface{} {
return strings.Join(parts, "\n")
}

// String returns our default value if evaluated in a context, our text in our case
func (i *MsgInput) String() string {
return i.text
}

var _ flows.Input = (*MsgInput)(nil)

//------------------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion flows/triggers/manual.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ManualTrigger struct {
}

// NewManualTrigger creates a new manual trigger
func NewManualTrigger(env utils.Environment, contact *flows.Contact, flow flows.Flow, triggeredOn time.Time) flows.Trigger {
func NewManualTrigger(env utils.Environment, contact *flows.Contact, flow flows.Flow, params utils.JSONFragment, triggeredOn time.Time) flows.Trigger {
return &ManualTrigger{baseTrigger{environment: env, contact: contact, flow: flow, triggeredOn: triggeredOn}}
}

Expand Down

0 comments on commit 331f884

Please sign in to comment.