-
Notifications
You must be signed in to change notification settings - Fork 2
/
http_shopify_webhook_test.go
149 lines (124 loc) · 4 KB
/
http_shopify_webhook_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package http_shopify_webhook
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// Test base verification function works.
func TestIsValidSignatureSuccess(t *testing.T) {
// Setup a simple body with a matching HMAC.
body := []byte(`{"key":"value"}`)
hmac := "7iASoA8WSbw19M/h+lgrLr2ly/LvgnE9bcLsk9gflvs="
// Create a signature
lhmac := newSignature("secret", body)
if ok := isValidSignature(lhmac, hmac); !ok {
t.Error("expected request data to verify")
}
}
func TestIsValidSignatureFailure(t *testing.T) {
// Setup a simple body with a matching HMAC, but missing shop.
body := []byte(`{"key":"value"}`)
hmac := "ee2012a00f1649bc35f4cfe1fa582b2ebda5cbf2ef82713d6dc2ec93d81f96fb"
// Create a signature
lhmac := newSignature("secret", body)
if ok := isValidSignature(lhmac, hmac); ok {
t.Errorf("expected request data to not verify, but it did")
}
// HMAC which does not match body content.
hmac = "7iASoA8WSbw19M/h+"
// Create a signature
lhmac = newSignature("secret", body)
if ok := isValidSignature(lhmac, hmac); ok {
t.Error("expected request data to not verify, but it did")
}
}
// Test the implementation with a server.
func TestNetHttpSuccess(t *testing.T) {
// Set our data.
key := "secret"
body := `{"key":"value"}`
hmac := "7iASoA8WSbw19M/h+lgrLr2ly/LvgnE9bcLsk9gflvs="
shop := "example.myshopify.com"
// Setup the server with our data.
rec, ran := setupServer(key, shop, hmac, body)
if c := rec.Code; c != http.StatusOK {
t.Errorf("expected status code %d got %v", http.StatusOK, c)
}
if !ran {
t.Error("expected next handler to run but did not")
}
}
// Test the implementation with a server (failure of HMAC).
func TestNetHttpFailure(t *testing.T) {
// Set our data.
key := "secret"
body := `{"key":"value"}`
hmac := "ee2012a00f1649bc35f"
shop := "example.myshopify.com"
// Setup the server with our data.
rec, ran := setupServer(key, shop, hmac, body)
if c := rec.Code; c != http.StatusBadRequest {
t.Errorf("expected status code %d got %v", http.StatusBadRequest, c)
}
if ran == true {
t.Error("expected next handler to not run but it did")
}
}
// Test for missing HMAC header from request.
func TestMissingHeaderHMAC(t *testing.T) {
// Set our data.
key := "secret"
body := `{"key":"value"}`
shop := "example.myshopify.com"
// Setup the server with our data. No shop.
rec, ran := setupServer(key, shop, "", body)
if c := rec.Code; c != http.StatusBadRequest {
t.Errorf("expected status code %d got %v", http.StatusBadRequest, c)
}
if b := rec.Body; !strings.Contains(b.String(), errMissingSignature) {
t.Errorf("expected '%s' body got '%v'", errMissingSignature, b)
}
if ran == true {
t.Error("expected next handler to not run but it did")
}
}
// Test for missing shop header from request.
func TestMissingHeaderShop(t *testing.T) {
// Set our data.
key := "secret"
body := `{"key":"value"}`
hmac := "ee2012a00f1649bc35f"
// Setup the server with our data. No shop.
rec, ran := setupServer(key, "", hmac, body)
if c := rec.Code; c != http.StatusBadRequest {
t.Errorf("expected status code %d got %v", http.StatusBadRequest, c)
}
if b := rec.Body; !strings.Contains(b.String(), errMissingShop) {
t.Errorf("expected '%s' body got '%v'", errMissingShop, b)
}
if ran == true {
t.Error("expected next handler to not run but it did")
}
}
// Sets up the server for a few tests.
func setupServer(key string, shop string, hmac string, body string) (*httptest.ResponseRecorder, bool) {
// Create a mock request to use
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/webhook/order-create", bytes.NewBufferString(body))
// Set the headers.
req.Header.Set("X-Shopify-Shop-Domain", shop)
req.Header.Set("X-Shopify-Hmac-Sha256", hmac)
// Our "next" handler.
ran := false
nh := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Ok")
ran = true
})
// Create the handler and serve with our recorder and request.
h := WebhookVerify(key, nh)
h.ServeHTTP(rec, req)
return rec, ran
}