github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/event_handler_webhooks_test.go (about) 1 package gateway 2 3 import ( 4 "net/http" 5 "path/filepath" 6 "strings" 7 "testing" 8 9 "github.com/TykTechnologies/tyk/config" 10 "github.com/TykTechnologies/tyk/headers" 11 ) 12 13 func createGetHandler() *WebHookHandler { 14 eventHandlerConf := config.WebHookHandlerConf{ 15 TargetPath: TestHttpGet, 16 Method: "GET", 17 EventTimeout: 10, 18 TemplatePath: "../templates/default_webhook.json", 19 HeaderList: map[string]string{"x-tyk-test": "TEST"}, 20 } 21 ev := &WebHookHandler{} 22 if err := ev.Init(eventHandlerConf); err != nil { 23 panic(err) 24 } 25 return ev 26 } 27 28 func TestNewValid(t *testing.T) { 29 h := &WebHookHandler{} 30 err := h.Init(map[string]interface{}{ 31 "method": "POST", 32 "target_path": testHttpPost, 33 "template_path": "../templates/default_webhook.json", 34 "header_map": map[string]string{"X-Tyk-Test-Header": "Tyk v1.BANANA"}, 35 "event_timeout": 10, 36 }) 37 if err != nil { 38 t.Error("Webhook Handler should have created valid configuration") 39 } 40 } 41 42 func TestNewInvalid(t *testing.T) { 43 h := &WebHookHandler{} 44 err := h.Init(map[string]interface{}{ 45 "method": 123, 46 "target_path": testHttpPost, 47 "template_path": "../templates/default_webhook.json", 48 "header_map": map[string]string{"X-Tyk-Test-Header": "Tyk v1.BANANA"}, 49 "event_timeout": 10, 50 }) 51 if err == nil { 52 t.Error("Webhook Handler should have failed") 53 } 54 } 55 56 func TestChecksum(t *testing.T) { 57 rBody := `{ 58 "event": "QuotaExceeded", 59 "message": "Key Quota Limit Exceeded", 60 "path": "/about-lonelycoder/", 61 "origin": "", 62 "key": "4321", 63 "timestamp": 2014-11-27 12:52:05.944549825 +0000 GMT 64 }` 65 66 hook := createGetHandler() 67 checksum, err := hook.Checksum(rBody) 68 69 if err != nil { 70 t.Error("Checksum should not have failed with good objet and body") 71 } 72 73 if checksum != "62a6b4fa9b45cd372b871764296fb3a5" { 74 t.Error("Checksum is incorrect") 75 t.Error(checksum) 76 } 77 } 78 79 func TestBuildRequest(t *testing.T) { 80 hook := createGetHandler() 81 82 rBody := `{ 83 "event": "QuotaExceeded", 84 "message": "Key Quota Limit Exceeded", 85 "path": "/about-lonelycoder/", 86 "origin": "", 87 "key": "4321", 88 "timestamp": 2014-11-27 12:52:05.944549825 +0000 GMT 89 }` 90 91 req, err := hook.BuildRequest(rBody) 92 if err != nil { 93 t.Error("Request should have built cleanly.") 94 } 95 if req.Method != http.MethodGet { 96 t.Error("Method hould be GET") 97 } 98 99 if got := req.Header.Get(headers.UserAgent); got != headers.TykHookshot { 100 t.Error("Header User Agent is not correct!") 101 } 102 103 if got := req.Header.Get(headers.ContentType); got != headers.ApplicationJSON { 104 t.Error("Header Content-Type is not correct!") 105 } 106 } 107 108 func TestCreateBody(t *testing.T) { 109 em := config.EventMessage{ 110 Type: EventQuotaExceeded, 111 TimeStamp: "0", 112 } 113 114 hook := createGetHandler() 115 body, err := hook.CreateBody(em) 116 if err != nil { 117 t.Error("Create body failed with error! ", err) 118 } 119 120 expectedBody := `"event": "QuotaExceeded"` 121 if !strings.Contains(body, expectedBody) { 122 t.Error("Body incorrect, is: ", body) 123 } 124 } 125 126 func TestGet(t *testing.T) { 127 eventHandler := createGetHandler() 128 129 eventMessage := config.EventMessage{ 130 Type: EventKeyExpired, 131 Meta: EventKeyFailureMeta{ 132 EventMetaDefault: EventMetaDefault{Message: "THIS IS A TEST"}, 133 Path: "/banana", 134 Origin: "tyk.io", 135 Key: "123456789", 136 }, 137 } 138 body, _ := eventHandler.CreateBody(eventMessage) 139 140 checksum, _ := eventHandler.Checksum(body) 141 eventHandler.HandleEvent(eventMessage) 142 143 if wasFired := eventHandler.WasHookFired(checksum); !wasFired { 144 t.Error("Checksum should have matched, event did not fire!") 145 } 146 147 } 148 149 func TestPost(t *testing.T) { 150 eventHandlerConf := config.WebHookHandlerConf{ 151 TargetPath: "`+testHttpPost+`", 152 Method: "POST", 153 EventTimeout: 10, 154 TemplatePath: "templates/default_webhook.json", 155 HeaderList: map[string]string{"x-tyk-test": "TEST POST"}, 156 } 157 158 eventHandler := &WebHookHandler{} 159 if err := eventHandler.Init(eventHandlerConf); err != nil { 160 t.Fatal(err) 161 } 162 163 eventMessage := config.EventMessage{ 164 Type: EventKeyExpired, 165 Meta: EventKeyFailureMeta{ 166 EventMetaDefault: EventMetaDefault{Message: "THIS IS A TEST"}, 167 Path: "/banana", 168 Origin: "tyk.io", 169 Key: "123456789", 170 }, 171 } 172 173 body, _ := eventHandler.CreateBody(eventMessage) 174 175 checksum, _ := eventHandler.Checksum(body) 176 eventHandler.HandleEvent(eventMessage) 177 178 if wasFired := eventHandler.WasHookFired(checksum); !wasFired { 179 t.Error("Checksum should have matched, event did not fire!") 180 } 181 } 182 183 func TestNewCustomTemplate(t *testing.T) { 184 tests := []struct { 185 name string 186 missingDefault bool 187 templatePath string 188 wantErr bool 189 }{ 190 {"UseDefault", false, "", false}, 191 {"FallbackToDefault", false, "missing_webhook.json", false}, 192 {"UseCustom", false, "templates/breaker_webhook.json", false}, 193 {"MissingDefault", true, "", true}, 194 {"MissingDefaultFallback", true, "missing_webhook.json", true}, 195 {"MissingDefaultNotNeeded", true, "../templates/breaker_webhook.json", false}, 196 } 197 for _, tc := range tests { 198 t.Run(tc.name, func(t *testing.T) { 199 if tc.missingDefault { 200 globalConf := config.Global() 201 old := globalConf.TemplatePath 202 globalConf.TemplatePath = "missing-dir" 203 config.SetGlobal(globalConf) 204 defer func() { 205 globalConf.TemplatePath = old 206 config.SetGlobal(globalConf) 207 }() 208 } 209 h := &WebHookHandler{} 210 err := h.Init(map[string]interface{}{ 211 "target_path": testHttpPost, 212 "template_path": tc.templatePath, 213 }) 214 if tc.wantErr && err == nil { 215 t.Fatalf("wanted error, got nil") 216 } else if !tc.wantErr && err != nil { 217 t.Fatalf("didn't want error, got: %v", err) 218 } 219 if err == nil && h.template == nil { 220 t.Fatalf("didn't get an error but template is nil") 221 } 222 }) 223 } 224 } 225 226 func TestWebhookContentTypeHeader(t *testing.T) { 227 globalConf := config.Global() 228 templatePath := globalConf.TemplatePath 229 230 tests := []struct { 231 Name string 232 TemplatePath string 233 InputHeaders map[string]string 234 ExpectedContentType string 235 }{ 236 {"MissingTemplatePath", "", nil, "application/json"}, 237 {"MissingTemplatePath/CustomHeaders", "", map[string]string{"Content-Type": "application/xml"}, "application/xml"}, 238 {"InvalidTemplatePath", "randomPath", nil, "application/json"}, 239 {"InvalidTemplatePath/CustomHeaders", "randomPath", map[string]string{"Content-Type": "application/xml"}, "application/xml"}, 240 {"CustomTemplate", filepath.Join(templatePath, "transform_test.tmpl"), nil, ""}, 241 {"CustomTemplate/CustomHeaders", filepath.Join(templatePath, "breaker_webhook.json"), map[string]string{"Content-Type": "application/xml"}, "application/xml"}, 242 } 243 244 for _, ts := range tests { 245 t.Run(ts.Name, func(t *testing.T) { 246 conf := config.WebHookHandlerConf{ 247 TemplatePath: ts.TemplatePath, 248 HeaderList: ts.InputHeaders, 249 } 250 251 hook := &WebHookHandler{} 252 if err := hook.Init(conf); err != nil { 253 t.Fatal("Webhook Init failed with err ", err) 254 } 255 256 req, err := hook.BuildRequest("") 257 if err != nil { 258 t.Fatal("Failed to build request with error ", err) 259 } 260 261 if req.Header.Get(headers.ContentType) != ts.ExpectedContentType { 262 t.Fatalf("Expect Content-Type %s. Got %s", ts.ExpectedContentType, req.Header.Get("Content-Type")) 263 } 264 }) 265 } 266 267 }