diff --git a/src/main/java/com/google/firebase/auth/FirebaseUserManager.java b/src/main/java/com/google/firebase/auth/FirebaseUserManager.java index 1d86fac8e..ec1cbe62e 100644 --- a/src/main/java/com/google/firebase/auth/FirebaseUserManager.java +++ b/src/main/java/com/google/firebase/auth/FirebaseUserManager.java @@ -36,10 +36,10 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSortedSet; import com.google.firebase.FirebaseApp; import com.google.firebase.ImplFirebaseTrampolines; -import com.google.firebase.auth.UserRecord.CreateRequest; -import com.google.firebase.auth.UserRecord.UpdateRequest; +import com.google.firebase.auth.UserRecord; import com.google.firebase.auth.internal.DownloadAccountResponse; import com.google.firebase.auth.internal.GetAccountInfoResponse; import com.google.firebase.auth.internal.HttpErrorResponse; @@ -171,7 +171,7 @@ UserRecord getUserByPhoneNumber(String phoneNumber) throws FirebaseAuthException return new UserRecord(response.getUsers().get(0), jsonFactory); } - String createUser(CreateRequest request) throws FirebaseAuthException { + String createUser(UserRecord.CreateRequest request) throws FirebaseAuthException { GenericJson response = post( "/accounts", request.getProperties(), GenericJson.class); if (response != null) { @@ -183,7 +183,8 @@ String createUser(CreateRequest request) throws FirebaseAuthException { throw new FirebaseAuthException(INTERNAL_ERROR, "Failed to create new user"); } - void updateUser(UpdateRequest request, JsonFactory jsonFactory) throws FirebaseAuthException { + void updateUser(UserRecord.UpdateRequest request, JsonFactory jsonFactory) + throws FirebaseAuthException { GenericJson response = post( "/accounts:update", request.getProperties(jsonFactory), GenericJson.class); if (response == null || !request.getUid().equals(response.get("localId"))) { @@ -230,20 +231,33 @@ UserImportResult importUsers(UserImportRequest request) throws FirebaseAuthExcep Tenant getTenant(String tenantId) throws FirebaseAuthException { GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants/" + tenantId); - Tenant response = sendRequest("GET", url, null, Tenant.class); - if (Strings.isNullOrEmpty(response.getTenantId())) { - throw new FirebaseAuthException(TENANT_NOT_FOUND_ERROR, "Failed to get tenant."); - } - return response; + return sendRequest("GET", url, null, Tenant.class); + } + + Tenant createTenant(Tenant.CreateRequest request) throws FirebaseAuthException { + GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants"); + return sendRequest("POST", url, request.getProperties(), Tenant.class); + } + + Tenant updateTenant(Tenant.UpdateRequest request) throws FirebaseAuthException { + Map properties = request.getProperties(); + checkArgument(!properties.isEmpty(), "tenant update must have at least one property set"); + GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants/" + request.getTenantId()); + url.put("updateMask", generateMask(properties)); + return sendRequest("PATCH", url, properties, Tenant.class); + } + + private static String generateMask(Map properties) { + // This implementation does not currently handle the case of nested properties. This is fine + // since we do not currently generate masks for any properties with nested values. When it + // comes time to implement this, we can check if a property has nested properties by checking + // if it is an instance of the Map class. + return String.join(",", ImmutableSortedSet.copyOf(properties.keySet())); } void deleteTenant(String tenantId) throws FirebaseAuthException { GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants/" + tenantId); - GenericJson response = sendRequest("DELETE", url, null, GenericJson.class); - if (response == null) { - throw new FirebaseAuthException(TENANT_NOT_FOUND_ERROR, - "Failed to delete tenant: " + tenantId); - } + sendRequest("DELETE", url, null, GenericJson.class); } ListTenantsResponse listTenants(int maxResults, String pageToken) diff --git a/src/main/java/com/google/firebase/auth/Tenant.java b/src/main/java/com/google/firebase/auth/Tenant.java index 366d9e997..6e489721a 100644 --- a/src/main/java/com/google/firebase/auth/Tenant.java +++ b/src/main/java/com/google/firebase/auth/Tenant.java @@ -134,6 +134,7 @@ Map getProperties() { */ public static final class UpdateRequest { + private final String tenantId; private final Map properties = new HashMap<>(); /** @@ -148,11 +149,11 @@ public static final class UpdateRequest { */ public UpdateRequest(String tenantId) { checkArgument(!Strings.isNullOrEmpty(tenantId), "tenant ID must not be null or empty"); - properties.put("name", tenantId); + this.tenantId = tenantId; } String getTenantId() { - return (String) properties.get("name"); + return tenantId; } /** diff --git a/src/main/java/com/google/firebase/auth/TenantManager.java b/src/main/java/com/google/firebase/auth/TenantManager.java index 9d8f63861..54abbe879 100644 --- a/src/main/java/com/google/firebase/auth/TenantManager.java +++ b/src/main/java/com/google/firebase/auth/TenantManager.java @@ -36,8 +36,7 @@ * This class can be used to perform a variety of tenant-related operations, including creating, * updating, and listing tenants. * - *

TODO(micahstairs): Implement the following methods: getAuthForTenant(), createTenant(), and - * updateTenant(). + *

TODO(micahstairs): Implement getAuthForTenant(). */ public final class TenantManager { @@ -154,6 +153,80 @@ protected ListTenantsPage execute() throws FirebaseAuthException { }; } + /** + * Creates a new tenant with the attributes contained in the specified {@link CreateRequest}. + * + * @param request A non-null {@link CreateRequest} instance. + * @return A {@link Tenant} instance corresponding to the newly created tenant. + * @throws NullPointerException if the provided request is null. + * @throws FirebaseAuthException if an error occurs while creating the tenant. + */ + public Tenant createTenant(@NonNull CreateRequest request) throws FirebaseAuthException { + return createTenantOp(request).call(); + } + + /** + * Similar to {@link #createTenant(CreateRequest)} but performs the operation asynchronously. + * + * @param request A non-null {@link CreateRequest} instance. + * @return An {@code ApiFuture} which will complete successfully with a {@link Tenant} + * instance corresponding to the newly created tenant. If an error occurs while creating the + * tenant, the future throws a {@link FirebaseAuthException}. + * @throws NullPointerException if the provided request is null. + */ + public ApiFuture createTenantAsync(@NonNull CreateRequest request) { + return createTenantOp(request).callAsync(firebaseApp); + } + + /** + * Updates an existing user account with the attributes contained in the specified {@link + * UpdateRequest}. + * + * @param request A non-null {@link UpdateRequest} instance. + * @return A {@link Tenant} instance corresponding to the updated user account. + * @throws NullPointerException if the provided update request is null. + * @throws FirebaseAuthException if an error occurs while updating the user account. + */ + public Tenant updateTenant(@NonNull UpdateRequest request) throws FirebaseAuthException { + return updateTenantOp(request).call(); + } + + /** + * Similar to {@link #updateTenant(UpdateRequest)} but performs the operation asynchronously. + * + * @param request A non-null {@link UpdateRequest} instance. + * @return An {@code ApiFuture} which will complete successfully with a {@link Tenant} + * instance corresponding to the updated user account. If an error occurs while updating the + * user account, the future throws a {@link FirebaseAuthException}. + */ + public ApiFuture updateTenantAsync(@NonNull UpdateRequest request) { + return updateTenantOp(request).callAsync(firebaseApp); + } + + private CallableOperation updateTenantOp( + final UpdateRequest request) { + // TODO(micahstairs): Add a check to make sure the app has not been destroyed yet. + checkNotNull(request, "update request must not be null"); + return new CallableOperation() { + @Override + protected Tenant execute() throws FirebaseAuthException { + return userManager.updateTenant(request); + } + }; + } + + private CallableOperation createTenantOp( + final CreateRequest request) { + // TODO(micahstairs): Add a check to make sure the app has not been destroyed yet. + checkNotNull(request, "create request must not be null"); + return new CallableOperation() { + @Override + protected Tenant execute() throws FirebaseAuthException { + return userManager.createTenant(request); + } + }; + } + /** * Deletes the tenant identified by the specified tenant ID. * diff --git a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java index efc59df22..47227b33c 100644 --- a/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java +++ b/src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java @@ -42,8 +42,6 @@ import com.google.firebase.FirebaseOptions; import com.google.firebase.TestOnlyImplFirebaseTrampolines; import com.google.firebase.auth.FirebaseUserManager.EmailLinkType; -import com.google.firebase.auth.UserRecord.CreateRequest; -import com.google.firebase.auth.UserRecord.UpdateRequest; import com.google.firebase.internal.SdkUtils; import com.google.firebase.testing.MultiRequestMockHttpTransport; import com.google.firebase.testing.TestResponseInterceptor; @@ -63,6 +61,7 @@ public class FirebaseUserManagerTest { + private static final JsonFactory JSON_FACTORY = Utils.getDefaultJsonFactory(); private static final String TEST_TOKEN = "token"; private static final GoogleCredentials credentials = new MockGoogleCredentials(TEST_TOKEN); private static final ActionCodeSettings ACTION_CODE_SETTINGS = ActionCodeSettings.builder() @@ -222,7 +221,8 @@ public void testCreateUser() throws Exception { TestResponseInterceptor interceptor = initializeAppForUserManagement( TestUtils.loadResource("createUser.json"), TestUtils.loadResource("getUser.json")); - UserRecord user = FirebaseAuth.getInstance().createUserAsync(new CreateRequest()).get(); + UserRecord user = + FirebaseAuth.getInstance().createUserAsync(new UserRecord.CreateRequest()).get(); checkUserRecord(user); checkRequestHeaders(interceptor); } @@ -233,7 +233,7 @@ public void testUpdateUser() throws Exception { TestUtils.loadResource("createUser.json"), TestUtils.loadResource("getUser.json")); UserRecord user = FirebaseAuth.getInstance() - .updateUserAsync(new UpdateRequest("testuser")).get(); + .updateUserAsync(new UserRecord.UpdateRequest("testuser")).get(); checkUserRecord(user); checkRequestHeaders(interceptor); } @@ -248,12 +248,9 @@ public void testSetCustomAttributes() throws Exception { 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals("testuser", parsed.get("localId")); - assertEquals(jsonFactory.toString(claims), parsed.get("customAttributes")); + assertEquals(JSON_FACTORY.toString(claims), parsed.get("customAttributes")); } @Test @@ -264,10 +261,7 @@ public void testRevokeRefreshTokens() throws Exception { 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals("testuser", parsed.get("localId")); assertNotNull(parsed.get("validSince")); } @@ -294,14 +288,11 @@ public void testImportUsers() throws Exception { assertEquals(0, result.getFailureCount()); assertTrue(result.getErrors().isEmpty()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - interceptor.getResponse().getRequest().getContent().writeTo(out); - JsonFactory jsonFactory = Utils.getDefaultJsonFactory(); - GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(1, parsed.size()); List> expected = ImmutableList.of( - user1.getProperties(jsonFactory), - user2.getProperties(jsonFactory) + user1.getProperties(JSON_FACTORY), + user2.getProperties(JSON_FACTORY) ); assertEquals(expected, parsed.get("users")); } @@ -334,15 +325,12 @@ public void testImportUsersError() throws Exception { assertEquals(2, error.getIndex()); assertEquals("Another error occurred in user3", error.getReason()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - interceptor.getResponse().getRequest().getContent().writeTo(out); - JsonFactory jsonFactory = Utils.getDefaultJsonFactory(); - GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(1, parsed.size()); List> expected = ImmutableList.of( - user1.getProperties(jsonFactory), - user2.getProperties(jsonFactory), - user3.getProperties(jsonFactory) + user1.getProperties(JSON_FACTORY), + user2.getProperties(JSON_FACTORY), + user3.getProperties(JSON_FACTORY) ); assertEquals(expected, parsed.get("users")); } @@ -372,14 +360,11 @@ protected Map getOptions() { assertEquals(0, result.getFailureCount()); assertTrue(result.getErrors().isEmpty()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - interceptor.getResponse().getRequest().getContent().writeTo(out); - JsonFactory jsonFactory = Utils.getDefaultJsonFactory(); - GenericJson parsed = jsonFactory.fromString(new String(out.toByteArray()), GenericJson.class); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(4, parsed.size()); List> expected = ImmutableList.of( - user1.getProperties(jsonFactory), - user2.getProperties(jsonFactory) + user1.getProperties(JSON_FACTORY), + user2.getProperties(JSON_FACTORY) ); assertEquals(expected, parsed.get("users")); assertEquals("MOCK_HASH", parsed.get("hashAlgorithm")); @@ -437,8 +422,10 @@ public void testImportUsersLargeList() { @Test public void testGetTenant() throws Exception { TestResponseInterceptor interceptor = initializeAppForUserManagement( - TestUtils.loadResource("getTenant.json")); - Tenant tenant = FirebaseAuth.getInstance().getTenantManager().getTenantAsync("TENANT_1").get(); + TestUtils.loadResource("tenant.json")); + + Tenant tenant = FirebaseAuth.getInstance().getTenantManager().getTenant("TENANT_1"); + checkTenant(tenant, "TENANT_1"); checkRequestHeaders(interceptor); checkUrl(interceptor, "GET", TENANTS_BASE_URL + "/TENANT_1"); @@ -450,12 +437,10 @@ public void testGetTenantWithNotFoundError() throws Exception { initializeAppForUserManagementWithStatusCode(404, "{\"error\": {\"message\": \"TENANT_NOT_FOUND\"}}"); try { - FirebaseAuth.getInstance().getTenantManager().getTenantAsync("UNKNOWN").get(); + FirebaseAuth.getInstance().getTenantManager().getTenant("UNKNOWN"); fail("No error thrown for invalid response"); - } catch (ExecutionException e) { - assertThat(e.getCause(), instanceOf(FirebaseAuthException.class)); - FirebaseAuthException authException = (FirebaseAuthException) e.getCause(); - assertEquals(FirebaseUserManager.TENANT_NOT_FOUND_ERROR, authException.getErrorCode()); + } catch (FirebaseAuthException e) { + assertEquals(FirebaseUserManager.TENANT_NOT_FOUND_ERROR, e.getErrorCode()); } checkUrl(interceptor, "GET", TENANTS_BASE_URL + "/UNKNOWN"); } @@ -464,15 +449,16 @@ public void testGetTenantWithNotFoundError() throws Exception { public void testListTenants() throws Exception { final TestResponseInterceptor interceptor = initializeAppForUserManagement( TestUtils.loadResource("listTenants.json")); - ListTenantsPage page = - FirebaseAuth.getInstance().getTenantManager().listTenantsAsync(null, 999).get(); + + ListTenantsPage page = FirebaseAuth.getInstance().getTenantManager().listTenants(null, 999); + ImmutableList tenants = ImmutableList.copyOf(page.getValues()); assertEquals(2, tenants.size()); checkTenant(tenants.get(0), "TENANT_1"); checkTenant(tenants.get(1), "TENANT_2"); assertEquals("", page.getNextPageToken()); checkRequestHeaders(interceptor); - + checkUrl(interceptor, "GET", TENANTS_BASE_URL + ":list"); GenericUrl url = interceptor.getResponse().getRequest().getUrl(); assertEquals(999, url.getFirst("pageSize")); assertNull(url.getFirst("pageToken")); @@ -482,15 +468,16 @@ public void testListTenants() throws Exception { public void testListTenantsWithPageToken() throws Exception { final TestResponseInterceptor interceptor = initializeAppForUserManagement( TestUtils.loadResource("listTenants.json")); - ListTenantsPage page = - FirebaseAuth.getInstance().getTenantManager().listTenantsAsync("token", 999).get(); + + ListTenantsPage page = FirebaseAuth.getInstance().getTenantManager().listTenants("token", 999); + ImmutableList tenants = ImmutableList.copyOf(page.getValues()); assertEquals(2, tenants.size()); checkTenant(tenants.get(0), "TENANT_1"); checkTenant(tenants.get(1), "TENANT_2"); assertEquals("", page.getNextPageToken()); checkRequestHeaders(interceptor); - + checkUrl(interceptor, "GET", TENANTS_BASE_URL + ":list"); GenericUrl url = interceptor.getResponse().getRequest().getUrl(); assertEquals(999, url.getFirst("pageSize")); assertEquals("token", url.getFirst("pageToken")); @@ -499,18 +486,142 @@ public void testListTenantsWithPageToken() throws Exception { @Test public void testListZeroTenants() throws Exception { final TestResponseInterceptor interceptor = initializeAppForUserManagement("{}"); - ListTenantsPage page = - FirebaseAuth.getInstance().getTenantManager().listTenantsAsync(null).get(); + + ListTenantsPage page = FirebaseAuth.getInstance().getTenantManager().listTenants(null); + assertTrue(Iterables.isEmpty(page.getValues())); assertEquals("", page.getNextPageToken()); checkRequestHeaders(interceptor); } + @Test + public void testCreateTenant() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("tenant.json")); + Tenant.CreateRequest request = new Tenant.CreateRequest() + .setDisplayName("DISPLAY_NAME") + .setPasswordSignInAllowed(true) + .setEmailLinkSignInEnabled(false); + + Tenant tenant = FirebaseAuth.getInstance().getTenantManager().createTenant(request); + + checkTenant(tenant, "TENANT_1"); + checkRequestHeaders(interceptor); + checkUrl(interceptor, "POST", TENANTS_BASE_URL); + GenericJson parsed = parseRequestContent(interceptor); + assertEquals("DISPLAY_NAME", parsed.get("displayName")); + assertEquals(true, parsed.get("allowPasswordSignup")); + assertEquals(false, parsed.get("enableEmailLinkSignin")); + } + + @Test + public void testCreateTenantMinimal() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("tenant.json")); + Tenant.CreateRequest request = new Tenant.CreateRequest(); + + Tenant tenant = FirebaseAuth.getInstance().getTenantManager().createTenant(request); + + checkTenant(tenant, "TENANT_1"); + checkRequestHeaders(interceptor); + checkUrl(interceptor, "POST", TENANTS_BASE_URL); + GenericJson parsed = parseRequestContent(interceptor); + assertNull(parsed.get("displayName")); + assertNull(parsed.get("allowPasswordSignup")); + assertNull(parsed.get("enableEmailLinkSignin")); + } + + @Test + public void testCreateTenantError() throws Exception { + TestResponseInterceptor interceptor = + initializeAppForUserManagementWithStatusCode(404, + "{\"error\": {\"message\": \"INTERNAL_ERROR\"}}"); + try { + FirebaseAuth.getInstance().getTenantManager().createTenant(new Tenant.CreateRequest()); + fail("No error thrown for invalid response"); + } catch (FirebaseAuthException e) { + assertEquals(FirebaseUserManager.INTERNAL_ERROR, e.getErrorCode()); + } + checkUrl(interceptor, "POST", TENANTS_BASE_URL); + } + + @Test + public void testUpdateTenant() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("tenant.json")); + Tenant.UpdateRequest request = new Tenant.UpdateRequest("TENANT_1") + .setDisplayName("DISPLAY_NAME") + .setPasswordSignInAllowed(true) + .setEmailLinkSignInEnabled(false); + + Tenant tenant = FirebaseAuth.getInstance().getTenantManager().updateTenant(request); + + checkTenant(tenant, "TENANT_1"); + checkRequestHeaders(interceptor); + checkUrl(interceptor, "PATCH", TENANTS_BASE_URL + "/TENANT_1"); + GenericUrl url = interceptor.getResponse().getRequest().getUrl(); + assertEquals("allowPasswordSignup,displayName,enableEmailLinkSignin", + url.getFirst("updateMask")); + GenericJson parsed = parseRequestContent(interceptor); + assertEquals("DISPLAY_NAME", parsed.get("displayName")); + assertEquals(true, parsed.get("allowPasswordSignup")); + assertEquals(false, parsed.get("enableEmailLinkSignin")); + } + + @Test + public void testUpdateTenantMinimal() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("tenant.json")); + Tenant.UpdateRequest request = + new Tenant.UpdateRequest("TENANT_1").setDisplayName("DISPLAY_NAME"); + + Tenant tenant = FirebaseAuth.getInstance().getTenantManager().updateTenant(request); + + checkTenant(tenant, "TENANT_1"); + checkRequestHeaders(interceptor); + checkUrl(interceptor, "PATCH", TENANTS_BASE_URL + "/TENANT_1"); + GenericUrl url = interceptor.getResponse().getRequest().getUrl(); + assertEquals("displayName", url.getFirst("updateMask")); + GenericJson parsed = parseRequestContent(interceptor); + assertEquals("DISPLAY_NAME", parsed.get("displayName")); + assertNull(parsed.get("allowPasswordSignup")); + assertNull(parsed.get("enableEmailLinkSignin")); + } + + @Test + public void testUpdateTenantNoValues() throws Exception { + TestResponseInterceptor interceptor = initializeAppForUserManagement( + TestUtils.loadResource("tenant.json")); + TenantManager tenantManager = FirebaseAuth.getInstance().getTenantManager(); + try { + tenantManager.updateTenant(new Tenant.UpdateRequest("TENANT_1")); + fail("No error thrown for empty tenant update"); + } catch (IllegalArgumentException e) { + // expected + } + } + + @Test + public void testUpdateTenantError() throws Exception { + TestResponseInterceptor interceptor = + initializeAppForUserManagementWithStatusCode(404, + "{\"error\": {\"message\": \"INTERNAL_ERROR\"}}"); + Tenant.UpdateRequest request = + new Tenant.UpdateRequest("TENANT_1").setDisplayName("DISPLAY_NAME"); + try { + FirebaseAuth.getInstance().getTenantManager().updateTenant(request); + fail("No error thrown for invalid response"); + } catch (FirebaseAuthException e) { + assertEquals(FirebaseUserManager.INTERNAL_ERROR, e.getErrorCode()); + } + checkUrl(interceptor, "PATCH", TENANTS_BASE_URL + "/TENANT_1"); + } + @Test public void testDeleteTenant() throws Exception { TestResponseInterceptor interceptor = initializeAppForUserManagement("{}"); - FirebaseAuth.getInstance().getTenantManager().deleteTenantAsync("TENANT_1").get(); + FirebaseAuth.getInstance().getTenantManager().deleteTenant("TENANT_1"); checkRequestHeaders(interceptor); checkUrl(interceptor, "DELETE", TENANTS_BASE_URL + "/TENANT_1"); @@ -522,12 +633,10 @@ public void testDeleteTenantWithNotFoundError() throws Exception { initializeAppForUserManagementWithStatusCode(404, "{\"error\": {\"message\": \"TENANT_NOT_FOUND\"}}"); try { - FirebaseAuth.getInstance().getTenantManager().deleteTenantAsync("UNKNOWN").get(); + FirebaseAuth.getInstance().getTenantManager().deleteTenant("UNKNOWN"); fail("No error thrown for invalid response"); - } catch (ExecutionException e) { - assertThat(e.getCause(), instanceOf(FirebaseAuthException.class)); - FirebaseAuthException authException = (FirebaseAuthException) e.getCause(); - assertEquals(FirebaseUserManager.TENANT_NOT_FOUND_ERROR, authException.getErrorCode()); + } catch (FirebaseAuthException e) { + assertEquals(FirebaseUserManager.TENANT_NOT_FOUND_ERROR, e.getErrorCode()); } checkUrl(interceptor, "DELETE", TENANTS_BASE_URL + "/UNKNOWN"); } @@ -543,10 +652,7 @@ public void testCreateSessionCookie() throws Exception { assertEquals("MockCookieString", cookie); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(2, parsed.size()); assertEquals("testToken", parsed.get("idToken")); assertEquals(new BigDecimal(3600), parsed.get("validDuration")); @@ -628,13 +734,13 @@ public void call(FirebaseAuth auth) throws Exception { .add(new UserManagerOp() { @Override public void call(FirebaseAuth auth) throws Exception { - auth.createUserAsync(new CreateRequest()).get(); + auth.createUserAsync(new UserRecord.CreateRequest()).get(); } }) .add(new UserManagerOp() { @Override public void call(FirebaseAuth auth) throws Exception { - auth.updateUserAsync(new UpdateRequest("test")).get(); + auth.updateUserAsync(new UserRecord.UpdateRequest("test")).get(); } }) .add(new UserManagerOp() { @@ -752,13 +858,13 @@ public void testTimeout() throws Exception { @Test public void testUserBuilder() { - Map map = new CreateRequest().getProperties(); + Map map = new UserRecord.CreateRequest().getProperties(); assertTrue(map.isEmpty()); } @Test public void testUserBuilderWithParams() { - Map map = new CreateRequest() + Map map = new UserRecord.CreateRequest() .setUid("TestUid") .setDisplayName("Display Name") .setPhotoUrl("http://test.com/example.png") @@ -779,7 +885,7 @@ public void testUserBuilderWithParams() { @Test public void testInvalidUid() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setUid(null); fail("No error thrown for null uid"); @@ -804,7 +910,7 @@ public void testInvalidUid() { @Test public void testInvalidDisplayName() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setDisplayName(null); fail("No error thrown for null display name"); @@ -815,7 +921,7 @@ public void testInvalidDisplayName() { @Test public void testInvalidPhotoUrl() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setPhotoUrl(null); fail("No error thrown for null photo url"); @@ -840,7 +946,7 @@ public void testInvalidPhotoUrl() { @Test public void testInvalidEmail() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setEmail(null); fail("No error thrown for null email"); @@ -865,7 +971,7 @@ public void testInvalidEmail() { @Test public void testInvalidPhoneNumber() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setPhoneNumber(null); fail("No error thrown for null phone number"); @@ -890,7 +996,7 @@ public void testInvalidPhoneNumber() { @Test public void testInvalidPassword() { - CreateRequest user = new CreateRequest(); + UserRecord.CreateRequest user = new UserRecord.CreateRequest(); try { user.setPassword(null); fail("No error thrown for null password"); @@ -908,7 +1014,7 @@ public void testInvalidPassword() { @Test public void testUserUpdater() throws IOException { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); Map claims = ImmutableMap.of("admin", true, "package", "gold"); Map map = update .setDisplayName("Display Name") @@ -918,7 +1024,7 @@ public void testUserUpdater() throws IOException { .setEmailVerified(true) .setPassword("secret") .setCustomClaims(claims) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(8, map.size()); assertEquals(update.getUid(), map.get("localId")); assertEquals("Display Name", map.get("displayName")); @@ -927,12 +1033,12 @@ public void testUserUpdater() throws IOException { assertEquals("+1234567890", map.get("phoneNumber")); assertTrue((Boolean) map.get("emailVerified")); assertEquals("secret", map.get("password")); - assertEquals(Utils.getDefaultJsonFactory().toString(claims), map.get("customAttributes")); + assertEquals(JSON_FACTORY.toString(claims), map.get("customAttributes")); } @Test public void testNullJsonFactory() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); Map claims = ImmutableMap.of("admin", true, "package", "gold"); update.setCustomClaims(claims); try { @@ -945,10 +1051,10 @@ public void testNullJsonFactory() { @Test public void testNullCustomClaims() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); Map map = update .setCustomClaims(null) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(2, map.size()); assertEquals(update.getUid(), map.get("localId")); assertEquals("{}", map.get("customAttributes")); @@ -956,10 +1062,10 @@ public void testNullCustomClaims() { @Test public void testEmptyCustomClaims() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); Map map = update .setCustomClaims(ImmutableMap.of()) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(2, map.size()); assertEquals(update.getUid(), map.get("localId")); assertEquals("{}", map.get("customAttributes")); @@ -967,31 +1073,31 @@ public void testEmptyCustomClaims() { @Test public void testDeleteDisplayName() { - Map map = new UpdateRequest("test") + Map map = new UserRecord.UpdateRequest("test") .setDisplayName(null) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(ImmutableList.of("DISPLAY_NAME"), map.get("deleteAttribute")); } @Test public void testDeletePhotoUrl() { - Map map = new UpdateRequest("test") + Map map = new UserRecord.UpdateRequest("test") .setPhotoUrl(null) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(ImmutableList.of("PHOTO_URL"), map.get("deleteAttribute")); } @Test public void testDeletePhoneNumber() { - Map map = new UpdateRequest("test") + Map map = new UserRecord.UpdateRequest("test") .setPhoneNumber(null) - .getProperties(Utils.getDefaultJsonFactory()); + .getProperties(JSON_FACTORY); assertEquals(ImmutableList.of("phone"), map.get("deleteProvider")); } @Test public void testInvalidUpdatePhotoUrl() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); try { update.setPhotoUrl(""); fail("No error thrown for invalid photo url"); @@ -1009,7 +1115,7 @@ public void testInvalidUpdatePhotoUrl() { @Test public void testInvalidUpdateEmail() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); try { update.setEmail(null); fail("No error thrown for null email"); @@ -1034,7 +1140,7 @@ public void testInvalidUpdateEmail() { @Test public void testInvalidUpdatePhoneNumber() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); try { update.setPhoneNumber(""); @@ -1053,7 +1159,7 @@ public void testInvalidUpdatePhoneNumber() { @Test public void testInvalidUpdatePassword() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); try { update.setPassword(null); fail("No error thrown for null password"); @@ -1071,7 +1177,7 @@ public void testInvalidUpdatePassword() { @Test public void testInvalidCustomClaims() { - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); for (String claim : FirebaseUserManager.RESERVED_CLAIMS) { try { update.setCustomClaims(ImmutableMap.of(claim, "value")); @@ -1088,10 +1194,10 @@ public void testLargeCustomClaims() { for (int i = 0; i < 1001; i++) { builder.append("a"); } - UpdateRequest update = new UpdateRequest("test"); + UserRecord.UpdateRequest update = new UserRecord.UpdateRequest("test"); update.setCustomClaims(ImmutableMap.of("key", builder.toString())); try { - update.getProperties(Utils.getDefaultJsonFactory()); + update.getProperties(JSON_FACTORY); fail("No error thrown for large claims payload"); } catch (Exception ignore) { // expected @@ -1123,10 +1229,7 @@ public void testGeneratePasswordResetLinkWithSettings() throws Exception { assertEquals("https://mock-oob-link.for.auth.tests", link); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(3 + ACTION_CODE_SETTINGS_MAP.size(), parsed.size()); assertEquals("test@example.com", parsed.get("email")); assertEquals("PASSWORD_RESET", parsed.get("requestType")); @@ -1145,10 +1248,7 @@ public void testGeneratePasswordResetLink() throws Exception { assertEquals("https://mock-oob-link.for.auth.tests", link); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(3, parsed.size()); assertEquals("test@example.com", parsed.get("email")); assertEquals("PASSWORD_RESET", parsed.get("requestType")); @@ -1180,10 +1280,7 @@ public void testGenerateEmailVerificationLinkWithSettings() throws Exception { assertEquals("https://mock-oob-link.for.auth.tests", link); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(3 + ACTION_CODE_SETTINGS_MAP.size(), parsed.size()); assertEquals("test@example.com", parsed.get("email")); assertEquals("VERIFY_EMAIL", parsed.get("requestType")); @@ -1202,10 +1299,7 @@ public void testGenerateEmailVerificationLink() throws Exception { assertEquals("https://mock-oob-link.for.auth.tests", link); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(3, parsed.size()); assertEquals("test@example.com", parsed.get("email")); assertEquals("VERIFY_EMAIL", parsed.get("requestType")); @@ -1250,10 +1344,7 @@ public void testGenerateSignInWithEmailLinkWithSettings() throws Exception { assertEquals("https://mock-oob-link.for.auth.tests", link); 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); + GenericJson parsed = parseRequestContent(interceptor); assertEquals(3 + ACTION_CODE_SETTINGS_MAP.size(), parsed.size()); assertEquals("test@example.com", parsed.get("email")); assertEquals("EMAIL_SIGNIN", parsed.get("requestType")); @@ -1320,6 +1411,13 @@ private static TestResponseInterceptor initializeAppForUserManagement(String... return interceptor; } + private static GenericJson parseRequestContent(TestResponseInterceptor interceptor) + throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + interceptor.getResponse().getRequest().getContent().writeTo(out); + return JSON_FACTORY.fromString(new String(out.toByteArray()), GenericJson.class); + } + private static void checkUserRecord(UserRecord userRecord) { assertEquals("testuser", userRecord.getUid()); assertEquals("testuser@example.com", userRecord.getEmail()); @@ -1372,7 +1470,7 @@ private static void checkRequestHeaders(TestResponseInterceptor interceptor) { private static void checkUrl(TestResponseInterceptor interceptor, String method, String url) { HttpRequest request = interceptor.getResponse().getRequest(); assertEquals(method, request.getRequestMethod()); - assertEquals(url, request.getUrl().toString()); + assertEquals(url, request.getUrl().toString().split("\\?")[0]); } private interface UserManagerOp { diff --git a/src/test/java/com/google/firebase/auth/TenantTest.java b/src/test/java/com/google/firebase/auth/TenantTest.java index 22209e8ad..1fc796dd1 100644 --- a/src/test/java/com/google/firebase/auth/TenantTest.java +++ b/src/test/java/com/google/firebase/auth/TenantTest.java @@ -57,9 +57,7 @@ public void testUpdateRequestFromTenant() throws IOException { Tenant.UpdateRequest updateRequest = tenant.updateRequest(); assertEquals("TENANT_ID", updateRequest.getTenantId()); - Map properties = updateRequest.getProperties(); - assertEquals(properties.size(), 1); - assertEquals("TENANT_ID", (String) properties.get("name")); + assertTrue(updateRequest.getProperties().isEmpty()); } @Test @@ -72,8 +70,7 @@ public void testUpdateRequestFromTenantId() throws IOException { assertEquals("TENANT_ID", updateRequest.getTenantId()); Map properties = updateRequest.getProperties(); - assertEquals(properties.size(), 4); - assertEquals("TENANT_ID", (String) properties.get("name")); + assertEquals(properties.size(), 3); assertEquals("DISPLAY_NAME", (String) properties.get("displayName")); assertFalse((boolean) properties.get("allowPasswordSignup")); assertTrue((boolean) properties.get("enableEmailLinkSignin")); diff --git a/src/test/resources/getTenant.json b/src/test/resources/tenant.json similarity index 100% rename from src/test/resources/getTenant.json rename to src/test/resources/tenant.json