Skip to content

Commit

Permalink
Merge pull request #271 from nyaruka/webhook_test
Browse files Browse the repository at this point in the history
Webhook test
  • Loading branch information
rowanseymour authored Apr 24, 2018
2 parents 97e5cc0 + 81c970a commit ac2cd74
Show file tree
Hide file tree
Showing 8 changed files with 644 additions and 593 deletions.
4 changes: 2 additions & 2 deletions cmd/flowrunner/testdata/flows/webhook_persists.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@
}
],
"router": {
"operand": "@run.webhook.status",
"operand": "@run.webhook",
"cases": [
{
"arguments": [
"success"
],
"uuid": "789b45bc-005a-46db-8331-6a966c0141c2",
"exit_uuid": "bb09f6b6-89f4-45bd-8cc9-1d4655914590",
"type": "is_text_eq"
"type": "has_webhook_status"
}
],
"default_exit_uuid": "3699df6c-15f0-4a86-b7f8-9fe1497e7854",
Expand Down
14 changes: 14 additions & 0 deletions docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,20 @@ Tests whether a ward name is contained in the `text`
@(has_ward("Gisozi")) → true
```

<a name="test:has_webhook_status"></a>

## has_webhook_status(webhook, status)

Tests whether the passed in `webhook` call has the passed in `status`.


```objectivec
@(has_webhook_status(run.webhook, "success")) → true
@(has_webhook_status(run.webhook, "connection_error")) → false
@(has_webhook_status(run.webhook, "success").match) → {"results":[{"state":"WA"},{"state":"IN"}]}
@(has_webhook_status("abc", "success")) → ERROR
```
<a name="test:is_error"></a>
## is_error(value)
Expand Down
1,153 changes: 580 additions & 573 deletions docs/index.html

Large diffs are not rendered by default.

33 changes: 31 additions & 2 deletions flows/routers/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ func init() {

// XTESTS is our mapping of the excellent test names to their actual functions
var XTESTS = map[string]functions.XFunction{
"is_error": functions.OneArgFunction(IsError),
"has_value": functions.OneArgFunction(HasValue),
"is_error": functions.OneArgFunction(IsError),
"has_value": functions.OneArgFunction(HasValue),

"has_group": functions.TwoArgFunction(HasGroup),
"has_webhook_status": functions.TwoArgFunction(HasWebhookStatus),
"has_wait_timed_out": functions.OneArgFunction(HasWaitTimedOut),

"is_text_eq": functions.TwoTextFunction(IsTextEQ),
Expand Down Expand Up @@ -151,6 +153,33 @@ func HasWaitTimedOut(env utils.Environment, value types.XValue) types.XValue {
return XFalseResult
}

// HasWebhookStatus tests whether the passed in `webhook` call has the passed in `status`.
//
// @(has_webhook_status(run.webhook, "success")) -> true
// @(has_webhook_status(run.webhook, "connection_error")) -> false
// @(has_webhook_status(run.webhook, "success").match) -> {"results":[{"state":"WA"},{"state":"IN"}]}
// @(has_webhook_status("abc", "success")) -> ERROR
//
// @test has_webhook_status(webhook, status)
func HasWebhookStatus(env utils.Environment, arg1 types.XValue, arg2 types.XValue) types.XValue {
// is the first argument a webhook call
webhook, isWebhook := arg1.(*flows.WebhookCall)
if !isWebhook {
return types.NewXErrorf("must have a webhook call as its first argument")
}

status, xerr := types.ToXText(arg2)
if xerr != nil {
return xerr
}

if string(webhook.Status()) == strings.ToLower(status.Native()) {
return XTestResult{true, types.NewXText(webhook.Body())}
}

return XFalseResult
}

// HasGroup returns whether the `contact` is part of group with the passed in UUID
//
// @(has_group(contact, "b7cf0d83-f1c9-411c-96fd-c511a4cfa86d")) -> true
Expand Down
5 changes: 3 additions & 2 deletions flows/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package flows

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
Expand Down Expand Up @@ -110,9 +111,9 @@ func (w *WebhookCall) Resolve(key string) types.XValue {
return types.NewXResolveError(w, key)
}

// Reduce is called when this object needs to be reduced to a primitive
// Reduce reduces this to a string of method and URL, e.g. "GET http://example.com/hook.php"
func (w *WebhookCall) Reduce() types.XPrimitive {
return types.NewXText(w.body)
return types.NewXText(fmt.Sprintf("%s %s", w.method, w.url))
}

// ToXJSON is called when this type is passed to @(json(...))
Expand Down
8 changes: 4 additions & 4 deletions legacy/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ func migrateRule(baseLanguage utils.Language, exitMap map[string]flows.Exit, r R
arguments = []string{test.ExitType}

case "webhook_status":
newType = "is_text_eq"
newType = "has_webhook_status"
test := webhookTest{}
err = json.Unmarshal(r.Test.Data, &test)
if test.Status == "success" {
Expand Down Expand Up @@ -773,7 +773,7 @@ func parseRules(baseLanguage utils.Language, r RuleSet, localization flows.Local
exits = append(exits, connectionErrorExit)
cases = append(cases, routers.Case{
UUID: utils.UUID(utils.NewUUID()),
Type: "is_text_eq",
Type: "has_webhook_status",
Arguments: []string{"connection_error"},
OmitOperand: false,
ExitUUID: connectionErrorExitUUID,
Expand Down Expand Up @@ -852,8 +852,8 @@ func migrateRuleSet(lang utils.Language, r RuleSet, localization flows.Localizat
},
}

// subflow rulesets operate on the child flow status
router = routers.NewSwitchRouter(defaultExit, "@run.webhook.status", cases, resultName)
// webhook rulesets operate on the webhook call
router = routers.NewSwitchRouter(defaultExit, "@run.webhook", cases, resultName)

case "form_field":
var config fieldConfig
Expand Down
16 changes: 8 additions & 8 deletions legacy/testdata/migrations/rulesets.json
Original file line number Diff line number Diff line change
Expand Up @@ -346,27 +346,27 @@
"type": "switch",
"result_name": "Response 1",
"default_exit_uuid": "f3e4cb68-408f-4435-b337-82826e928875",
"operand": "@run.webhook.status",
"operand": "@run.webhook",
"cases": [
{
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"success"
],
"exit_uuid": "7fab0ddd-3e4d-4541-84df-8470e05ead16"
},
{
"uuid": "692926ea-09d6-4942-bd38-d266ec8d3716",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"response_error"
],
"exit_uuid": "f3e4cb68-408f-4435-b337-82826e928875"
},
{
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"connection_error"
],
Expand Down Expand Up @@ -457,27 +457,27 @@
"type": "switch",
"result_name": "Response 1",
"default_exit_uuid": "f3e4cb68-408f-4435-b337-82826e928875",
"operand": "@run.webhook.status",
"operand": "@run.webhook",
"cases": [
{
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"success"
],
"exit_uuid": "7fab0ddd-3e4d-4541-84df-8470e05ead16"
},
{
"uuid": "692926ea-09d6-4942-bd38-d266ec8d3716",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"response_error"
],
"exit_uuid": "f3e4cb68-408f-4435-b337-82826e928875"
},
{
"uuid": "c34b6c7d-fa06-4563-92a3-d648ab64bccb",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": [
"connection_error"
],
Expand Down
4 changes: 2 additions & 2 deletions legacy/testdata/migrations/tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@
},
"expected_case": {
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": ["success"],
"exit_uuid": "c072ecb5-0686-40ea-8ed3-898dc1349783"
},
Expand All @@ -401,7 +401,7 @@
},
"expected_case": {
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"type": "is_text_eq",
"type": "has_webhook_status",
"arguments": ["response_error"],
"exit_uuid": "c072ecb5-0686-40ea-8ed3-898dc1349783"
},
Expand Down

0 comments on commit ac2cd74

Please sign in to comment.