@@ -100,15 +100,15 @@ function mockRequest(
100100}
101101
102102/**
103- * Returns a mocked out error response for a dummy URL.
103+ * Returns a mocked out HTTP error response for a dummy URL.
104104 *
105105 * @param {number } [statusCode] Optional response status code.
106106 * @param {string } [responseContentType] Optional response content type.
107107 * @param {any } [response] Optional response.
108108 *
109109 * @return {Object } A nock response object.
110110 */
111- function mockRequestWithError (
111+ function mockRequestWithHttpError (
112112 statusCode = 400 ,
113113 responseContentType = 'application/json' ,
114114 response : any = mockErrorResponse ,
@@ -124,6 +124,19 @@ function mockRequestWithError(
124124 } ) ;
125125}
126126
127+ /**
128+ * Returns a mocked out error response for a dummy URL, useful for simulating
129+ * network errors.
130+ *
131+ * @param {Error } [err] The request error.
132+ *
133+ * @return {Object } A nock response object.
134+ */
135+ function mockRequestWithError ( err : Error ) {
136+ return nock ( 'https://' + mockHost )
137+ . get ( mockPath )
138+ . replyWithError ( err ) ;
139+ }
127140
128141describe ( 'HttpRequestHandler' , ( ) => {
129142 let mockedRequests : nock . Scope [ ] = [ ] ;
@@ -151,14 +164,12 @@ describe('HttpRequestHandler', () => {
151164
152165
153166 describe ( 'sendRequest' , ( ) => {
154- it ( 'should be rejected on an unexpected error ' , ( ) => {
155- httpsRequestStub = sinon . stub ( https , 'request' ) ;
156- httpsRequestStub . returns ( mockRequestStream ) ;
167+ it ( 'should be rejected, after 1 retry, on multiple network errors ' , ( ) => {
168+ mockedRequests . push ( mockRequestWithError ( new Error ( 'first error' ) ) ) ;
169+ mockedRequests . push ( mockRequestWithError ( new Error ( 'second error' ) ) ) ;
157170
158171 const sendRequestPromise = httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' ) ;
159172
160- mockRequestStream . emit ( 'error' , new Error ( 'some error' ) ) ;
161-
162173 return sendRequestPromise
163174 . then ( ( ) => {
164175 throw new Error ( 'Unexpected success.' ) ;
@@ -168,7 +179,15 @@ describe('HttpRequestHandler', () => {
168179 expect ( response . error ) . to . have . property ( 'code' , 'app/network-error' ) ;
169180 expect ( response . statusCode ) . to . equal ( 502 ) ;
170181 } ) ;
171- } ) ;
182+ } ) ;
183+
184+ it ( 'should succeed, after 1 retry, on a single network error' , ( ) => {
185+ mockedRequests . push ( mockRequestWithError ( new Error ( 'first error' ) ) ) ;
186+ mockedRequests . push ( mockRequest ( ) ) ;
187+
188+ return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
189+ . should . eventually . be . fulfilled . and . deep . equal ( mockSuccessResponse ) ;
190+ } ) ;
172191
173192 it ( 'should be rejected on a network timeout' , ( ) => {
174193 httpsRequestStub = sinon . stub ( https , 'request' ) ;
@@ -224,7 +243,7 @@ describe('HttpRequestHandler', () => {
224243
225244 describe ( 'with JSON response' , ( ) => {
226245 it ( 'should be rejected given a 4xx response' , ( ) => {
227- mockedRequests . push ( mockRequestWithError ( 400 ) ) ;
246+ mockedRequests . push ( mockRequestWithHttpError ( 400 ) ) ;
228247
229248 return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
230249 . should . eventually . be . rejected . and . deep . equal ( {
@@ -234,7 +253,7 @@ describe('HttpRequestHandler', () => {
234253 } ) ;
235254
236255 it ( 'should be rejected given a 5xx response' , ( ) => {
237- mockedRequests . push ( mockRequestWithError ( 500 ) ) ;
256+ mockedRequests . push ( mockRequestWithHttpError ( 500 ) ) ;
238257
239258 return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
240259 . should . eventually . be . rejected . and . deep . equal ( {
@@ -244,7 +263,7 @@ describe('HttpRequestHandler', () => {
244263 } ) ;
245264
246265 it ( 'should be rejected given an error when parsing the JSON response' , ( ) => {
247- mockedRequests . push ( mockRequestWithError ( 400 , undefined , mockTextErrorResponse ) ) ;
266+ mockedRequests . push ( mockRequestWithHttpError ( 400 , undefined , mockTextErrorResponse ) ) ;
248267
249268 return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
250269 . then ( ( ) => {
@@ -275,7 +294,7 @@ describe('HttpRequestHandler', () => {
275294
276295 describe ( 'with text response' , ( ) => {
277296 it ( 'should be rejected given a 4xx response' , ( ) => {
278- mockedRequests . push ( mockRequestWithError ( 400 , 'text/html' ) ) ;
297+ mockedRequests . push ( mockRequestWithHttpError ( 400 , 'text/html' ) ) ;
279298
280299 return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
281300 . should . eventually . be . rejected . and . deep . equal ( {
@@ -285,7 +304,7 @@ describe('HttpRequestHandler', () => {
285304 } ) ;
286305
287306 it ( 'should be rejected given a 5xx response' , ( ) => {
288- mockedRequests . push ( mockRequestWithError ( 500 , 'text/html' ) ) ;
307+ mockedRequests . push ( mockRequestWithHttpError ( 500 , 'text/html' ) ) ;
289308
290309 return httpRequestHandler . sendRequest ( mockHost , mockPort , mockPath , 'GET' )
291310 . should . eventually . be . rejected . and . deep . equal ( {
0 commit comments