1package api
2
3import (
4	"encoding/json"
5	"io"
6	"io/ioutil"
7	"net/http"
8	"net/http/httptest"
9	"testing"
10
11	"github.com/stretchr/testify/mock"
12	"github.com/stretchr/testify/require"
13)
14
15type mockAPI struct {
16	ts *httptest.Server
17	t  *testing.T
18	mock.Mock
19}
20
21func setupMockAPI(t *testing.T) (*mockAPI, *Client) {
22	mapi := mockAPI{t: t}
23	mapi.Test(t)
24	mapi.ts = httptest.NewServer(&mapi)
25	t.Cleanup(func() {
26		mapi.ts.Close()
27		mapi.Mock.AssertExpectations(t)
28	})
29
30	cfg := DefaultConfig()
31	cfg.Address = mapi.ts.URL
32
33	client, err := NewClient(cfg)
34	require.NoError(t, err)
35	return &mapi, client
36}
37
38func (m *mockAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
39	var body interface{}
40
41	if r.Body != nil {
42		bodyBytes, err := ioutil.ReadAll(r.Body)
43		if err == nil && len(bodyBytes) > 0 {
44			body = bodyBytes
45
46			var bodyMap map[string]interface{}
47			if err := json.Unmarshal(bodyBytes, &bodyMap); err != nil {
48				body = bodyMap
49			}
50		}
51	}
52
53	ret := m.Called(r.Method, r.URL.Path, body)
54
55	if replyFn, ok := ret.Get(0).(func(http.ResponseWriter, *http.Request)); ok {
56		replyFn(w, r)
57		return
58	}
59}
60
61func (m *mockAPI) static(method string, path string, body interface{}) *mock.Call {
62	return m.On("ServeHTTP", method, path, body)
63}
64
65func (m *mockAPI) withReply(method, path string, body interface{}, status int, reply interface{}) *mock.Call {
66	return m.static(method, path, body).Return(func(w http.ResponseWriter, r *http.Request) {
67		w.WriteHeader(status)
68
69		if reply == nil {
70			return
71		}
72
73		rdr, ok := reply.(io.Reader)
74		if ok {
75			io.Copy(w, rdr)
76			return
77		}
78
79		enc := json.NewEncoder(w)
80		require.NoError(m.t, enc.Encode(reply))
81	})
82}
83