Files
ozon-api-client/client.go
2023-12-11 21:30:36 +03:00

126 lines
2.5 KiB
Go

package core
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
)
type HttpClient interface {
Do(req *http.Request) (*http.Response, error)
}
type Client struct {
baseUrl string
Options map[string]string
client HttpClient
}
func NewClient(client HttpClient, baseUrl string, opts map[string]string) *Client {
return &Client{
Options: opts,
client: client,
baseUrl: baseUrl,
}
}
func NewMockClient(handler http.HandlerFunc) *Client {
return &Client{
client: NewMockHttpClient(handler),
}
}
func (c Client) newRequest(ctx context.Context, method string, uri string, body interface{}) (*http.Request, error) {
bodyJson, err := json.Marshal(body)
if err != nil {
return nil, err
}
uri, err = url.JoinPath(c.baseUrl, uri)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, method, uri, bytes.NewBuffer(bodyJson))
if err != nil {
return nil, err
}
for k, v := range c.Options {
req.Header.Add(k, v)
}
return req, nil
}
func (c Client) Request(ctx context.Context, method string, path string, req, resp interface{}, options map[string]string) (*Response, error) {
httpReq, err := c.newRequest(ctx, method, path, req)
if err != nil {
return nil, err
}
rawQuery, err := buildRawQuery(httpReq, req)
if err != nil {
return nil, err
}
httpReq.URL.RawQuery = rawQuery
httpResp, err := c.client.Do(httpReq)
if err != nil {
return nil, err
}
defer httpResp.Body.Close()
body, err := ioutil.ReadAll(httpResp.Body)
if err != nil {
return nil, err
}
response := &Response{}
response.Data = resp
response.StatusCode = httpResp.StatusCode
if httpResp.StatusCode == http.StatusOK {
err = json.Unmarshal(body, &response.Data)
} else {
err = json.Unmarshal(body, &response)
}
if err != nil {
return nil, err
}
return response, nil
}
type MockHttpClient struct {
handler http.HandlerFunc
}
func NewMockHttpClient(handler http.HandlerFunc) *MockHttpClient {
return &MockHttpClient{
handler: handler,
}
}
func (c MockHttpClient) Do(req *http.Request) (*http.Response, error) {
rr := httptest.NewRecorder()
c.handler.ServeHTTP(rr, req)
return rr.Result(), nil
}
func NewMockHttpHandler(statusCode int, json string, headers map[string]string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if len(headers) > 0 {
for key, value := range headers {
w.Header().Add(key, value)
}
}
w.WriteHeader(statusCode)
w.Write([]byte(json))
}
}