99 "testing"
1010
1111 "github.com/stretchr/testify/assert"
12+ "github.com/stretchr/testify/mock"
1213 "github.com/stretchr/testify/require"
1314)
1415
@@ -56,6 +57,15 @@ func TestNewRequest(t *testing.T) {
5657 require .NoError (t , err )
5758 assert .JSONEq (t , `{"domain":"example.com"}` , string (b ))
5859 })
60+
61+ t .Run ("JSON marshal error" , func (t * testing.T ) {
62+ c := newClient ()
63+ // Create a value that cannot be marshaled to JSON
64+ invalidData := make (chan int )
65+ req , err := c .newRequest (context .Background (), http .MethodPost , "/v1/emails" , invalidData )
66+ assert .Error (t , err )
67+ assert .Nil (t , req )
68+ })
5969}
6070
6171// readFile reads the file from the given path.
@@ -72,3 +82,124 @@ func newTestResponse(statusCode int, body []byte) *http.Response {
7282 Body : io .NopCloser (bytes .NewReader (body )),
7383 }
7484}
85+
86+ func TestClient_do (t * testing.T ) {
87+ t .Run ("success with nil v" , func (t * testing.T ) {
88+ mDoer := newMockDoer (t )
89+ mDoer .EXPECT ().Do (mock .Anything ).Return (newTestResponse (http .StatusOK , []byte {}), nil )
90+
91+ c := newClient ()
92+ c .doer = mDoer
93+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
94+ require .NoError (t , err )
95+ resp , err := c .do (req , nil )
96+ require .NoError (t , err )
97+ assert .Equal (t , 200 , resp .StatusCode )
98+ })
99+
100+ t .Run ("error from rawDo" , func (t * testing.T ) {
101+ mDoer := newMockDoer (t )
102+ mDoer .EXPECT ().Do (mock .Anything ).Return (nil , assert .AnError )
103+
104+ c := newClient ()
105+ c .doer = mDoer
106+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
107+ require .NoError (t , err )
108+ _ , err = c .do (req , nil )
109+ assert .EqualError (t , err , assert .AnError .Error ())
110+ })
111+
112+ t .Run ("error from checkResponse" , func (t * testing.T ) {
113+ mDoer := newMockDoer (t )
114+ mDoer .EXPECT ().Do (mock .Anything ).Return (newTestResponse (http .StatusBadRequest , readFile (t , "testdata/error_response.json" )), nil )
115+
116+ c := newClient ()
117+ c .doer = mDoer
118+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
119+ require .NoError (t , err )
120+ _ , err = c .do (req , nil )
121+ require .Error (t , err )
122+ var httpErr * HTTPError
123+ assert .ErrorAs (t , err , & httpErr )
124+ assert .NotNil (t , httpErr .Response )
125+ assert .Equal (t , HTTPErrorError {
126+ Type : "request_error" ,
127+ Code : "not_found" ,
128+ Detail : "Attachment not found" ,
129+ }, httpErr .ErrorDetails )
130+ assert .Equal (t , HTTPErrorMeta {
131+ RequestID : "req_123456789" ,
132+ }, httpErr .Meta )
133+ })
134+
135+ t .Run ("JSON decode error" , func (t * testing.T ) {
136+ mDoer := newMockDoer (t )
137+ mDoer .EXPECT ().Do (mock .Anything ).Return (newTestResponse (200 , []byte ("invalid json" )), nil )
138+
139+ c := newClient ()
140+ c .doer = mDoer
141+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
142+ require .NoError (t , err )
143+ var result map [string ]interface {}
144+ _ , err = c .do (req , & result )
145+ require .Error (t , err )
146+ assert .EqualError (t , err , "invalid character 'i' looking for beginning of value" )
147+ })
148+ }
149+
150+ func TestClient_checkResponse (t * testing.T ) {
151+ t .Run ("success response" , func (t * testing.T ) {
152+ c := newClient ()
153+ resp := newResponse (newTestResponse (http .StatusOK , []byte {}))
154+ err := c .checkResponse (resp )
155+ require .NoError (t , err )
156+ })
157+
158+ t .Run ("error response" , func (t * testing.T ) {
159+ c := newClient ()
160+ resp := newResponse (newTestResponse (http .StatusBadRequest , readFile (t , "testdata/error_response.json" )))
161+ err := c .checkResponse (resp )
162+ require .Error (t , err )
163+ var httpErr * HTTPError
164+ require .ErrorAs (t , err , & httpErr )
165+ assert .Equal (t , 400 , httpErr .Response .StatusCode )
166+ assert .Equal (t , "request_error" , httpErr .ErrorDetails .Type )
167+ assert .Equal (t , "not_found" , httpErr .ErrorDetails .Code )
168+ })
169+
170+ t .Run ("error response with invalid JSON" , func (t * testing.T ) {
171+ c := newClient ()
172+ resp := newResponse (newTestResponse (http .StatusBadGateway , []byte ("invalid json" )))
173+ err := c .checkResponse (resp )
174+ require .Error (t , err )
175+ assert .Errorf (t , err , "invalid character 'i' looking for beginning of value" )
176+ })
177+ }
178+
179+ func TestClient_rawDo (t * testing.T ) {
180+ t .Run ("success" , func (t * testing.T ) {
181+ mDoer := newMockDoer (t )
182+ expectedResp := newTestResponse (http .StatusOK , []byte ("test" ))
183+ mDoer .EXPECT ().Do (mock .Anything ).Return (expectedResp , nil )
184+
185+ c := newClient ()
186+ c .doer = mDoer
187+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
188+ require .NoError (t , err )
189+ resp , err := c .rawDo (req )
190+ require .NoError (t , err )
191+ assert .Equal (t , 200 , resp .StatusCode )
192+ })
193+
194+ t .Run ("error from doer" , func (t * testing.T ) {
195+ mDoer := newMockDoer (t )
196+ mDoer .EXPECT ().Do (mock .Anything ).Return (nil , assert .AnError )
197+
198+ c := newClient ()
199+ c .doer = mDoer
200+ req , err := c .newRequest (context .Background (), http .MethodGet , "/test" , nil )
201+ require .NoError (t , err )
202+ _ , err = c .rawDo (req )
203+ assert .EqualError (t , err , assert .AnError .Error ())
204+ })
205+ }
0 commit comments