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  }