refactor: internal package
This commit is contained in:
96
internal/httpx/mock.go
Normal file
96
internal/httpx/mock.go
Normal file
@@ -0,0 +1,96 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user