Repository: firebase/firebase-admin-java
Pull request #147 (2018-02-26 23:46:06)

Improved Auth Unit Test Coverage
Unit tests currently test the `FirebaseUserManager` internal class, but does not test the public API surface in `FirebaseAuth`. As a result the `com.google.firebase.auth` package has a test coverage of only 69%. This PR modifies the tests so that we test the public API surface, bringing the package test coverage to 91%. 

The overall test coverage goes from 81% to 82%.

hiranya911: Made the suggested changes.

Patch:
diff --git a/src/main/java/com/google/firebase/auth/FirebaseAuth.java b/src/main/java/com/google/firebase/auth/FirebaseAuth.java
index efd4ad7..52fd7ed 100644
--- a/src/main/java/com/google/firebase/auth/FirebaseAuth.java
+++ b/src/main/java/com/google/firebase/auth/FirebaseAuth.java
@@ -40,7 +40,6 @@ import com.google.firebase.internal.FirebaseService;
 import com.google.firebase.internal.Nullable;
 import com.google.firebase.internal.TaskToApiFuture;
 import com.google.firebase.tasks.Task;
-import java.util.Date;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -608,6 +607,11 @@ public class FirebaseAuth {
     return ImplFirebaseTrampolines.submitCallable(firebaseApp, command);
   }
 
