Skip to content

Commit 92184e3

Browse files
joeybloggsjoeybloggs
authored andcommitted
Added WebHook Test Converage + reduces server complexity
1 parent d6829a3 commit 92184e3

File tree

4 files changed

+216
-41
lines changed

4 files changed

+216
-41
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ Library webhooks
33

44
[![GoDoc](https://godoc.org/github.com/joeybloggs/webhooks?status.svg)](https://godoc.org/github.com/joeybloggs/webhooks)
55

6-
Source control webhook reciever for GitHub
6+
Source control webhook reciever for GitHub, others to come, with complete event payload parsing
77

88
### In Development

github/github.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,6 @@ func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
225225

226226
func (hook Webhook) runProcessPayloadFunc(fn webhooks.ProcessPayloadFunc, results interface{}) {
227227
go func(fn webhooks.ProcessPayloadFunc, results interface{}) {
228-
229-
// put in recovery here!
230-
231228
fn(results)
232229
}(fn, results)
233230
}

webhooks.go

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package webhooks
22

3-
import (
4-
"errors"
5-
"fmt"
6-
"net/http"
7-
)
3+
import "net/http"
84

95
// Provider defines the type of webhook
106
type Provider int
@@ -46,23 +42,11 @@ func Run(hook Webhook, addr string, path string) error {
4642

4743
s := &http.Server{Addr: addr, Handler: srv}
4844

49-
return run(s)
50-
}
51-
52-
// RunTLS runs a server with TLS configuration.
53-
func RunTLS(hook Webhook, addr string, path string, certFile string, keyFile string) error {
54-
srv := &server{
55-
hook: hook,
56-
path: path,
57-
}
58-
59-
s := &http.Server{Addr: addr, Handler: srv}
60-
61-
return run(s, certFile, keyFile)
45+
return s.ListenAndServe()
6246
}
6347

6448
// RunServer runs a custom server.
65-
func RunServer(s *http.Server, hook Webhook, addr string, path string) error {
49+
func RunServer(s *http.Server, hook Webhook, path string) error {
6650

6751
srv := &server{
6852
hook: hook,
@@ -71,12 +55,16 @@ func RunServer(s *http.Server, hook Webhook, addr string, path string) error {
7155

7256
s.Handler = srv
7357

74-
return run(s)
58+
return s.ListenAndServe()
7559
}
7660

7761
// RunTLSServer runs a custom server with TLS configuration.
78-
// NOTE: http.Server Handler will be overridden by this library, just set it to nil
79-
func RunTLSServer(s *http.Server, hook Webhook, addr string, path string, certFile string, keyFile string) error {
62+
// NOTE: http.Server Handler will be overridden by this library, just set it to nil.
63+
// Setting the Certificates can be done in the http.Server.TLSConfig.Certificates
64+
// see example here:
65+
func RunTLSServer(s *http.Server, hook Webhook, path string) error {
66+
67+
// var err error
8068

8169
srv := &server{
8270
hook: hook,
@@ -85,24 +73,12 @@ func RunTLSServer(s *http.Server, hook Webhook, addr string, path string, certFi
8573

8674
s.Handler = srv
8775

88-
return run(s, certFile, keyFile)
89-
}
90-
91-
func run(s *http.Server, files ...string) error {
92-
if len(files) == 0 {
93-
return s.ListenAndServe()
94-
} else if len(files) == 2 {
95-
return s.ListenAndServeTLS(files[0], files[1])
96-
}
97-
98-
return errors.New("invalid server configuration")
76+
return s.ListenAndServeTLS("", "")
9977
}
10078

10179
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
10280
defer r.Body.Close()
10381

104-
fmt.Println("GOT HERE!")
105-
10682
if r.Method != "POST" {
10783
http.Error(w, "405 Method not allowed", http.StatusMethodNotAllowed)
10884
return

webhooks_test.go

Lines changed: 204 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package webhooks
22

33
import (
4+
"bytes"
5+
"crypto/tls"
6+
"net/http"
47
"os"
58
"testing"
69

@@ -18,16 +21,215 @@ import (
1821
// go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html
1922
//
2023

24+
type FakeWebhook struct {
25+
provider Provider
26+
}
27+
28+
func (fhook FakeWebhook) Provider() Provider {
29+
return fhook.provider
30+
}
31+
32+
func (fhook FakeWebhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
33+
}
34+
35+
var fakeHook Webhook
36+
2137
func TestMain(m *testing.M) {
2238

2339
// setup
40+
fakeHook = &FakeWebhook{
41+
provider: GitHub,
42+
}
2443

2544
os.Exit(m.Run())
2645

2746
// teardown
2847
}
2948

30-
func TestHooks(t *testing.T) {
49+
func TestRun(t *testing.T) {
50+
51+
go Run(fakeHook, ":3006", "/webhooks")
52+
53+
payload := "{}"
54+
55+
req, err := http.NewRequest("POST", "http://localhost:3006/webhooks", bytes.NewBuffer([]byte(payload)))
56+
req.Header.Set("Content-Type", "application/json")
57+
58+
Equal(t, err, nil)
59+
60+
client := &http.Client{}
61+
resp, err := client.Do(req)
62+
Equal(t, err, nil)
63+
64+
defer resp.Body.Close()
65+
66+
Equal(t, resp.StatusCode, http.StatusOK)
67+
68+
// While HTTP Server is running test some bad input
69+
70+
// Test BAD URL
71+
req, err = http.NewRequest("POST", "http://localhost:3006", bytes.NewBuffer([]byte(payload)))
72+
req.Header.Set("Content-Type", "application/json")
73+
74+
Equal(t, err, nil)
75+
76+
resp, err = client.Do(req)
77+
Equal(t, err, nil)
78+
79+
defer resp.Body.Close()
80+
81+
Equal(t, resp.StatusCode, http.StatusNotFound)
82+
83+
// Test BAD METHOD
84+
req, err = http.NewRequest("GET", "http://localhost:3006/webhooks", bytes.NewBuffer([]byte(payload)))
85+
req.Header.Set("Content-Type", "application/json")
86+
87+
Equal(t, err, nil)
88+
89+
resp, err = client.Do(req)
90+
Equal(t, err, nil)
91+
92+
defer resp.Body.Close()
93+
94+
Equal(t, resp.StatusCode, http.StatusMethodNotAllowed)
95+
}
96+
97+
func TestRunServer(t *testing.T) {
98+
99+
server := &http.Server{Addr: ":3007", Handler: nil}
100+
go RunServer(server, fakeHook, "/webhooks")
101+
102+
payload := "{}"
103+
104+
req, err := http.NewRequest("POST", "http://localhost:3007/webhooks", bytes.NewBuffer([]byte(payload)))
105+
req.Header.Set("Content-Type", "application/json")
106+
107+
Equal(t, err, nil)
108+
109+
client := &http.Client{}
110+
resp, err := client.Do(req)
111+
Equal(t, err, nil)
112+
113+
defer resp.Body.Close()
114+
115+
Equal(t, resp.StatusCode, http.StatusOK)
116+
117+
// While HTTP Server is running test some bad input
118+
119+
// Test BAD URL
120+
req, err = http.NewRequest("POST", "http://localhost:3007", bytes.NewBuffer([]byte(payload)))
121+
req.Header.Set("Content-Type", "application/json")
122+
123+
Equal(t, err, nil)
124+
125+
resp, err = client.Do(req)
126+
Equal(t, err, nil)
127+
128+
defer resp.Body.Close()
129+
130+
Equal(t, resp.StatusCode, http.StatusNotFound)
131+
132+
// Test BAD METHOD
133+
req, err = http.NewRequest("GET", "http://localhost:3007/webhooks", bytes.NewBuffer([]byte(payload)))
134+
req.Header.Set("Content-Type", "application/json")
135+
136+
Equal(t, err, nil)
137+
138+
resp, err = client.Do(req)
139+
Equal(t, err, nil)
140+
141+
defer resp.Body.Close()
142+
143+
Equal(t, resp.StatusCode, http.StatusMethodNotAllowed)
144+
}
145+
146+
func TestRunTLSServer(t *testing.T) {
147+
148+
var err error
149+
150+
// can have certificates in static variables or load from disk
151+
cert := `-----BEGIN CERTIFICATE-----
152+
MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
153+
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
154+
aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
155+
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
156+
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
157+
hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
158+
rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
159+
zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
160+
MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
161+
r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
162+
-----END CERTIFICATE-----
163+
`
164+
key := `-----BEGIN RSA PRIVATE KEY-----
165+
MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
166+
k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
167+
6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
168+
MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
169+
SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
170+
xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
171+
D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
172+
-----END RSA PRIVATE KEY-----
173+
`
174+
175+
server := &http.Server{Addr: ":3008", Handler: nil, TLSConfig: &tls.Config{}}
176+
server.TLSConfig.Certificates = make([]tls.Certificate, 1)
177+
178+
server.TLSConfig.Certificates[0], err = tls.X509KeyPair([]byte(cert), []byte(key))
179+
Equal(t, err, nil)
180+
181+
go RunTLSServer(server, fakeHook, "/webhooks")
182+
183+
payload := "{}"
184+
185+
req, err := http.NewRequest("POST", "https://localhost:3008/webhooks", bytes.NewBuffer([]byte(payload)))
186+
req.Header.Set("Content-Type", "application/json")
187+
188+
Equal(t, err, nil)
189+
190+
tr := &http.Transport{
191+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
192+
}
193+
194+
client := &http.Client{Transport: tr}
195+
resp, err := client.Do(req)
196+
Equal(t, err, nil)
197+
198+
defer resp.Body.Close()
199+
200+
Equal(t, resp.StatusCode, http.StatusOK)
201+
202+
// While HTTP Server is running test some bad input
203+
204+
// Test BAD URL
205+
req, err = http.NewRequest("POST", "https://localhost:3008", bytes.NewBuffer([]byte(payload)))
206+
req.Header.Set("Content-Type", "application/json")
207+
208+
Equal(t, err, nil)
209+
210+
resp, err = client.Do(req)
211+
Equal(t, err, nil)
212+
213+
defer resp.Body.Close()
214+
215+
Equal(t, resp.StatusCode, http.StatusNotFound)
216+
217+
// Test BAD METHOD
218+
req, err = http.NewRequest("GET", "https://localhost:3008/webhooks", bytes.NewBuffer([]byte(payload)))
219+
req.Header.Set("Content-Type", "application/json")
220+
221+
Equal(t, err, nil)
222+
223+
resp, err = client.Do(req)
224+
Equal(t, err, nil)
225+
226+
defer resp.Body.Close()
227+
228+
Equal(t, resp.StatusCode, http.StatusMethodNotAllowed)
229+
}
230+
231+
func TestProviderString(t *testing.T) {
31232

32-
Equal(t, true, true)
233+
Equal(t, GitHub.String(), "GitHub")
234+
Equal(t, Provider(999999).String(), "Unknown")
33235
}

0 commit comments

Comments
 (0)