hanayo/vendor/gopkg.in/mailgun/mailgun-go.v1/webhooks_test.go
2019-02-23 13:29:15 +00:00

143 lines
2.9 KiB
Go

package mailgun
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"io"
"mime/multipart"
"net/http"
"net/url"
"strings"
"testing"
"github.com/facebookgo/ensure"
)
func TestWebhookCRUD(t *testing.T) {
mg, err := NewMailgunFromEnv()
ensure.Nil(t, err)
var countHooks = func() int {
hooks, err := mg.GetWebhooks()
ensure.Nil(t, err)
return len(hooks)
}
hookCount := countHooks()
domainURL := randomDomainURL(10)
ensure.Nil(t, mg.CreateWebhook("deliver", domainURL))
defer func() {
ensure.Nil(t, mg.DeleteWebhook("deliver"))
newCount := countHooks()
ensure.DeepEqual(t, newCount, hookCount)
}()
newCount := countHooks()
ensure.False(t, newCount <= hookCount)
theURL, err := mg.GetWebhookByType("deliver")
ensure.Nil(t, err)
ensure.DeepEqual(t, theURL, domainURL)
updatedDomainURL := randomDomainURL(10)
ensure.Nil(t, mg.UpdateWebhook("deliver", updatedDomainURL))
hooks, err := mg.GetWebhooks()
ensure.Nil(t, err)
ensure.DeepEqual(t, hooks["deliver"], updatedDomainURL)
}
var signedTests = []bool{
true,
false,
}
func TestVerifyWebhookRequest_Form(t *testing.T) {
mg, err := NewMailgunFromEnv()
ensure.Nil(t, err)
for _, v := range signedTests {
fields := getSignatureFields(mg.ApiKey(), v)
req := buildFormRequest(fields)
verified, err := mg.VerifyWebhookRequest(req)
ensure.Nil(t, err)
if v != verified {
t.Errorf("VerifyWebhookRequest should return '%v' but got '%v'", v, verified)
}
}
}
func TestVerifyWebhookRequest_MultipartForm(t *testing.T) {
mg, err := NewMailgunFromEnv()
ensure.Nil(t, err)
for _, v := range signedTests {
fields := getSignatureFields(mg.ApiKey(), v)
req := buildMultipartFormRequest(fields)
verified, err := mg.VerifyWebhookRequest(req)
ensure.Nil(t, err)
if v != verified {
t.Errorf("VerifyWebhookRequest should return '%v' but got '%v'", v, verified)
}
}
}
func buildFormRequest(fields map[string]string) *http.Request {
values := url.Values{}
for k, v := range fields {
values.Add(k, v)
}
r := strings.NewReader(values.Encode())
req, _ := http.NewRequest("POST", "/", r)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req
}
func buildMultipartFormRequest(fields map[string]string) *http.Request {
buf := &bytes.Buffer{}
writer := multipart.NewWriter(buf)
for k, v := range fields {
writer.WriteField(k, v)
}
writer.Close()
req, _ := http.NewRequest("POST", "/", buf)
req.Header.Set("Content-type", writer.FormDataContentType())
return req
}
func getSignatureFields(key string, signed bool) map[string]string {
badSignature := hex.EncodeToString([]byte("badsignature"))
fields := map[string]string{
"token": "token",
"timestamp": "123456789",
"signature": badSignature,
}
if signed {
h := hmac.New(sha256.New, []byte(key))
io.WriteString(h, fields["timestamp"])
io.WriteString(h, fields["token"])
hash := h.Sum(nil)
fields["signature"] = hex.EncodeToString(hash)
}
return fields
}