+  @VisibleForTesting
+  FirebaseUserManager getUserManager() {
+    return this.userManager;
+  }
+
   private void checkNotDestroyed() {
     synchronized (lock) {
       checkState(!destroyed.get(), "FirebaseAuth instance is no longer alive. This happens when "
diff --git a/src/main/java/com/google/firebase/auth/ListUsersPage.java b/src/main/java/com/google/firebase/auth/ListUsersPage.java
index c0fc14a..f406366 100644
--- a/src/main/java/com/google/firebase/auth/ListUsersPage.java
+++ b/src/main/java/com/google/firebase/auth/ListUsersPage.java
@@ -81,7 +81,11 @@ public class ListUsersPage implements Page<ExportedUserRecord> {
   public ListUsersPage getNextPage() {
     if (hasNextPage()) {
       PageFactory factory = new PageFactory(source, maxResults, currentBatch.getNextPageToken());
-      return factory.create();
+      try {
+        return factory.create();
+      } catch (FirebaseAuthException e) {
+        throw new RuntimeException(e);
+      }
     }
     return null;
   }
@@ -179,7 +183,7 @@ public class ListUsersPage implements Page<ExportedUserRecord> {
    */
   interface UserSource {
     @NonNull
-    ListUsersResult fetch(int maxResults, String pageToken);
+    ListUsersResult fetch(int maxResults, String pageToken) throws FirebaseAuthException;
   }
 
   static class DefaultUserSource implements UserSource {
@@ -193,21 +197,17 @@ public class ListUsersPage implements Page<ExportedUserRecord> {
     }
 
     @Override
-    public ListUsersResult fetch(int maxResults, String pageToken) {
-      try {
-        DownloadAccountResponse response = userManager.listUsers(maxResults, pageToken);
-        ImmutableList.Builder<ExportedUserRecord> builder = ImmutableList.builder();
-        if (response.hasUsers()) {
-          for (DownloadAccountResponse.User user : response.getUsers()) {
-            builder.add(new ExportedUserRecord(user, jsonFactory));
-          }
+    public ListUsersResult fetch(int maxResults, String pageToken) throws FirebaseAuthException {
+      DownloadAccountResponse response = userManager.listUsers(maxResults, pageToken);
+      ImmutableList.Builder<ExportedUserRecord> builder = ImmutableList.builder();
+      if (response.hasUsers()) {
+        for (DownloadAccountResponse.User user : response.getUsers()) {
+          builder.add(new ExportedUserRecord(user, jsonFactory));
         }
-        String nextPageToken = response.getPageToken() != null
-            ? response.getPageToken() : END_OF_LIST;
-        return new ListUsersResult(builder.build(), nextPageToken);
-      } catch (Exception e) {
-        throw new RuntimeException("Error while downloading user accounts", e);
       }
+      String nextPageToken = response.getPageToken() != null
+          ? response.getPageToken() : END_OF_LIST;
+      return new ListUsersResult(builder.build(), nextPageToken);
     }
   }
 
@@ -257,7 +257,7 @@ public class ListUsersPage implements Page<ExportedUserRecord> {
       this.pageToken = pageToken;
     }
 
-    ListUsersPage create() {
+    ListUsersPage create() throws FirebaseAuthException {
       ListUsersResult batch = source.fetch(maxResults, pageToken);
       return new ListUsersPage(batch, source, maxResults);
     }


Test patch:
diff --git a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
index f1e92ce..de6862b 100644
--- a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
+++ b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java
@@ -18,6 +18,7 @@ package com.google.firebase.auth;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -27,152 +28,128 @@ import com.google.api.client.http.HttpHeaders;
 import com.google.api.client.http.HttpResponseException;
 import com.google.api.client.json.GenericJson;
 import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.gson.GsonFactory;
 import com.google.api.client.testing.http.MockHttpTransport;
 import com.google.api.client.testing.http.MockLowLevelHttpResponse;
 import com.google.auth.oauth2.GoogleCredentials;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.firebase.FirebaseApp;
+import com.google.firebase.FirebaseOptions;
+import com.google.firebase.TestOnlyImplFirebaseTrampolines;
 import com.google.firebase.auth.UserRecord.CreateRequest;
 import com.google.firebase.auth.UserRecord.UpdateRequest;
-import com.google.firebase.auth.internal.DownloadAccountResponse;
-import com.google.firebase.auth.internal.DownloadAccountResponse.User;
 import com.google.firebase.internal.SdkUtils;
+import com.google.firebase.testing.MultiRequestMockHttpTransport;
 import com.google.firebase.testing.TestResponseInterceptor;
 import com.google.firebase.testing.TestUtils;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import java.util.concurrent.ExecutionException;
+import org.junit.After;
 import org.junit.Test;
 
 public class FirebaseUserManagerTest {
 
   private static final String TEST_TOKEN = "token";
-  private static final GsonFactory gson = new GsonFactory();
   private static final GoogleCredentials credentials = new MockGoogleCredentials(TEST_TOKEN);
 
+  @After
+  public void tearDown() {
+    TestOnlyImplFirebaseTrampolines.clearInstancesForTest();
+  }
+
   @Test
   public void testGetUser() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    UserRecord userRecord = userManager.getUserById("testuser");
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("getUser.json"));
+    UserRecord userRecord = FirebaseAuth.getInstance().getUserAsync("testuser").get();
     checkUserRecord(userRecord);
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testGetUserWithNotFoundError() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUserError.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    initializeAppForUserManagement(TestUtils.loadResource("getUserError.json"));
     try {
-      userManager.getUserById("testuser");
+      FirebaseAuth.getInstance().getUserAsync("testuser").get();
       fail("No error thrown for invalid response");
-    } catch (FirebaseAuthException e) {
-      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, e.getErrorCode());
+    } catch (ExecutionException e) {
+      assertTrue(e.getCause() instanceof FirebaseAuthException);
+      FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, authException.getErrorCode());
     }
   }
 
   @Test
   public void testGetUserByEmail() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    UserRecord userRecord = userManager.getUserByEmail("testuser@example.com");
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("getUser.json"));
+    UserRecord userRecord = FirebaseAuth.getInstance()
+        .getUserByEmailAsync("testuser@example.com").get();
     checkUserRecord(userRecord);
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testGetUserByEmailWithNotFoundError() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUserError.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    initializeAppForUserManagement(TestUtils.loadResource("getUserError.json"));
     try {
-      userManager.getUserByEmail("testuser@example.com");
+      FirebaseAuth.getInstance().getUserByEmailAsync("testuser@example.com").get();
       fail("No error thrown for invalid response");
-    } catch (FirebaseAuthException e) {
-      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, e.getErrorCode());
+    } catch (ExecutionException e) {
+      assertTrue(e.getCause() instanceof FirebaseAuthException);
+      FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, authException.getErrorCode());
     }
   }
 
   @Test
   public void testGetUserByPhoneNumber() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    UserRecord userRecord = userManager.getUserByPhoneNumber("+1234567890");
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("getUser.json"));
+    UserRecord userRecord = FirebaseAuth.getInstance()
+        .getUserByPhoneNumberAsync("+1234567890").get();
     checkUserRecord(userRecord);
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testGetUserByPhoneNumberWithNotFoundError() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("getUserError.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    initializeAppForUserManagement(TestUtils.loadResource("getUserError.json"));
     try {
-      userManager.getUserByPhoneNumber("+1234567890");
+      FirebaseAuth.getInstance().getUserByPhoneNumberAsync("+1234567890").get();
       fail("No error thrown for invalid response");
-    } catch (FirebaseAuthException e) {
-      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, e.getErrorCode());
+    } catch (ExecutionException e) {
+      assertTrue(e.getCause() instanceof FirebaseAuthException);
+      FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+      assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, authException.getErrorCode());
     }
   }
 
   @Test
   public void testListUsers() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("listUsers.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-
-    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
-    DownloadAccountResponse download = userManager.listUsers(999, null);
-    assertEquals(2, download.getUsers().size());
-    for (User user : download.getUsers()) {
-      ExportedUserRecord userRecord = new ExportedUserRecord(user, jsonFactory);
+    final TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("listUsers.json"));
+    ListUsersPage page = FirebaseAuth.getInstance().listUsersAsync(null, 999).get();
+    assertEquals(2, Iterables.size(page.getValues()));
+    for (ExportedUserRecord userRecord : page.getValues()) {
       checkUserRecord(userRecord);
       assertEquals("passwordHash", userRecord.getPasswordHash());
       assertEquals("passwordSalt", userRecord.getPasswordSalt());
     }
-    assertNull(download.getPageToken());
+    assertEquals("", page.getNextPageToken());
     checkRequestHeaders(interceptor);
 
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     interceptor.getResponse().getRequest().getContent().writeTo(out);
+    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
     GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class);
     assertEquals(new BigDecimal(999), parsed.get("maxResults"));
     assertNull(parsed.get("nextPageToken"));
