pkg/httpmock/stub.go (101 lines of code) (raw):

package httpmock import ( "bytes" "encoding/json" "io" "net/http" "net/url" "os" "reflect" "strings" ) type ( Matcher func(req *http.Request) bool Responder func(req *http.Request) (*http.Response, error) ) type Stub struct { matched bool Matcher Matcher Responder Responder body string } func MatchAny(*http.Request) bool { return true } func newRequest(method, path string, match matchType) Matcher { return func(req *http.Request) bool { if !strings.EqualFold(req.Method, method) { return false } if match == PathOnly { if !strings.HasPrefix(path, "/api/v4") { path = "/api/v4" + path } return req.URL.Path == path } u, err := url.Parse(path) if err != nil { return false } if match == FullURL { return req.URL.String() == u.String() } if match == HostOnly { return req.URL.Host == u.Host } if match == HostAndPath { return req.URL.Host == u.Host && req.URL.Path == u.Path } if match == PathAndQuerystring { return req.URL.RawQuery == u.RawQuery && req.URL.Path == u.Path } return false } } func newRequestWithBody(method, path, body string) Matcher { return func(req *http.Request) bool { if !strings.EqualFold(req.Method, method) { return false } u, err := url.Parse(path) if err != nil { return false } bytedata, _ := io.ReadAll(req.Body) reqBodyString := string(bytedata) return req.URL.RawQuery == u.RawQuery && req.URL.Path == u.Path && bodyEqual(reqBodyString, body) } } func NewStringResponse(status int, body string) Responder { return func(req *http.Request) (*http.Response, error) { return httpResponse(status, req, bytes.NewBufferString(body)), nil } } func NewJSONResponse(status int, body any) Responder { return func(req *http.Request) (*http.Response, error) { b, _ := json.Marshal(body) return httpResponse(status, req, bytes.NewBuffer(b)), nil } } func NewFileResponse(status int, filename string) Responder { return func(req *http.Request) (*http.Response, error) { f, err := os.Open(filename) if err != nil { return nil, err } return httpResponse(status, req, f), nil } } func httpResponse(status int, req *http.Request, body io.Reader) *http.Response { return &http.Response{ StatusCode: status, Request: req, Body: io.NopCloser(body), } } func bodyEqual(expected, actual string) bool { var expectedJSON, actualJSON any _ = json.Unmarshal([]byte(expected), &expectedJSON) _ = json.Unmarshal([]byte(actual), &actualJSON) return reflect.DeepEqual(expectedJSON, actualJSON) }