Skip to content

Add integration tests for TenantManager operations. #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/main/java/com/google/firebase/auth/FirebaseUserManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,15 @@ void deleteTenant(String tenantId) throws FirebaseAuthException {

ListTenantsResponse listTenants(int maxResults, String pageToken)
throws FirebaseAuthException {
ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
.put("pageSize", maxResults);
ImmutableMap.Builder<String, Object> builder =
ImmutableMap.<String, Object>builder().put("pageSize", maxResults);
if (pageToken != null) {
checkArgument(!pageToken.equals(
ListTenantsPage.END_OF_LIST), "invalid end of list page token");
builder.put("pageToken", pageToken);
}

GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants:list");
GenericUrl url = new GenericUrl(tenantMgtBaseUrl + "/tenants");
url.putAll(builder.build());
ListTenantsResponse response = sendRequest("GET", url, null, ListTenantsResponse.class);
if (response == null) {
Expand Down Expand Up @@ -329,9 +329,13 @@ private <T> T sendRequest(
HttpResponse response = null;
try {
HttpContent httpContent = content != null ? new JsonHttpContent(jsonFactory, content) : null;
HttpRequest request = requestFactory.buildRequest(method, url, httpContent);
HttpRequest request =
requestFactory.buildRequest(method.equals("PATCH") ? "POST" : method, url, httpContent);
request.setParser(new JsonObjectParser(jsonFactory));
request.getHeaders().set(CLIENT_VERSION_HEADER, clientVersion);
if (method.equals("PATCH")) {
request.getHeaders().set("X-HTTP-Method-Override", "PATCH");
}
request.setResponseInterceptor(interceptor);
response = request.execute();
return response.parseAs(clazz);
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/google/firebase/auth/Tenant.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@
*/
public final class Tenant {

@Key("name")
// Lazily initialized from 'resourceName'.
private String tenantId;

@Key("name")
private String resourceName;

@Key("displayName")
private String displayName;

Expand All @@ -44,6 +47,9 @@ public final class Tenant {
private boolean emailLinkSignInEnabled;

public String getTenantId() {
if (tenantId == null) {
tenantId = resourceName.substring(resourceName.lastIndexOf("/") + 1);
}
return tenantId;
}

Expand Down
25 changes: 13 additions & 12 deletions src/main/java/com/google/firebase/auth/TenantManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ public ApiFuture<Tenant> createTenantAsync(@NonNull CreateRequest request) {
return createTenantOp(request).callAsync(firebaseApp);
}

private CallableOperation<Tenant, FirebaseAuthException> 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<Tenant, FirebaseAuthException>() {
@Override
protected Tenant execute() throws FirebaseAuthException {
return userManager.createTenant(request);
}
};
}


/**
* Updates an existing user account with the attributes contained in the specified {@link
* UpdateRequest}.
Expand Down Expand Up @@ -215,18 +228,6 @@ protected Tenant execute() throws FirebaseAuthException {
};
}

private CallableOperation<Tenant, FirebaseAuthException> 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<Tenant, FirebaseAuthException>() {
@Override
protected Tenant execute() throws FirebaseAuthException {
return userManager.createTenant(request);
}
};
}

/**
* Deletes the tenant identified by the specified tenant ID.
*
Expand Down
145 changes: 127 additions & 18 deletions src/test/java/com/google/firebase/auth/FirebaseAuthIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.ImplFirebaseTrampolines;
import com.google.firebase.auth.UserRecord.CreateRequest;
import com.google.firebase.auth.UserRecord.UpdateRequest;
import com.google.firebase.auth.hash.Scrypt;
import com.google.firebase.testing.IntegrationTestUtils;
import java.io.IOException;
Expand Down Expand Up @@ -116,7 +114,7 @@ public void testGetNonExistingUserByEmail() throws Exception {
@Test
public void testUpdateNonExistingUser() throws Exception {
try {
auth.updateUserAsync(new UpdateRequest("non.existing")).get();
auth.updateUserAsync(new UserRecord.UpdateRequest("non.existing")).get();
fail("No error thrown for non existing uid");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof FirebaseAuthException);
Expand All @@ -141,7 +139,7 @@ public void testDeleteNonExistingUser() throws Exception {
public void testCreateUserWithParams() throws Exception {
RandomUser randomUser = RandomUser.create();
String phone = randomPhoneNumber();
CreateRequest user = new CreateRequest()
UserRecord.CreateRequest user = new UserRecord.CreateRequest()
.setUid(randomUser.uid)
.setEmail(randomUser.email)
.setPhoneNumber(phone)
Expand All @@ -168,7 +166,7 @@ public void testCreateUserWithParams() throws Exception {
assertTrue(providers.contains("password"));
assertTrue(providers.contains("phone"));

checkRecreate(randomUser.uid);
checkRecreateUser(randomUser.uid);
} finally {
auth.deleteUserAsync(userRecord.getUid()).get();
}
Expand All @@ -177,7 +175,7 @@ public void testCreateUserWithParams() throws Exception {
@Test
public void testUserLifecycle() throws Exception {
// Create user
UserRecord userRecord = auth.createUserAsync(new CreateRequest()).get();
UserRecord userRecord = auth.createUserAsync(new UserRecord.CreateRequest()).get();
String uid = userRecord.getUid();

// Get user
Expand All @@ -197,7 +195,7 @@ public void testUserLifecycle() throws Exception {
// Update user
RandomUser randomUser = RandomUser.create();
String phone = randomPhoneNumber();
UpdateRequest request = userRecord.updateRequest()
UserRecord.UpdateRequest request = userRecord.updateRequest()
.setDisplayName("Updated Name")
.setEmail(randomUser.email)
.setPhoneNumber(phone)
Expand Down Expand Up @@ -240,7 +238,7 @@ public void testUserLifecycle() throws Exception {
auth.deleteUserAsync(userRecord.getUid()).get();
try {
auth.getUserAsync(userRecord.getUid()).get();
fail("No error thrown for deleted user");
fail("No error thrown for getting a deleted user");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof FirebaseAuthException);
assertEquals(FirebaseUserManager.USER_NOT_FOUND_ERROR,
Expand All @@ -253,9 +251,11 @@ public void testListUsers() throws Exception {
final List<String> uids = new ArrayList<>();

try {
uids.add(auth.createUserAsync(new CreateRequest().setPassword("password")).get().getUid());
uids.add(auth.createUserAsync(new CreateRequest().setPassword("password")).get().getUid());
uids.add(auth.createUserAsync(new CreateRequest().setPassword("password")).get().getUid());
for (int i = 0; i < 3; i++) {
UserRecord.CreateRequest createRequest =
new UserRecord.CreateRequest().setPassword("password");
uids.add(auth.createUserAsync(createRequest).get().getUid());
}

// Test list by batches
final AtomicInteger collected = new AtomicInteger(0);
Expand Down Expand Up @@ -320,9 +320,118 @@ public void onSuccess(ListUsersPage result) {
}
}

@Test
public void testTenantLifecycle() throws Exception {
TenantManager tenantManager = auth.getTenantManager();

// Create tenant
Tenant.CreateRequest createRequest = new Tenant.CreateRequest().setDisplayName("DisplayName");
Tenant tenant = tenantManager.createTenantAsync(createRequest).get();
String tenantId = tenant.getTenantId();

// Get tenant
tenant = tenantManager.getTenantAsync(tenantId).get();
assertEquals(tenantId, tenant.getTenantId());
assertEquals("DisplayName", tenant.getDisplayName());
assertFalse(tenant.isPasswordSignInAllowed());
assertFalse(tenant.isEmailLinkSignInEnabled());

// Update tenant
Tenant.UpdateRequest updateRequest = tenant.updateRequest()
.setDisplayName("UpdatedName")
.setPasswordSignInAllowed(true)
.setEmailLinkSignInEnabled(true);
tenant = tenantManager.updateTenantAsync(updateRequest).get();
assertEquals(tenantId, tenant.getTenantId());
assertEquals("UpdatedName", tenant.getDisplayName());
assertTrue(tenant.isPasswordSignInAllowed());
assertTrue(tenant.isEmailLinkSignInEnabled());

// Delete tenant
tenantManager.deleteTenantAsync(tenant.getTenantId()).get();
try {
tenantManager.getTenantAsync(tenant.getTenantId()).get();
fail("No error thrown for getting a deleted tenant");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof FirebaseAuthException);
assertEquals(FirebaseUserManager.TENANT_NOT_FOUND_ERROR,
((FirebaseAuthException) e.getCause()).getErrorCode());
}
}

@Test
public void testListTenants() throws Exception {
TenantManager tenantManager = auth.getTenantManager();
final List<String> tenantIds = new ArrayList<>();

try {
for (int i = 0; i < 3; i++) {
Tenant.CreateRequest createRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName" + i);
tenantIds.add(tenantManager.createTenantAsync(createRequest).get().getTenantId());
}

// Test list by batches
final AtomicInteger collected = new AtomicInteger(0);
ListTenantsPage page = tenantManager.listTenantsAsync(null).get();
while (page != null) {
for (Tenant tenant : page.getValues()) {
if (tenantIds.contains(tenant.getTenantId())) {
collected.incrementAndGet();
assertNotNull(tenant.getDisplayName());
}
}
page = page.getNextPage();
}
assertEquals(tenantIds.size(), collected.get());

// Test iterate all
collected.set(0);
page = tenantManager.listTenantsAsync(null).get();
for (Tenant tenant : page.iterateAll()) {
if (tenantIds.contains(tenant.getTenantId())) {
collected.incrementAndGet();
assertNotNull(tenant.getDisplayName());
}
}
assertEquals(tenantIds.size(), collected.get());

// Test iterate async
collected.set(0);
final Semaphore semaphore = new Semaphore(0);
final AtomicReference<Throwable> error = new AtomicReference<>();
ApiFuture<ListTenantsPage> pageFuture = tenantManager.listTenantsAsync(null);
ApiFutures.addCallback(pageFuture, new ApiFutureCallback<ListTenantsPage>() {
@Override
public void onFailure(Throwable t) {
error.set(t);
semaphore.release();
}

@Override
public void onSuccess(ListTenantsPage result) {
for (Tenant tenant : result.iterateAll()) {
if (tenantIds.contains(tenant.getTenantId())) {
collected.incrementAndGet();
assertNotNull(tenant.getDisplayName());
}
}
semaphore.release();
}
}, MoreExecutors.directExecutor());
semaphore.acquire();
assertEquals(tenantIds.size(), collected.get());
assertNull(error.get());
} finally {
for (String tenantId : tenantIds) {
tenantManager.deleteTenantAsync(tenantId).get();
}
}
}

@Test
public void testCustomClaims() throws Exception {
UserRecord userRecord = auth.createUserAsync(new CreateRequest()).get();
UserRecord userRecord = auth.createUserAsync(new UserRecord.CreateRequest()).get();
String uid = userRecord.getUid();

try {
Expand Down Expand Up @@ -413,7 +522,7 @@ public void testVerifyIdToken() throws Exception {
}
idToken = signInWithCustomToken(customToken);
decoded = auth.verifyIdTokenAsync(idToken, true).get();
assertEquals("user2", decoded.getUid());
assertEquals("user2", decoded.getUid());
auth.deleteUserAsync("user2");
}

Expand Down Expand Up @@ -524,7 +633,7 @@ public void testImportUsersWithPassword() throws Exception {
@Test
public void testGeneratePasswordResetLink() throws Exception {
RandomUser user = RandomUser.create();
auth.createUser(new CreateRequest()
auth.createUser(new UserRecord.CreateRequest()
.setUid(user.uid)
.setEmail(user.email)
.setEmailVerified(false)
Expand All @@ -549,7 +658,7 @@ public void testGeneratePasswordResetLink() throws Exception {
@Test
public void testGenerateEmailVerificationResetLink() throws Exception {
RandomUser user = RandomUser.create();
auth.createUser(new CreateRequest()
auth.createUser(new UserRecord.CreateRequest()
.setUid(user.uid)
.setEmail(user.email)
.setEmailVerified(false)
Expand All @@ -572,7 +681,7 @@ public void testGenerateEmailVerificationResetLink() throws Exception {
@Test
public void testGenerateSignInWithEmailLink() throws Exception {
RandomUser user = RandomUser.create();
auth.createUser(new CreateRequest()
auth.createUser(new UserRecord.CreateRequest()
.setUid(user.uid)
.setEmail(user.email)
.setEmailVerified(false)
Expand Down Expand Up @@ -686,9 +795,9 @@ private String signInWithEmailLink(
}
}

private void checkRecreate(String uid) throws Exception {
private void checkRecreateUser(String uid) throws Exception {
try {
auth.createUserAsync(new CreateRequest().setUid(uid)).get();
auth.createUserAsync(new UserRecord.CreateRequest().setUid(uid)).get();
fail("No error thrown for creating user with existing ID");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof FirebaseAuthException);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ public void testListTenants() throws Exception {
checkTenant(tenants.get(1), "TENANT_2");
assertEquals("", page.getNextPageToken());
checkRequestHeaders(interceptor);
checkUrl(interceptor, "GET", TENANTS_BASE_URL + ":list");
checkUrl(interceptor, "GET", TENANTS_BASE_URL);
GenericUrl url = interceptor.getResponse().getRequest().getUrl();
assertEquals(999, url.getFirst("pageSize"));
assertNull(url.getFirst("pageToken"));
Expand All @@ -477,7 +477,7 @@ public void testListTenantsWithPageToken() throws Exception {
checkTenant(tenants.get(1), "TENANT_2");
assertEquals("", page.getNextPageToken());
checkRequestHeaders(interceptor);
checkUrl(interceptor, "GET", TENANTS_BASE_URL + ":list");
checkUrl(interceptor, "GET", TENANTS_BASE_URL);
GenericUrl url = interceptor.getResponse().getRequest().getUrl();
assertEquals(999, url.getFirst("pageSize"));
assertEquals("token", url.getFirst("pageToken"));
Expand Down Expand Up @@ -1469,7 +1469,13 @@ 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());
if (method.equals("PATCH")) {
assertEquals("PATCH",
request.getHeaders().getFirstHeaderStringValue("X-HTTP-Method-Override"));
assertEquals("POST", request.getRequestMethod());
} else {
assertEquals(method, request.getRequestMethod());
}
assertEquals(url, request.getUrl().toString().split("\\?")[0]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/google/firebase/auth/TenantTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class TenantTest {

private static final String TENANT_JSON_STRING =
"{"
+ "\"name\":\"TENANT_ID\","
+ "\"name\":\"projects/project-id/resource/TENANT_ID\","
+ "\"displayName\":\"DISPLAY_NAME\","
+ "\"allowPasswordSignup\":true,"
+ "\"enableEmailLinkSignin\":false"
Expand Down