@@ -180,29 +157,21 @@ public class FirebaseUserManagerTest {
 
   @Test
   public void testListUsersWithPageToken() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("listUsers.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-
-    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
-    DownloadAccountResponse download = userManager.listUsers(999, "token");
-    assertEquals(2, download.getUsers().size());
-    for (User user : download.getUsers()) {
-      ExportedUserRecord userRecord = new ExportedUserRecord(user, jsonFactory);
+    final TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("listUsers.json"));
+    ListUsersPage page = FirebaseAuth.getInstance().listUsersAsync("token", 999).get();
+    assertEquals(2, Iterables.size(page.getValues()));
+    for (ExportedUserRecord userRecord : page.getValues()) {
       checkUserRecord(userRecord);
       assertEquals("passwordHash", userRecord.getPasswordHash());
       assertEquals("passwordSalt", userRecord.getPasswordSalt());
     }
-    assertNull(download.getPageToken());
+    assertEquals("", page.getNextPageToken());
     checkRequestHeaders(interceptor);
 
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     interceptor.getResponse().getRequest().getContent().writeTo(out);
+    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
     GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class);
     assertEquals(new BigDecimal(999), parsed.get("maxResults"));
     assertEquals("token", parsed.get("nextPageToken"));
@@ -210,87 +179,74 @@ public class FirebaseUserManagerTest {
 
   @Test
   public void testListZeroUsers() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent("{}");
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    DownloadAccountResponse download = userManager.listUsers(999, null);
-    assertNull(download.getUsers());
-    assertNull(download.getPageToken());
+    TestResponseInterceptor interceptor = initializeAppForUserManagement("{}");
+    ListUsersPage page = FirebaseAuth.getInstance().listUsersAsync(null).get();
+    assertTrue(Iterables.isEmpty(page.getValues()));
+    assertEquals("", page.getNextPageToken());
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testCreateUser() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("createUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    String uid = userManager.createUser(new CreateRequest());
-    assertEquals("testuser", uid);
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("createUser.json"),
+        TestUtils.loadResource("getUser.json"));
+    UserRecord user = FirebaseAuth.getInstance().createUserAsync(new CreateRequest()).get();
+    checkUserRecord(user);
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testUpdateUser() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("createUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
-    // should not throw
-    userManager.updateUser(new UpdateRequest("testuser"), Utils.getDefaultJsonFactory());
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("createUser.json"),
+        TestUtils.loadResource("getUser.json"));
+    UserRecord user = FirebaseAuth.getInstance()
+        .updateUserAsync(new UpdateRequest("testuser")).get();
+    checkUserRecord(user);
     checkRequestHeaders(interceptor);
   }
 
   @Test
   public void testSetCustomAttributes() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("createUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("createUser.json"));
     // should not throw
     ImmutableMap<String, Object> claims = ImmutableMap.<String, Object>of(
         "admin", true, "package", "gold");
-    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
-    userManager.updateUser(new UpdateRequest("testuser")
-        .setCustomClaims(claims), jsonFactory);
+    FirebaseAuth.getInstance().setCustomUserClaimsAsync("testuser", claims).get();
     checkRequestHeaders(interceptor);
 
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     interceptor.getResponse().getRequest().getContent().writeTo(out);
+    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
     GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class);
     assertEquals("testuser", parsed.get("localId"));
     assertEquals(jsonFactory.toString(claims), parsed.get("customAttributes"));
   }
 
