forked from ggicci/httpin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware_test.go
More file actions
114 lines (95 loc) · 3.34 KB
/
middleware_test.go
File metadata and controls
114 lines (95 loc) · 3.34 KB
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
package httpin
import (
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/justinas/alice"
. "github.com/smartystreets/goconvey/convey"
)
type EchoInput struct {
Token string `in:"form=access_token;header=x-api-key;required"`
Saying string `in:"form=saying"`
}
func EchoHandler(rw http.ResponseWriter, r *http.Request) {
var input = r.Context().Value(Input).(*EchoInput)
json.NewEncoder(rw).Encode(input)
}
func CustomErrorHandler(rw http.ResponseWriter, r *http.Request, err error) {
var invalidFieldError *InvalidFieldError
if errors.As(err, &invalidFieldError) {
rw.WriteHeader(http.StatusBadRequest) // status: 400
io.WriteString(rw, invalidFieldError.Error())
return
}
http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) // status: 500
}
func TestMiddleware(t *testing.T) {
Convey("Should panic on invalid input", t, func() {
So(func() { NewInput(nil) }, ShouldPanic)
})
Convey("Decode request successfully", t, func() {
r, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
r.Header.Add("X-Api-Key", "abc")
var params = url.Values{}
params.Add("saying", "TO THINE OWE SELF BE TRUE")
r.URL.RawQuery = params.Encode()
rw := httptest.NewRecorder()
handler := alice.New(NewInput(EchoInput{})).ThenFunc(EchoHandler)
handler.ServeHTTP(rw, r)
So(rw.Code, ShouldEqual, 200)
expected := `{"Token":"abc","Saying":"TO THINE OWE SELF BE TRUE"}` + "\n"
So(rw.Body.String(), ShouldEqual, expected)
})
Convey("Decode request failed with default error handler", t, func() {
r, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
var params = url.Values{}
params.Add("saying", "TO THINE OWE SELF BE TRUE")
r.URL.RawQuery = params.Encode()
rw := httptest.NewRecorder()
handler := alice.New(NewInput(EchoInput{})).ThenFunc(EchoHandler)
handler.ServeHTTP(rw, r)
var out map[string]interface{}
So(json.NewDecoder(rw.Body).Decode(&out), ShouldBeNil)
So(out["field"], ShouldEqual, "Token")
So(out["source"], ShouldEqual, "required")
So(out["error"], ShouldEqual, ErrMissingField.Error())
})
Convey("Decode request failed with custom error handler", t, func() {
r, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
var params = url.Values{}
params.Add("saying", "TO THINE OWE SELF BE TRUE")
r.URL.RawQuery = params.Encode()
rw := httptest.NewRecorder()
handler := alice.New(
NewInput(EchoInput{}, WithErrorHandler(CustomErrorHandler)),
).ThenFunc(EchoHandler)
handler.ServeHTTP(rw, r)
So(rw.Code, ShouldEqual, 400)
So(rw.Body.String(), ShouldContainSubstring, `invalid field "Token":`)
})
}
func TestReplaceDefaultErrorHandler(t *testing.T) {
Convey("Given a nil handler should panic", t, func() {
So(func() { ReplaceDefaultErrorHandler(nil) }, ShouldPanic)
})
Convey("Replace default error handler globally", t, func() {
r, err := http.NewRequest("GET", "/", nil)
So(err, ShouldBeNil)
var params = url.Values{}
params.Add("saying", "TO THINE OWE SELF BE TRUE")
r.URL.RawQuery = params.Encode()
rw := httptest.NewRecorder()
handler := alice.New(NewInput(EchoInput{})).ThenFunc(EchoHandler)
// NOTE: replace global error handler after NewInput should work
ReplaceDefaultErrorHandler(CustomErrorHandler)
handler.ServeHTTP(rw, r)
So(rw.Code, ShouldEqual, 400)
})
}