Skip to content

Commit

Permalink
Merge pull request #263 from nyaruka/webhooks
Browse files Browse the repository at this point in the history
Fully legacy compatible webhooks
  • Loading branch information
rowanseymour authored Apr 23, 2018
2 parents 36b328a + 74e548e commit d84ea29
Show file tree
Hide file tree
Showing 31 changed files with 366 additions and 150 deletions.
8 changes: 5 additions & 3 deletions cmd/flowrunner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ func main() {
os.Exit(1)
}

httpClient := utils.NewHTTPClient("goflow-flowrunner")

assetsFilename := flag.Args()[0]
startFlowUUID := flows.FlowUUID(flag.Args()[1])

Expand All @@ -159,7 +161,7 @@ func main() {
if err != nil {
log.Fatal("Error reading assets file: ", err)
}
assetCache := assets.NewAssetCache(100, 5, "testing/1.0")
assetCache := assets.NewAssetCache(100, 5)
if err := assetCache.Include(json.RawMessage(assetsJSON)); err != nil {
log.Fatal("Error reading assets: ", err)
}
Expand All @@ -168,7 +170,7 @@ func main() {
la, _ := time.LoadLocation("America/Los_Angeles")
env := utils.NewEnvironment(utils.DateFormatYearMonthDay, utils.TimeFormatHourMinute, la, utils.LanguageList{})

session := engine.NewSession(assetCache, assets.NewMockAssetServer())
session := engine.NewSession(assetCache, assets.NewMockAssetServer(), httpClient)

contactJSON, err := ioutil.ReadFile(*contactFile)
if err != nil {
Expand Down Expand Up @@ -224,7 +226,7 @@ func main() {
callerEvents = append(callerEvents, []flows.Event{event})

// rebuild our session
session, err = engine.ReadSession(assetCache, assets.NewMockAssetServer(), outJSON)
session, err = engine.ReadSession(assetCache, assets.NewMockAssetServer(), httpClient, outJSON)
if err != nil {
log.Fatalf("Error unmarshalling output: %s", err)
}
Expand Down
46 changes: 23 additions & 23 deletions cmd/flowrunner/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ func runFlow(assetsFilename string, triggerEnvelope *utils.TypedEnvelope, caller
// rewrite the URL on any webhook actions
testAssetsJSONStr := strings.Replace(string(testAssetsJSON), "http://localhost", serverURL, -1)

assetCache := assets.NewAssetCache(100, 5, "testing/1.0")
assetCache := assets.NewAssetCache(100, 5)
if err := assetCache.Include(defaultAssetsJSON); err != nil {
return runResult{}, fmt.Errorf("Error reading default assets '%s': %s", assetsFilename, err)
}
if err := assetCache.Include(json.RawMessage(testAssetsJSONStr)); err != nil {
return runResult{}, fmt.Errorf("Error reading test assets '%s': %s", assetsFilename, err)
}

session := engine.NewSession(assetCache, assets.NewMockAssetServer())
session := engine.NewSession(assetCache, assets.NewMockAssetServer(), test.TestHTTPClient)

trigger, err := triggers.ReadTrigger(session, triggerEnvelope)
if err != nil {
Expand All @@ -119,7 +119,7 @@ func runFlow(assetsFilename string, triggerEnvelope *utils.TypedEnvelope, caller
}
outputs = append(outputs, &Output{outJSON, marshalEventLog(session.Events())})

session, err = engine.ReadSession(assetCache, assets.NewMockAssetServer(), outJSON)
session, err = engine.ReadSession(assetCache, assets.NewMockAssetServer(), test.TestHTTPClient, outJSON)
if err != nil {
return runResult{}, fmt.Errorf("Error marshalling output: %s", err)
}
Expand Down Expand Up @@ -153,15 +153,15 @@ func TestFlows(t *testing.T) {
// save away our server URL so we can rewrite our URLs
serverURL = server.URL

for _, test := range flowTests {
for _, tc := range flowTests {
utils.SetUUIDGenerator(utils.NewSeededUUID4Generator(123456))

testJSON, err := readFile("flows/", test.output)
require.NoError(t, err, "Error reading output file for flow '%s' and output '%s': %s", test.assets, test.output, err)
testJSON, err := readFile("flows/", tc.output)
require.NoError(t, err, "Error reading output file for flow '%s' and output '%s': %s", tc.assets, tc.output, err)

flowTest := FlowTest{}
err = json.Unmarshal(json.RawMessage(testJSON), &flowTest)
require.NoError(t, err, "Error unmarshalling output for flow '%s' and output '%s': %s", test.assets, test.output, err)
require.NoError(t, err, "Error unmarshalling output for flow '%s' and output '%s': %s", tc.assets, tc.output, err)

// unmarshal our caller events
callerEvents := make([][]flows.Event, len(flowTest.CallerEvents))
Expand All @@ -171,17 +171,17 @@ func TestFlows(t *testing.T) {

for e := range flowTest.CallerEvents[i] {
event, err := events.EventFromEnvelope(flowTest.CallerEvents[i][e])
require.NoError(t, err, "Error unmarshalling caller events for flow '%s' and output '%s': %s", test.assets, test.output, err)
require.NoError(t, err, "Error unmarshalling caller events for flow '%s' and output '%s': %s", tc.assets, tc.output, err)

event.SetFromCaller(true)
callerEvents[i][e] = event
}
}

// run our flow
runResult, err := runFlow(test.assets, flowTest.Trigger, callerEvents)
runResult, err := runFlow(tc.assets, flowTest.Trigger, callerEvents)
if err != nil {
t.Errorf("Error running flow for flow '%s' and output '%s': %s", test.assets, test.output, err)
t.Errorf("Error running flow for flow '%s' and output '%s': %s", tc.assets, tc.output, err)
continue
}

Expand All @@ -197,7 +197,7 @@ func TestFlows(t *testing.T) {
require.NoError(t, err, "Error marshalling test definition: %s", err)

// write our output
outputFilename := deriveFilename("flows/", test.output)
outputFilename := deriveFilename("flows/", tc.output)
err = ioutil.WriteFile(outputFilename, clearTimestamps(testJSON), 0644)
require.NoError(t, err, "Error writing test file to %s: %s", outputFilename, err)
} else {
Expand All @@ -213,23 +213,23 @@ func TestFlows(t *testing.T) {

// read our output and test that we are the same
if len(runResult.outputs) != len(expectedOutputs) {
t.Errorf("Actual outputs:\n%s\n do not match expected:\n%s\n for flow '%s'", runResult.outputs, expectedOutputs, test.assets)
t.Errorf("Actual outputs:\n%s\n do not match expected:\n%s\n for flow '%s'", runResult.outputs, expectedOutputs, tc.assets)
continue
}

for i := range runResult.outputs {
actualOutput := runResult.outputs[i]
expectedOutput := expectedOutputs[i]

actualSession, err := engine.ReadSession(runResult.assetCache, assets.NewMockAssetServer(), actualOutput.Session)
require.NoError(t, err, "Error unmarshalling session running flow '%s': %s\n", test.assets, err)
actualSession, err := engine.ReadSession(runResult.assetCache, assets.NewMockAssetServer(), test.TestHTTPClient, actualOutput.Session)
require.NoError(t, err, "Error unmarshalling session running flow '%s': %s\n", tc.assets, err)

expectedSession, err := engine.ReadSession(runResult.assetCache, assets.NewMockAssetServer(), expectedOutput.Session)
require.NoError(t, err, "Error unmarshalling expected session running flow '%s': %s\n", test.assets, err)
expectedSession, err := engine.ReadSession(runResult.assetCache, assets.NewMockAssetServer(), test.TestHTTPClient, expectedOutput.Session)
require.NoError(t, err, "Error unmarshalling expected session running flow '%s': %s\n", tc.assets, err)

// number of runs should be the same
if len(actualSession.Runs()) != len(expectedSession.Runs()) {
t.Errorf("Actual runs:\n%#v\n do not match expected:\n%#v\n for flow '%s'\n", actualSession.Runs(), expectedSession.Runs(), test.assets)
t.Errorf("Actual runs:\n%#v\n do not match expected:\n%#v\n for flow '%s'\n", actualSession.Runs(), expectedSession.Runs(), tc.assets)
}

// runs should have same status and flows
Expand All @@ -238,16 +238,16 @@ func TestFlows(t *testing.T) {
expected := expectedSession.Runs()[i]

if run.Flow() != expected.Flow() {
t.Errorf("Actual run flow: %s does not match expected: %s for flow '%s'", run.Flow().UUID(), expected.Flow().UUID(), test.assets)
t.Errorf("Actual run flow: %s does not match expected: %s for flow '%s'", run.Flow().UUID(), expected.Flow().UUID(), tc.assets)
}

if run.Status() != expected.Status() {
t.Errorf("Actual run status: %s does not match expected: %s for flow '%s'", run.Status(), expected.Status(), test.assets)
t.Errorf("Actual run status: %s does not match expected: %s for flow '%s'", run.Status(), expected.Status(), tc.assets)
}
}

if len(actualOutput.Events) != len(expectedOutput.Events) {
t.Errorf("Actual events:\n%#v\n do not match expected:\n%#v\n for flow '%s'\n", actualOutput.Events, expectedOutput.Events, test.assets)
t.Errorf("Actual events:\n%#v\n do not match expected:\n%#v\n for flow '%s'\n", actualOutput.Events, expectedOutput.Events, tc.assets)
}

for j := range actualOutput.Events {
Expand All @@ -256,13 +256,13 @@ func TestFlows(t *testing.T) {

// write our events as json
eventJSON, err := rawMessageAsJSON(event)
require.NoError(t, err, "Error marshalling event for flow '%s' and output '%s': %s\n", test.assets, test.output, err)
require.NoError(t, err, "Error marshalling event for flow '%s' and output '%s': %s\n", tc.assets, tc.output, err)

expectedJSON, err := rawMessageAsJSON(expected)
require.NoError(t, err, "Error marshalling expected event for flow '%s' and output '%s': %s\n", test.assets, test.output, err)
require.NoError(t, err, "Error marshalling expected event for flow '%s' and output '%s': %s\n", tc.assets, tc.output, err)

if eventJSON != expectedJSON {
t.Errorf("Got event:\n'%s'\n\nwhen expecting:\n'%s'\n\n for flow '%s' and output '%s\n", eventJSON, expectedJSON, test.assets, test.output)
t.Errorf("Got event:\n'%s'\n\nwhen expecting:\n'%s'\n\n for flow '%s' and output '%s\n", eventJSON, expectedJSON, tc.assets, tc.output)
break
}
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/flowrunner/testdata/flows/all_actions_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -629,7 +629,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -677,7 +677,7 @@
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"webhook": {
"body": "{ \"ok\": \"true\" }",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down
2 changes: 1 addition & 1 deletion cmd/flowrunner/testdata/flows/triggered_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
},
"language": "",
"name": "Bob",
"timezone": "UTC",
"timezone": "",
"urns": [],
"uuid": "c59b0033-e748-4240-9d4c-e85eb6800151"
},
Expand Down
6 changes: 3 additions & 3 deletions cmd/flowrunner/testdata/flows/two_questions_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -556,7 +556,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -640,7 +640,7 @@
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"webhook": {
"body": "{ \"ok\": \"true\" }",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"request": "POST /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nContent-Length: 69\r\nAccept-Encoding: gzip\r\n\r\n{ \"contact\": \"ba96bf7f-bc2a-4873-a7c7-254d1927c4e3\", \"soda\": \"Coke\" }",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down
10 changes: 5 additions & 5 deletions cmd/flowrunner/testdata/flows/webhook_persists_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -108,7 +108,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -174,7 +174,7 @@
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"webhook": {
"body": "{ \"ok\": \"true\" }",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -287,7 +287,7 @@
},
{
"created_on": "2000-01-01T00:00:00.000000000-00:00",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down Expand Up @@ -401,7 +401,7 @@
"uuid": "d2f852ec-7b4e-457f-ae7f-f8b243c49ff5",
"webhook": {
"body": "{ \"ok\": \"true\" }",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n",
"request": "GET /?cmd=success HTTP/1.1\r\nHost: 127.0.0.1:49999\r\nUser-Agent: goflow-testing\r\nAccept-Encoding: gzip\r\n\r\n",
"response": "HTTP/1.1 200 OK\r\nContent-Length: 16\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 11 Apr 2018 18:24:30 GMT\r\n\r\n{ \"ok\": \"true\" }",
"status": "success",
"status_code": 200,
Expand Down
Loading

0 comments on commit d84ea29

Please sign in to comment.