+  @Test
+  public void testRevokeRefreshTokens() throws Exception {
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("createUser.json"));
+    // should not throw
+    FirebaseAuth.getInstance().revokeRefreshTokensAsync("testuser").get();
+    checkRequestHeaders(interceptor);
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    interceptor.getResponse().getRequest().getContent().writeTo(out);
+    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
+    GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class);
+    assertEquals("testuser", parsed.get("localId"));
+    assertNotNull(parsed.get("validSince"));
+  }
+
   @Test
   public void testDeleteUser() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent(TestUtils.loadResource("deleteUser.json"));
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
-    TestResponseInterceptor interceptor = new TestResponseInterceptor();
-    userManager.setInterceptor(interceptor);
+    TestResponseInterceptor interceptor = initializeAppForUserManagement(
+        TestUtils.loadResource("deleteUser.json"));
     // should not throw
-    userManager.deleteUser("testuser");
+    FirebaseAuth.getInstance().deleteUserAsync("testuser").get();
     checkRequestHeaders(interceptor);
   }
 
@@ -299,44 +255,44 @@ public class FirebaseUserManagerTest {
     List<UserManagerOp> operations = ImmutableList.<UserManagerOp>builder()
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.getUserById("testuser");
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.getUserAsync("testuser").get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.getUserByEmail("testuser@example.com");
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.getUserByEmailAsync("testuser@example.com").get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.getUserByPhoneNumber("+1234567890");
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.getUserByPhoneNumberAsync("+1234567890").get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.createUser(new CreateRequest());
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.createUserAsync(new CreateRequest()).get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.updateUser(new UpdateRequest("test"), Utils.getDefaultJsonFactory());
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.updateUserAsync(new UpdateRequest("test")).get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.deleteUser("testuser");
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.deleteUserAsync("testuser").get();
           }
         })
         .add(new UserManagerOp() {
           @Override
-          public void call(FirebaseUserManager userManager) throws Exception {
-            userManager.listUsers(1000, null);
+          public void call(FirebaseAuth auth) throws Exception {
+            auth.listUsersAsync(null, 1000).get();
           }
         })
         .build();
@@ -345,7 +301,10 @@ public class FirebaseUserManagerTest {
     MockHttpTransport transport = new MockHttpTransport.Builder()
         .setLowLevelHttpResponse(response)
         .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    FirebaseApp.initializeApp(new FirebaseOptions.Builder()
+        .setCredentials(credentials)
+        .setHttpTransport(transport)
+        .build());
 
     // Test for common HTTP error codes
     for (int code : ImmutableList.of(302, 400, 401, 404, 500)) {
@@ -354,13 +313,15 @@ public class FirebaseUserManagerTest {
         response.setContent("{}");
         response.setStatusCode(code);
         try {
-          operation.call(userManager);
-          fail("No error thrown for HTTP error");
-        }  catch (FirebaseAuthException e) {
+          operation.call(FirebaseAuth.getInstance());
+          fail("No error thrown for HTTP error: " + code);
+        } catch (ExecutionException e) {
+          assertTrue(e.getCause().toString(), e.getCause() instanceof FirebaseAuthException);
+          FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
           String msg = String.format("Unexpected HTTP response with status: %d; body: {}", code);
-          assertEquals(msg, e.getMessage());
-          assertTrue(e.getCause() instanceof HttpResponseException);
-          assertEquals(FirebaseUserManager.INTERNAL_ERROR, e.getErrorCode());
+          assertEquals(msg, authException.getMessage());
+          assertTrue(authException.getCause() instanceof HttpResponseException);
+          assertEquals(FirebaseUserManager.INTERNAL_ERROR, authException.getErrorCode());
         }
       }
     }
@@ -370,30 +331,29 @@ public class FirebaseUserManagerTest {
       response.setContent("{\"error\": {\"message\": \"USER_NOT_FOUND\"}}");
       response.setStatusCode(500);
       try {
-        operation.call(userManager);
+        operation.call(FirebaseAuth.getInstance());
         fail("No error thrown for HTTP error");
-      }  catch (FirebaseAuthException e) {
-        assertEquals("User management service responded with an error", e.getMessage());
-        assertTrue(e.getCause() instanceof HttpResponseException);
-        assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, e.getErrorCode());
+      }  catch (ExecutionException e) {
+        assertTrue(e.getCause().toString(), e.getCause() instanceof FirebaseAuthException);
+        FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+        assertEquals("User management service responded with an error", authException.getMessage());
+        assertTrue(authException.getCause() instanceof HttpResponseException);
+        assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR, authException.getErrorCode());
       }
     }
   }
 
   @Test
   public void testGetUserMalformedJsonError() throws Exception {
-    MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
-    response.setContent("{\"not\" json}");
-    MockHttpTransport transport = new MockHttpTransport.Builder()
-        .setLowLevelHttpResponse(response)
-        .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    initializeAppForUserManagement("{\"not\" json}");
     try {
-      userManager.getUserById("testuser");
+      FirebaseAuth.getInstance().getUserAsync("testuser").get();
       fail("No error thrown for JSON error");
-    }  catch (FirebaseAuthException e) {
-      assertTrue(e.getCause() instanceof IOException);
-      assertEquals(FirebaseUserManager.INTERNAL_ERROR, e.getErrorCode());
+    }  catch (ExecutionException e) {
+      assertTrue(e.getCause() instanceof FirebaseAuthException);
+      FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+      assertTrue(authException.getCause() instanceof IOException);
+      assertEquals(FirebaseUserManager.INTERNAL_ERROR, authException.getErrorCode());
     }
   }
 
