24
24
import com .cloudant .tests .util .MockWebServerResources ;
25
25
import com .cloudant .tests .util .Utils ;
26
26
import com .google .gson .Gson ;
27
+ import com .google .gson .JsonElement ;
28
+ import com .google .gson .JsonNull ;
27
29
import com .google .gson .JsonObject ;
30
+ import com .google .gson .JsonPrimitive ;
28
31
import com .squareup .okhttp .mockwebserver .Dispatcher ;
29
32
import com .squareup .okhttp .mockwebserver .MockResponse ;
30
33
import com .squareup .okhttp .mockwebserver .MockWebServer ;
@@ -228,43 +231,6 @@ public void cookieInterceptorURLEncoding() throws Exception {
228
231
}
229
232
}
230
233
231
- /**
232
- * This test checks that the cookie is successfully renewed if a 403 with an error of
233
- * "credentials_expired" is returned.
234
- *
235
- * @throws Exception
236
- */
237
- @ Test
238
- public void cookie403Renewal () throws Exception {
239
-
240
- // Request sequence
241
- // _session request to get Cookie
242
- // GET request -> 403
243
- // _session for new cookie
244
- // GET replay -> 200
245
- mockWebServer .enqueue (MockWebServerResources .OK_COOKIE );
246
- mockWebServer .enqueue (new MockResponse ().setResponseCode (403 ).setBody
247
- ("{\" error\" :\" credentials_expired\" , \" reason\" :\" Session expired\" }\r \n " ));
248
- mockWebServer .enqueue (MockWebServerResources .OK_COOKIE );
249
- mockWebServer .enqueue (new MockResponse ());
250
-
251
- CloudantClient c = CloudantClientHelper .newMockWebServerClientBuilder (mockWebServer )
252
- .username ("a" )
253
- .password ("b" )
254
- .build ();
255
- //the GET request will try to get a session, then perform the GET
256
- //the GET will result in a 403, which should mean another request to _session
257
- //followed by a replay of GET
258
- c .executeRequest (Http .GET (c .getBaseUri ()));
259
-
260
- //if we don't handle the 403 correctly an exception will be thrown
261
-
262
- // also assert that there were 4 calls
263
- assertEquals ("The server should have received 4 requests" , 4 , mockWebServer
264
- .getRequestCount ());
265
-
266
- }
267
-
268
234
/**
269
235
* This test check that the cookie is renewed if the server presents a Set-Cookie header
270
236
* after the cookie authentication.
@@ -278,7 +244,7 @@ public void cookieRenewal() throws Exception {
278
244
"AuthSession=\" RenewCookie_a2ltc3RlYmVsOjUxMzRBQTUzOtiY2_IDUIdsTJEVNEjObAbyhrgz\" ;" ;
279
245
// Request sequence
280
246
// _session request to get Cookie
281
- // GET request -> 403
247
+ // GET request -> 200 with a Set-Cookie
282
248
// _session for new cookie
283
249
// GET replay -> 200
284
250
mockWebServer .enqueue (MockWebServerResources .OK_COOKIE );
@@ -312,6 +278,19 @@ public void cookieRenewal() throws Exception {
312
278
"\" " , headerValue );
313
279
}
314
280
281
+ /**
282
+ * This test checks that the cookie is successfully renewed if a 403 with an error of
283
+ * "credentials_expired" is returned.
284
+ *
285
+ * @throws Exception
286
+ */
287
+ @ Test
288
+ public void cookie403Renewal () throws Exception {
289
+
290
+ // Test for a 403 with expired credentials, should result in 4 requests
291
+ basic403Test ("credentials_expired" , "Session expired" , 4 );
292
+ }
293
+
315
294
/**
316
295
* This test checks that if we get a 403 that is not an error of "credentials_expired" then
317
296
* the exception is correctly thrown and the error stream is deserialized. This is important
@@ -322,28 +301,90 @@ public void cookieRenewal() throws Exception {
322
301
@ Test
323
302
public void handleNonExpiry403 () throws Exception {
324
303
325
- // Request sequence
326
- // _session request to get Cookie
327
- // GET request -> 403 (CouchDbException)
304
+ // Test for a non-expiry 403, expect 2 requests
305
+ basic403Test ("403_not_expired_test" , "example reason" , 2 );
306
+ }
307
+
308
+ /**
309
+ * Same as {@link #handleNonExpiry403()} but with no reason property in the JSON.
310
+ *
311
+ * @throws Exception
312
+ */
313
+ @ Test
314
+ public void handleNonExpiry403NoReason () throws Exception {
315
+
316
+ // Test for a non-expiry 403, expect 2 requests
317
+ basic403Test ("403_not_expired_test" , null , 2 );
318
+ }
319
+
320
+ /**
321
+ * * Same as {@link #handleNonExpiry403()} but with a {@code null} reason property in the JSON.
322
+ *
323
+ * @throws Exception
324
+ */
325
+ @ Test
326
+ public void handleNonExpiry403NullReason () throws Exception {
327
+
328
+ // Test for a non-expiry 403, expect 2 requests
329
+ basic403Test ("403_not_expired_test" , "null" , 2 );
330
+ }
331
+
332
+ /**
333
+ * Method that performs a basic test for a 403 response. The sequence of requests is:
334
+ * <OL>
335
+ * <LI>_session request to get Cookie</LI>
336
+ * <LI>GET request -> a 403 response</LI>
337
+ * <LI>_session for new cookie*</LI>
338
+ * <LI>GET replay -> a 200 response*</LI>
339
+ * </OL>
340
+ * The requests annotated * should only happen in the credentials_expired 403 case
341
+ *
342
+ * @param error the response JSON error content for the 403
343
+ * @param reason the response JSON reason content for the 403
344
+ */
345
+ private void basic403Test (String error , String reason , int expectedRequests ) throws
346
+ Exception {
328
347
mockWebServer .enqueue (MockWebServerResources .OK_COOKIE );
329
- mockWebServer .enqueue (new MockResponse ().setResponseCode (403 ).setBody
330
- ("{\" error\" :\" 403_not_expired_test\" , \" reason\" :\" example reason\" }\r \n " ));
348
+ JsonObject responseBody = new JsonObject ();
349
+ responseBody .add ("error" , new JsonPrimitive (error ));
350
+ JsonElement jsonReason ;
351
+ if (reason != null ) {
352
+ if ("null" .equals (reason )) {
353
+ jsonReason = JsonNull .INSTANCE ;
354
+ reason = null ; // For the assertion we need a real null, not a JsonNull
355
+ } else {
356
+ jsonReason = new JsonPrimitive (reason );
357
+ }
358
+ responseBody .add ("reason" , jsonReason );
359
+ }
360
+ mockWebServer .enqueue (new MockResponse ().setResponseCode (403 ).setBody (responseBody
361
+ .toString ()));
362
+ mockWebServer .enqueue (MockWebServerResources .OK_COOKIE );
363
+ mockWebServer .enqueue (new MockResponse ());
364
+
365
+ CloudantClient c = CloudantClientHelper .newMockWebServerClientBuilder (mockWebServer )
366
+ .username ("a" )
367
+ .password ("b" )
368
+ .build ();
331
369
370
+ //the GET request will try to get a session, then perform the GET
371
+ //the GET will result in a 403, which in a renewal case should mean another request to
372
+ // _session followed by a replay of GET
332
373
try {
333
- CloudantClient c = CloudantClientHelper .newMockWebServerClientBuilder (mockWebServer )
334
- .username ("a" )
335
- .password ("b" )
336
- .build ();
337
- //the GET request will try to get a session, then perform the GET
338
- //the GET will result in a 403, which should result in a CouchDbException
339
374
c .executeRequest (Http .GET (c .getBaseUri ()));
340
- fail ("A 403 not due to cookie expiry should result in a CouchDbException" );
375
+ if (!error .equals ("credentials_expired" )) {
376
+ fail ("A 403 not due to cookie expiry should result in a CouchDbException" );
377
+ }
341
378
} catch (CouchDbException e ) {
342
- e .printStackTrace ();
343
- assertNotNull ("The error should not be null" , e .getError ());
344
- assertEquals ("The error message should be the expected one" , "403_not_expired_test" , e
345
- .getError ());
379
+ assertEquals ("The exception error should be the expected message" , error , e .getError ());
380
+ assertEquals ("The exception reason should be the expected message" , reason , e
381
+ .getReason ());
346
382
}
383
+
384
+ // also assert that there were the correct number of calls
385
+ assertEquals ("The server should receive the expected number of requests" ,
386
+ expectedRequests , mockWebServer
387
+ .getRequestCount ());
347
388
}
348
389
349
390
@ Test
0 commit comments