97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
package httpx
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
)
|
|
|
|
var contentTypes = map[string]string{
|
|
".json": "application/json",
|
|
".txt": "text/plain",
|
|
}
|
|
|
|
// MockClient serves responses from the file system instead of remote calls.
|
|
// Should be used for testing purposes only.
|
|
type MockClient struct {
|
|
dir string
|
|
}
|
|
|
|
// Mock creates a new MockClient and installs it instead of the default one.
|
|
func Mock(path ...string) *MockClient {
|
|
dir := filepath.Join("testdata", filepath.Join(path...))
|
|
c := &MockClient{dir: dir}
|
|
client = c
|
|
return c
|
|
}
|
|
|
|
// Do serves the file according to the request URL.
|
|
func (c *MockClient) Do(req *http.Request) (*http.Response, error) {
|
|
filename := filepath.Join(c.dir, path.Base(req.URL.Path))
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
resp := http.Response{
|
|
Status: http.StatusText(http.StatusNotFound),
|
|
StatusCode: http.StatusNotFound,
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
cType, ok := contentTypes[path.Ext(filename)]
|
|
if !ok {
|
|
cType = "application/octet-stream"
|
|
}
|
|
rdr := respond(cType, data)
|
|
resp, err := http.ReadResponse(bufio.NewReader(rdr), req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func respond(cType string, data []byte) io.Reader {
|
|
buf := bytes.Buffer{}
|
|
buf.WriteString("HTTP/1.1 200 OK\n")
|
|
buf.WriteString(fmt.Sprintf("Content-Type: %s\n\n", cType))
|
|
_, err := buf.Write(data)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return &buf
|
|
}
|
|
|
|
// MockServer creates a mock HTTP server and installs its client
|
|
// instead of the default one. Serves responses from the file system
|
|
// instead of remote calls. Should be used for testing purposes only.
|
|
func MockServer() *httptest.Server {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
filename := filepath.Join("testdata", path.Base(r.URL.Path))
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
cType, ok := contentTypes[path.Ext(filename)]
|
|
if !ok {
|
|
cType = "application/octet-stream"
|
|
}
|
|
|
|
w.Header().Set("content-type", cType)
|
|
_, err = w.Write(data)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}))
|
|
client = srv.Client()
|
|
return srv
|
|
}
|