-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathchecker.go
149 lines (130 loc) · 3.92 KB
/
checker.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 goahttpcheck
import (
"context"
"log"
"net/http"
"time"
"github.com/ikawaha/httpcheck"
goahttp "goa.design/goa/v3/http"
goa "goa.design/goa/v3/pkg"
)
type (
decoder = func(*http.Request) goahttp.Decoder
encoder = func(context.Context, http.ResponseWriter) goahttp.Encoder
errorHandler = func(context.Context, http.ResponseWriter, error)
formatter = func(context.Context, error) goahttp.Statuser
middleware = func(http.Handler) http.Handler
// HandlerBuilder represents the goa http handler builder.
HandlerBuilder func(goa.Endpoint, goahttp.Muxer, decoder, encoder, errorHandler, formatter) http.Handler
// HandlerMounter represents the goa http handler mounter.
HandlerMounter func(goahttp.Muxer, http.Handler)
)
// APIChecker represents the API checker.
type APIChecker struct {
Mux goahttp.Muxer
Middleware []middleware
Decoder decoder
Encoder encoder
ErrorHandler errorHandler
Formatter formatter
ClientOptions []httpcheck.Option
}
// Option represents options for API checker.
type Option func(c *APIChecker)
// ClientTimeout sets the client timeout.
func ClientTimeout(d time.Duration) Option {
return func(c *APIChecker) {
c.ClientOptions = append(c.ClientOptions, httpcheck.ClientTimeout(d))
}
}
// CheckRedirect sets the policy of redirection to the HTTP client.
func CheckRedirect(policy func(req *http.Request, via []*http.Request) error) Option {
return func(c *APIChecker) {
c.ClientOptions = append(c.ClientOptions, httpcheck.CheckRedirect(policy))
}
}
// NoRedirect is the alias of the following:
//
// CheckRedirect(func(req *http.Request, via []*http.Request) error {
// return http.ErrUseLastResponse
// })
//
// Client returns ErrUseLastResponse, the next request is not sent and the most recent
// response is returned with its body unclosed.
func NoRedirect() Option {
return CheckRedirect(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
})
}
// Muxer sets the goa http multiplexer.
func Muxer(mux goahttp.Muxer) Option {
return func(c *APIChecker) {
c.Mux = mux
}
}
// Decoder sets the decoder.
func Decoder(dec decoder) Option {
return func(c *APIChecker) {
c.Decoder = dec
}
}
// Encoder sets the encoder.
func Encoder(enc encoder) Option {
return func(c *APIChecker) {
c.Encoder = enc
}
}
// ErrorHandler sets the error handler.
func ErrorHandler(eh errorHandler) Option {
return func(c *APIChecker) {
c.ErrorHandler = eh
}
}
// Formatter sets the error handler.
func Formatter(fm formatter) Option {
return func(c *APIChecker) {
c.Formatter = fm
}
}
// New constructs API checker.
func New(options ...Option) *APIChecker {
ret := &APIChecker{
Mux: goahttp.NewMuxer(),
Middleware: []middleware{},
Decoder: goahttp.RequestDecoder,
Encoder: goahttp.ResponseEncoder,
ErrorHandler: func(ctx context.Context, w http.ResponseWriter, err error) {
log.Printf("ERROR: %v", err)
},
}
for _, v := range options {
v(ret)
}
return ret
}
// Mount mounts the endpoint handler.
func (c *APIChecker) Mount(builder HandlerBuilder, mounter HandlerMounter, endpoint goa.Endpoint, middlewares ...middleware) {
handler := builder(endpoint, c.Mux, c.Decoder, c.Encoder, c.ErrorHandler, c.Formatter)
for _, v := range middlewares {
handler = v(handler)
}
mounter(c.Mux, handler)
}
// Use sets the middleware.
func (c *APIChecker) Use(middleware func(http.Handler) http.Handler) {
c.Middleware = append(c.Middleware, middleware)
}
// TestingT is an interface wrapper around *testing.T.
type TestingT interface {
Errorf(format string, args ...any)
FailNow()
}
// Test returns a http checker that tests the endpoint.
// see. https://github.com/ikawaha/httpcheck/
func (c APIChecker) Test(t TestingT, method, path string) *httpcheck.Tester {
var handler http.Handler = c.Mux
for _, v := range c.Middleware {
handler = v(handler)
}
return httpcheck.New(handler, c.ClientOptions...).Test(t, method, path)
}