@@ -405,15 +365,20 @@ public class FirebaseUserManagerTest {
     MockHttpTransport transport = new MockHttpTransport.Builder()
         .setLowLevelHttpResponse(response)
         .build();
-    FirebaseUserManager userManager = new FirebaseUserManager(gson, transport, credentials);
+    FirebaseApp.initializeApp(new FirebaseOptions.Builder()
+        .setCredentials(credentials)
+        .setHttpTransport(transport)
+        .build());
     try {
-      userManager.getUserById("testuser");
+      FirebaseAuth.getInstance().getUserAsync("testuser").get();
       fail("No error thrown for JSON error");
-    }  catch (FirebaseAuthException e) {
-      assertTrue(e.getCause() instanceof HttpResponseException);
+    }  catch (ExecutionException e) {
+      assertTrue(e.getCause() instanceof FirebaseAuthException);
+      FirebaseAuthException authException = (FirebaseAuthException) e.getCause();
+      assertTrue(authException.getCause() instanceof HttpResponseException);
       assertEquals("Unexpected HTTP response with status: 500; body: {\"not\" json}",
-          e.getMessage());
-      assertEquals(FirebaseUserManager.INTERNAL_ERROR, e.getErrorCode());
+          authException.getMessage());
+      assertEquals(FirebaseUserManager.INTERNAL_ERROR, authException.getErrorCode());
     }
   }
 
@@ -765,7 +730,24 @@ public class FirebaseUserManagerTest {
     }
   }
 
