44package twilio
55
66import (
7+ "encoding/json"
8+ "fmt"
9+ "net/http"
710 "os"
811 "testing"
12+ "time"
913
14+ "github.com/localtunnel/go-localtunnel"
1015 "github.com/stretchr/testify/assert"
16+ twilio "github.com/twilio/twilio-go/client"
1117 Api "github.com/twilio/twilio-go/rest/api/v2010"
1218 ChatV2 "github.com/twilio/twilio-go/rest/chat/v2"
1319 EventsV1 "github.com/twilio/twilio-go/rest/events/v1"
20+ StudioV2 "github.com/twilio/twilio-go/rest/studio/v2"
1421)
1522
1623var from string
@@ -120,6 +127,127 @@ func TestListParams(t *testing.T) {
120127 assert .Nil (t , err )
121128}
122129
130+ func createValidationServer (channel chan bool ) * http.Server {
131+ server := & http.Server {}
132+ server .Handler = http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
133+ url := r .Header ["X-Forwarded-Proto" ][0 ] + "://" + r .Header ["X-Forwarded-Host" ][0 ] + r .URL .RequestURI ()
134+ signatureHeader := r .Header ["X-Twilio-Signature" ]
135+ r .ParseForm ()
136+ params := make (map [string ]string )
137+ for k , v := range r .PostForm {
138+ params [k ] = v [0 ]
139+ }
140+ requestValidator := twilio .NewRequestValidator (os .Getenv ("TWILIO_AUTH_TOKEN" ))
141+ if len (signatureHeader ) != 0 {
142+ channel <- requestValidator .Validate (url , params , r .Header ["X-Twilio-Signature" ][0 ])
143+ } else {
144+ channel <- false
145+ }
146+ })
147+ return server
148+ }
149+
150+ func createStudioFlowParams (url string , method string ) * StudioV2.CreateFlowParams {
151+ jsonStr := fmt .Sprintf (`{
152+ "description": "Studio Flow",
153+ "states": [
154+ {
155+ "name": "Trigger",
156+ "type": "trigger",
157+ "transitions": [
158+ {
159+ "next": "httpRequest",
160+ "event": "incomingRequest"
161+ }
162+ ],
163+ "properties": {
164+ }
165+ },
166+ {
167+ "name": "httpRequest",
168+ "type": "make-http-request",
169+ "transitions": [],
170+ "properties": {
171+ "method": "%s",
172+ "content_type": "application/x-www-form-urlencoded;charset=utf-8",
173+ "url": "%s"
174+ }
175+ }
176+ ],
177+ "initial_state": "Trigger",
178+ "flags": {
179+ "allow_concurrent_calls": true
180+ }
181+ }` , method , url )
182+
183+ var definition interface {}
184+ _ = json .Unmarshal ([]byte (jsonStr ), & definition )
185+
186+ params := & StudioV2.CreateFlowParams {
187+ Definition : & definition ,
188+ }
189+ params .SetFriendlyName ("Go Cluster Test Flow" )
190+ params .SetStatus ("published" )
191+ return params
192+ }
193+
194+ func createStudioExecutionParams () * StudioV2.CreateExecutionParams {
195+ executionParams := & StudioV2.CreateExecutionParams {}
196+ executionParams .SetTo ("To" )
197+ executionParams .SetFrom ("From" )
198+ return executionParams
199+ }
200+
201+ func executeFlow (t * testing.T , flowSid string ) {
202+ _ , exeErr := testClient .StudioV2 .CreateExecution (flowSid , createStudioExecutionParams ())
203+ if exeErr != nil {
204+ t .Fatal ("Error with Studio Execution Creation: " , exeErr )
205+ }
206+ }
207+
208+ func requestValidation (t * testing.T , method string ) {
209+ //Invoke Localtunnel
210+ listener , ltErr := localtunnel .Listen (localtunnel.Options {})
211+ if ltErr != nil {
212+ t .Fatal ("Error with Localtunnel: " , ltErr )
213+ }
214+ //Create Validation Server & Listen
215+ channel := make (chan bool )
216+ server := createValidationServer (channel )
217+ go server .Serve (listener )
218+
219+ //Extra time for server to set up
220+ time .Sleep (1 * time .Second )
221+
222+ //Create Studio Flow
223+ params := createStudioFlowParams (listener .URL (), method )
224+ resp , flowErr := testClient .StudioV2 .CreateFlow (params )
225+ if flowErr != nil {
226+ t .Fatal ("Error with Studio Flow Creation: " , flowErr )
227+ }
228+ flowSid := * resp .Sid
229+ executeFlow (t , flowSid )
230+
231+ //Await for Request Validation
232+ afterCh := time .After (5 * time .Second )
233+ select {
234+ case validate := <- channel :
235+ assert .True (t , validate )
236+ case <- afterCh :
237+ t .Fatal ("No request was sent to validation server" )
238+ }
239+ defer testClient .StudioV2 .DeleteFlow (flowSid )
240+ defer server .Close ()
241+ }
242+
243+ func TestRequestValidation_GETMethod (t * testing.T ) {
244+ requestValidation (t , "GET" )
245+ }
246+
247+ func TestRequestValidation_POSTMethod (t * testing.T ) {
248+ requestValidation (t , "POST" )
249+ }
250+
123251func TestListingAvailableNumber (t * testing.T ) {
124252 params := & Api.ListAvailablePhoneNumberTollFreeParams {}
125253 params .SetLimit (2 )
@@ -128,4 +256,4 @@ func TestListingAvailableNumber(t *testing.T) {
128256 assert .Nil (t , err )
129257 assert .NotNil (t , resp )
130258 assert .Equal (t , 2 , len (resp ))
131- }
259+ }
0 commit comments