-  private void checkUserRecord(UserRecord userRecord) {
+  private static TestResponseInterceptor initializeAppForUserManagement(String ...responses) {
+    List<MockLowLevelHttpResponse> mocks = new ArrayList<>();
+    for (String response : responses) {
+      mocks.add(new MockLowLevelHttpResponse().setContent(response));
+    }
+    MockHttpTransport transport = new MultiRequestMockHttpTransport(mocks);
+    FirebaseApp.initializeApp(new FirebaseOptions.Builder()
+        .setCredentials(credentials)
+        .setHttpTransport(transport)
+        .build());
+    FirebaseAuth auth = FirebaseAuth.getInstance();
+    FirebaseUserManager userManager = auth.getUserManager();
+    TestResponseInterceptor interceptor = new TestResponseInterceptor();
+    userManager.setInterceptor(interceptor);
+    return interceptor;
+  }
+
+  private static void checkUserRecord(UserRecord userRecord) {
     assertEquals("testuser", userRecord.getUid());
     assertEquals("testuser@example.com", userRecord.getEmail());
     assertEquals("+1234567890", userRecord.getPhoneNumber());
@@ -798,7 +780,7 @@ public class FirebaseUserManagerTest {
     assertEquals("gold", claims.get("package"));
   }
 
-  private void checkRequestHeaders(TestResponseInterceptor interceptor) {
+  private static void checkRequestHeaders(TestResponseInterceptor interceptor) {
     HttpHeaders headers = interceptor.getResponse().getRequest().getHeaders();
     String auth = "Bearer " + TEST_TOKEN;
     assertEquals(auth, headers.getFirstHeaderStringValue("Authorization"));
@@ -808,7 +790,7 @@ public class FirebaseUserManagerTest {
   }
 
   private interface UserManagerOp {
-    void call(FirebaseUserManager userManager) throws Exception;
+    void call(FirebaseAuth auth) throws Exception;
   }
   
 }
diff --git a/src/test/java/com/google/firebase/auth/ListUsersPageTest.java b/src/test/java/com/google/firebase/auth/ListUsersPageTest.java
index 449afc1..1c6282f 100644
--- a/src/test/java/com/google/firebase/auth/ListUsersPageTest.java
+++ b/src/test/java/com/google/firebase/auth/ListUsersPageTest.java
@@ -39,7 +39,7 @@ import org.junit.Test;
 public class ListUsersPageTest {
 
   @Test
-  public void testSinglePage() throws IOException {
+  public void testSinglePage() throws FirebaseAuthException, IOException {
     TestUserSource source = new TestUserSource(3);
     ListUsersPage page = new ListUsersPage.PageFactory(source).create();
     assertFalse(page.hasNextPage());
@@ -56,7 +56,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testMultiplePages() throws IOException {
+  public void testMultiplePages() throws FirebaseAuthException, IOException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.of(newUser("user0"), newUser("user1"), newUser("user2")),
         "token");
@@ -106,7 +106,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testListUsersIterable() throws IOException {
+  public void testListUsersIterable() throws FirebaseAuthException, IOException {
     TestUserSource source = new TestUserSource(3);
     ListUsersPage page = new ListUsersPage.PageFactory(source).create();
     Iterable<ExportedUserRecord> users = page.iterateAll();
@@ -132,7 +132,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testListUsersIterator() throws IOException {
+  public void testListUsersIterator() throws FirebaseAuthException, IOException {
     TestUserSource source = new TestUserSource(3);
     ListUsersPage page = new ListUsersPage.PageFactory(source).create();
     Iterable<ExportedUserRecord> users = page.iterateAll();
@@ -159,7 +159,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testListUsersPagedIterable() throws IOException {
+  public void testListUsersPagedIterable() throws FirebaseAuthException, IOException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.of(newUser("user0"), newUser("user1"), newUser("user2")),
         "token");
@@ -185,7 +185,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testListUsersPagedIterator() throws IOException {
+  public void testListUsersPagedIterator() throws FirebaseAuthException, IOException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.of(newUser("user0"), newUser("user1"), newUser("user2")),
         "token");
@@ -218,7 +218,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testPageWithNoUsers() {
+  public void testPageWithNoUsers() throws FirebaseAuthException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.<ExportedUserRecord>of(),
         ListUsersPage.END_OF_LIST);
@@ -232,7 +232,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testIterableWithNoUsers() {
+  public void testIterableWithNoUsers() throws FirebaseAuthException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.<ExportedUserRecord>of(),
         ListUsersPage.END_OF_LIST);
@@ -245,7 +245,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testIteratorWithNoUsers() {
+  public void testIteratorWithNoUsers() throws FirebaseAuthException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.<ExportedUserRecord>of(),
         ListUsersPage.END_OF_LIST);
@@ -260,7 +260,7 @@ public class ListUsersPageTest {
   }
 
   @Test
-  public void testRemove() throws IOException {
+  public void testRemove() throws FirebaseAuthException, IOException {
     ListUsersResult result = new ListUsersResult(
         ImmutableList.of(newUser("user1")),
         ListUsersPage.END_OF_LIST);
diff --git a/src/test/java/com/google/firebase/testing/MultiRequestMockHttpTransport.java b/src/test/java/com/google/firebase/testing/MultiRequestMockHttpTransport.java
new file mode 100644
index 0000000..53c34df
--- /dev/null
+++ b/src/test/java/com/google/firebase/testing/MultiRequestMockHttpTransport.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.testing;
+
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * A mock HttpTransport that can simulate multiple (sequential) HTTP interactions. This can be
+ * used when an SDK operation makes multiple backend calls.
+ */
+public class MultiRequestMockHttpTransport extends MockHttpTransport {
+
+  private final Queue<MockLowLevelHttpResponse> responses;
+
+  public MultiRequestMockHttpTransport(List<MockLowLevelHttpResponse> responses) {
+    this.responses = new LinkedList<>(responses);
+  }
+
+  @Override
+  public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
+    LowLevelHttpRequest request = super.buildRequest(method, url);
+    ((MockLowLevelHttpRequest) request).setResponse(responses.remove());
+    return request;
+  }
+}