package org.robolectric.shadows;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorDescription;
import android.accounts.AuthenticatorException;
import android.accounts.OnAccountsUpdateListener;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.TestRunners;
import org.robolectric.annotation.Config;
import org.robolectric.util.Scheduler;
import java.io.IOException;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.robolectric.Shadows.shadowOf;
@RunWith(TestRunners.MultiApiSelfTest.class)
public class ShadowAccountManagerTest {
private AccountManager am;
private Scheduler scheduler;
private Activity activity;
@Before
public void setUp() throws Exception {
am = AccountManager.get(RuntimeEnvironment.application);
scheduler = Robolectric.getForegroundThreadScheduler();
activity = new Activity();
}
@Test
public void testGet() {
assertThat(am).isNotNull();
assertThat(am).isSameAs(AccountManager.get(RuntimeEnvironment.application));
AccountManager activityAM = AccountManager.get(RuntimeEnvironment.application);
assertThat(activityAM).isNotNull();
assertThat(activityAM).isSameAs(am);
}
@Test
public void testGetAccounts() {
assertThat(am.getAccounts()).isNotNull();
assertThat(am.getAccounts().length).isEqualTo(0);
Account a1 = new Account("name_a", "type_a");
shadowOf(am).addAccount(a1);
assertThat(am.getAccounts()).isNotNull();
assertThat(am.getAccounts().length).isEqualTo(1);
assertThat(am.getAccounts()[0]).isSameAs(a1);
Account a2 = new Account("name_b", "type_b");
shadowOf(am).addAccount(a2);
assertThat(am.getAccounts()).isNotNull();
assertThat(am.getAccounts().length).isEqualTo(2);
assertThat(am.getAccounts()[1]).isSameAs(a2);
}
@Test
public void getAccountsByType_nullTypeReturnsAllAccounts() {
shadowOf(am).addAccount(new Account("name_1", "type_1"));
shadowOf(am).addAccount(new Account("name_2", "type_2"));
shadowOf(am).addAccount(new Account("name_3", "type_3"));
assertThat(am.getAccountsByType(null)).containsExactly(am.getAccounts());
}
@Test
public void testGetAccountsByType() {
assertThat(am.getAccountsByType("name_a")).isNotNull();
assertThat(am.getAccounts().length).isEqualTo(0);
Account a1 = new Account("name_a", "type_a");
shadowOf(am).addAccount(a1);
Account[] accounts = am.getAccountsByType("type_a");
assertThat(accounts).isNotNull();
assertThat(accounts.length).isEqualTo(1);
assertThat(accounts[0]).isSameAs(a1);
Account a2 = new Account("name_b", "type_b");
shadowOf(am).addAccount(a2);
accounts = am.getAccountsByType("type_a");
assertThat(accounts).isNotNull();
assertThat(accounts.length).isEqualTo(1);
assertThat(accounts[0]).isSameAs(a1);
Account a3 = new Account("name_c", "type_a");
shadowOf(am).addAccount(a3);
accounts = am.getAccountsByType("type_a");
assertThat(accounts).isNotNull();
assertThat(accounts.length).isEqualTo(2);
assertThat(accounts[0]).isSameAs(a1);
assertThat(accounts[1]).isSameAs(a3);
}
@Test
public void addAuthToken() {
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
am.setAuthToken(account, "token_type_1", "token1");
am.setAuthToken(account, "token_type_2", "token2");
assertThat(am.peekAuthToken(account, "token_type_1")).isEqualTo("token1");
assertThat(am.peekAuthToken(account, "token_type_2")).isEqualTo("token2");
}
@Test
public void setAuthToken_shouldNotAddTokenIfAccountNotPresent() {
Account account = new Account("name", "type");
am.setAuthToken(account, "token_type_1", "token1");
assertThat(am.peekAuthToken(account, "token_type_1")).isNull();
}
@Test
public void testAddAccountExplicitly_noPasswordNoExtras() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
assertThat(am.getAccountsByType("type").length).isEqualTo(1);
assertThat(am.getAccountsByType("type")[0].name).isEqualTo("name");
boolean accountAddedTwice = am.addAccountExplicitly(account, null, null);
assertThat(accountAddedTwice).isFalse();
account = new Account("another_name", "type");
accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
assertThat(am.getAccountsByType("type").length).isEqualTo(2);
assertThat(am.getAccountsByType("type")[0].name).isEqualTo("name");
assertThat(am.getAccountsByType("type")[1].name).isEqualTo("another_name");
assertThat(am.getPassword(account)).isNull();
try {
am.addAccountExplicitly(null, null, null);
fail("An illegal argument exception should have been thrown when trying to add a null account");
} catch (IllegalArgumentException iae) {
// NOP
}
}
@Test
public void testAddAccountExplicitly_withPassword() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, "passwd", null);
assertThat(accountAdded).isTrue();
assertThat(am.getPassword(account)).isEqualTo("passwd");
}
@Test
public void testAddAccountExplicitly_withExtras() {
Account account = new Account("name", "type");
Bundle extras = new Bundle();
extras.putString("key123", "value123");
boolean accountAdded = am.addAccountExplicitly(account, null, extras);
assertThat(accountAdded).isTrue();
assertThat(am.getUserData(account, "key123")).isEqualTo("value123");
assertThat(am.getUserData(account, "key456")).isNull();
}
@Test
public void testGetSetUserData_addToInitiallyEmptyExtras() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
am.setUserData(account, "key123", "value123");
assertThat(am.getUserData(account, "key123")).isEqualTo("value123");
}
@Test
public void testGetSetUserData_overwrite() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
am.setUserData(account, "key123", "value123");
assertThat(am.getUserData(account, "key123")).isEqualTo("value123");
am.setUserData(account, "key123", "value456");
assertThat(am.getUserData(account, "key123")).isEqualTo("value456");
}
@Test
public void testGetSetUserData_remove() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
am.setUserData(account, "key123", "value123");
assertThat(am.getUserData(account, "key123")).isEqualTo("value123");
am.setUserData(account, "key123", null);
assertThat(am.getUserData(account, "key123")).isNull();
}
@Test
public void testGetSetPassword_setInAccountInitiallyWithNoPassword() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, null, null);
assertThat(accountAdded).isTrue();
assertThat(am.getPassword(account)).isNull();
am.setPassword(account, "passwd");
assertThat(am.getPassword(account)).isEqualTo("passwd");
}
@Test
public void testGetSetPassword_overwrite() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, "passwd1", null);
assertThat(accountAdded).isTrue();
assertThat(am.getPassword(account)).isEqualTo("passwd1");
am.setPassword(account, "passwd2");
assertThat(am.getPassword(account)).isEqualTo("passwd2");
}
@Test
public void testGetSetPassword_remove() {
Account account = new Account("name", "type");
boolean accountAdded = am.addAccountExplicitly(account, "passwd1", null);
assertThat(accountAdded).isTrue();
assertThat(am.getPassword(account)).isEqualTo("passwd1");
am.setPassword(account, null);
assertThat(am.getPassword(account)).isNull();
}
@Test
public void testBlockingGetAuthToken() throws AuthenticatorException, OperationCanceledException, IOException {
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
am.setAuthToken(account, "token_type_1", "token1");
am.setAuthToken(account, "token_type_2", "token2");
assertThat(am.blockingGetAuthToken(account, "token_type_1", false)).isEqualTo("token1");
assertThat(am.blockingGetAuthToken(account, "token_type_2", false)).isEqualTo("token2");
try {
am.blockingGetAuthToken(null, "token_type_1", false);
fail("blockingGetAuthToken() should throw an illegal argument exception if the account is null");
} catch (IllegalArgumentException iae) {
// Expected
}
try {
am.blockingGetAuthToken(account, null, false);
fail("blockingGetAuthToken() should throw an illegal argument exception if the auth token type is null");
} catch (IllegalArgumentException iae) {
// Expected
}
Account account1 = new Account("unknown", "type");
assertThat(am.blockingGetAuthToken(account1, "token_type_1", false)).isNull();
}
@Test
public void removeAccount_throwsIllegalArgumentException_whenPassedNullAccount() {
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
try {
am.removeAccount(null, null, null);
fail("removeAccount() should throw an illegal argument exception if the account is null");
} catch (IllegalArgumentException iae) {
// Expected
}
}
@Test
public void removeAccount_doesNotRemoveAccountOfDifferentName() throws Exception {
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
Account wrongAccount = new Account("wrong_name", "type");
AccountManagerFuture<Boolean> future = am.removeAccount(wrongAccount, null, null);
assertThat(future.getResult()).isFalse();
assertThat(am.getAccountsByType("type")).isNotEmpty();
}
@Test
public void removeAccount_does() throws Exception {
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
TestAccountManagerCallback<Boolean> testAccountManagerCallback = new TestAccountManagerCallback<>();
AccountManagerFuture<Boolean> future = am.removeAccount(account, testAccountManagerCallback, null);
assertThat(future.getResult()).isTrue();
assertThat(am.getAccountsByType("type")).isEmpty();
assertThat(testAccountManagerCallback.accountManagerFuture).isNotNull();
}
private static class TestOnAccountsUpdateListener implements OnAccountsUpdateListener {
private int invocationCount = 0;
@Override
public void onAccountsUpdated(Account[] accounts) {
invocationCount++;
}
public int getInvocationCount() {
return invocationCount;
}
}
@Test
public void testAccountsUpdateListener() {
TestOnAccountsUpdateListener listener = new TestOnAccountsUpdateListener();
am.addOnAccountsUpdatedListener(listener, null, false);
assertThat(listener.getInvocationCount()).isEqualTo(0);
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
assertThat(listener.getInvocationCount()).isEqualTo(1);
}
@Test
public void testAccountsUpdateListener_duplicate() {
TestOnAccountsUpdateListener listener = new TestOnAccountsUpdateListener();
am.addOnAccountsUpdatedListener(listener, null, false);
am.addOnAccountsUpdatedListener(listener, null, false);
assertThat(listener.getInvocationCount()).isEqualTo(0);
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
assertThat(listener.getInvocationCount()).isEqualTo(1);
}
@Test
public void testAccountsUpdateListener_updateImmediately() {
TestOnAccountsUpdateListener listener = new TestOnAccountsUpdateListener();
am.addOnAccountsUpdatedListener(listener, null, true);
assertThat(listener.getInvocationCount()).isEqualTo(1);
}
@Test
public void testAccountsUpdateListener_listenerNotInvokedAfterRemoval() {
TestOnAccountsUpdateListener listener = new TestOnAccountsUpdateListener();
am.addOnAccountsUpdatedListener(listener, null, false);
assertThat(listener.getInvocationCount()).isEqualTo(0);
Account account = new Account("name", "type");
shadowOf(am).addAccount(account);
assertThat(listener.getInvocationCount()).isEqualTo(1);
am.removeOnAccountsUpdatedListener(listener);
shadowOf(am).addAccount(account);
assertThat(listener.getInvocationCount()).isEqualTo(1);
}
@Test
public void testAddAuthenticator() {
shadowOf(am).addAuthenticator("type");
AuthenticatorDescription[] result = am.getAuthenticatorTypes();
assertThat(result.length).isEqualTo(1);
assertThat(result[0].type).isEqualTo("type");
}
@Test
public void invalidateAuthToken_noAccount() {
am.invalidateAuthToken("type1", "token1");
}
@Test
public void invalidateAuthToken_noToken() {
Account account1 = new Account("name", "type1");
shadowOf(am).addAccount(account1);
am.invalidateAuthToken("type1", "token1");
}
@Test
public void invalidateAuthToken_multipleAccounts() {
Account account1 = new Account("name", "type1");
shadowOf(am).addAccount(account1);
Account account2 = new Account("name", "type2");
shadowOf(am).addAccount(account2);
am.setAuthToken(account1, "token_type_1", "token1");
am.setAuthToken(account2, "token_type_1", "token1");
assertThat(am.peekAuthToken(account1, "token_type_1")).isEqualTo("token1");
assertThat(am.peekAuthToken(account2, "token_type_1")).isEqualTo("token1");
// invalidate token for type1 account
am.invalidateAuthToken("type1", "token1");
assertThat(am.peekAuthToken(account1, "token_type_1")).isNull();
assertThat(am.peekAuthToken(account2, "token_type_1")).isEqualTo("token1");
// invalidate token for type2 account
am.invalidateAuthToken("type2", "token1");
assertThat(am.peekAuthToken(account1, "token_type_1")).isNull();
assertThat(am.peekAuthToken(account2, "token_type_1")).isNull();
}
@Test
public void invalidateAuthToken_multipleTokens() {
Account account = new Account("name", "type1");
shadowOf(am).addAccount(account);
am.setAuthToken(account, "token_type_1", "token1");
am.setAuthToken(account, "token_type_2", "token2");
assertThat(am.peekAuthToken(account, "token_type_1")).isEqualTo("token1");
assertThat(am.peekAuthToken(account, "token_type_2")).isEqualTo("token2");
// invalidate token1
am.invalidateAuthToken("type1", "token1");
assertThat(am.peekAuthToken(account, "token_type_1")).isNull();
assertThat(am.peekAuthToken(account, "token_type_2")).isEqualTo("token2");
// invalidate token2
am.invalidateAuthToken("type1", "token2");
assertThat(am.peekAuthToken(account, "token_type_1")).isNull();
assertThat(am.peekAuthToken(account, "token_type_2")).isNull();
}
@Test
public void invalidateAuthToken_multipleTokenTypesSameToken() {
Account account = new Account("name", "type1");
shadowOf(am).addAccount(account);
am.setAuthToken(account, "token_type_1", "token1");
am.setAuthToken(account, "token_type_2", "token1");
assertThat(am.peekAuthToken(account, "token_type_1")).isEqualTo("token1");
assertThat(am.peekAuthToken(account, "token_type_2")).isEqualTo("token1");
// invalidate token1
am.invalidateAuthToken("type1", "token1");
assertThat(am.peekAuthToken(account, "token_type_1")).isNull();
assertThat(am.peekAuthToken(account, "token_type_2")).isNull();
}
@Test
public void addAccount_noActivitySpecified() throws Exception {
shadowOf(am).addAuthenticator("google.com");
AccountManagerFuture<Bundle> result = am.addAccount("google.com", "auth_token_type", null, null, null, null, null);
Bundle resultBundle = result.getResult();
assertThat(resultBundle.getParcelable(AccountManager.KEY_INTENT)).isNotNull();
}
@Test
public void addAccount_activitySpecified() throws Exception {
shadowOf(am).addAuthenticator("google.com");
AccountManagerFuture<Bundle> result = am.addAccount("google.com", "auth_token_type", null, null, activity, null, null);
Bundle resultBundle = result.getResult();
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_TYPE)).isEqualTo("google.com");
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_NAME)).isEqualTo("some_user@gmail.com");
}
@Test
public void addAccount_shouldCallCallback() throws Exception {
shadowOf(am).addAuthenticator("google.com");
TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Bundle> result = am.addAccount("google.com", "auth_token_type", null, null, activity, callback, new Handler());
assertThat(callback.hasBeenCalled()).isFalse();
assertThat(result.isDone()).isFalse();
shadowOf(am).addAccount(new Account("thebomb@google.com", "google.com"));
assertThat(result.isDone()).isTrue();
assertThat(callback.accountManagerFuture).isNotNull();
Bundle resultBundle = callback.getResult();
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_TYPE)).isEqualTo("google.com");
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_NAME)).isEqualTo("thebomb@google.com");
}
@Test
public void addAccount_whenSchedulerPaused_shouldCallCallbackAfterSchedulerUnpaused() throws Exception {
scheduler.pause();
shadowOf(am).addAuthenticator("google.com");
TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Bundle> result = am.addAccount("google.com", "auth_token_type", null, null, activity, callback, new Handler());
assertThat(callback.hasBeenCalled()).isFalse();
assertThat(result.isDone()).isFalse();
shadowOf(am).addAccount(new Account("thebomb@google.com", "google.com"));
scheduler.unPause();
assertThat(result.isDone()).isTrue();
assertThat(callback.hasBeenCalled()).isTrue();
Bundle resultBundle = callback.getResult();
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_TYPE)).isEqualTo("google.com");
assertThat(resultBundle.getString(AccountManager.KEY_ACCOUNT_NAME)).isEqualTo("thebomb@google.com");
}
@Test
public void addAccount_noAuthenticatorDefined() throws Exception {
AccountManagerFuture<Bundle> future = am.addAccount("unknown_account_type", "auth_token_type", null, null, activity, null, null);
try {
future.getResult();
fail("addAccount() should throw an authenticator exception if no authenticator was registered for this account type");
} catch(AuthenticatorException e) {
// Expected
}
}
@Test
public void addAccount_withOptionsShouldSupportGetNextAddAccountOptions() throws Exception {
assertThat(shadowOf(am).getNextAddAccountOptions()).isNull();
shadowOf(am).addAuthenticator("google.com");
Bundle expectedAddAccountOptions = new Bundle();
expectedAddAccountOptions.putString("option", "value");
am.addAccount("google.com", "auth_token_type", null, expectedAddAccountOptions, activity, null, null);
Bundle actualAddAccountOptions = shadowOf(am).getNextAddAccountOptions();
assertThat(shadowOf(am).getNextAddAccountOptions()).isNull();
assertThat(actualAddAccountOptions).isEqualTo(expectedAddAccountOptions);
}
@Test
public void addAccount_withOptionsShouldSupportPeekNextAddAccountOptions() throws Exception {
assertThat(shadowOf(am).peekNextAddAccountOptions()).isNull();
shadowOf(am).addAuthenticator("google.com");
Bundle expectedAddAccountOptions = new Bundle();
expectedAddAccountOptions.putString("option", "value");
am.addAccount("google.com", "auth_token_type", null, expectedAddAccountOptions, activity, null, null);
Bundle actualAddAccountOptions = shadowOf(am).peekNextAddAccountOptions();
assertThat(shadowOf(am).peekNextAddAccountOptions()).isNotNull();
assertThat(actualAddAccountOptions).isEqualTo(expectedAddAccountOptions);
}
@Test
public void addAccount_withNoAuthenticatorForType_throwsExceptionInGetResult() throws Exception {
assertThat(shadowOf(am).peekNextAddAccountOptions()).isNull();
AccountManagerFuture<Bundle> futureResult = am.addAccount("google.com", "auth_token_type", null, null, activity, null, null);
try {
futureResult.getResult();
fail("should have thrown");
} catch (AuthenticatorException expected) { }
}
@Test
@Config(minSdk = LOLLIPOP)
public void addPreviousAccount() {
Account account = new Account("name_a", "type_a");
shadowOf(am).setPreviousAccountName(account, "old_name");
assertThat(am.getPreviousName(account)).isEqualTo("old_name");
}
@Test
public void testGetAsSystemService() throws Exception {
AccountManager systemService = (AccountManager) RuntimeEnvironment.application.getSystemService(Context.ACCOUNT_SERVICE);
assertThat(systemService).isNotNull();
assertThat(am).isEqualTo(systemService);
}
@Test
public void getAuthToken() throws Exception {
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
shadowOf(am).addAuthenticator("google.com");
am.setAuthToken(account, "auth_token_type", "token1");
TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Bundle> future = am.getAuthToken(account,
"auth_token_type",
new Bundle(),
activity,
callback,
new Handler());
assertThat(future.isDone()).isTrue();
assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_NAME)).isEqualTo(account.name);
assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_TYPE)).isEqualTo(account.type);
assertThat(future.getResult().getString(AccountManager.KEY_AUTHTOKEN)).isEqualTo("token1");
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void whenPaused_getAuthToken() throws Exception {
scheduler.pause();
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
shadowOf(am).addAuthenticator("google.com");
am.setAuthToken(account, "auth_token_type", "token1");
TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Bundle> future = am.getAuthToken(account, "auth_token_type", new Bundle(), activity, callback, new Handler());
assertThat(future.isDone()).isFalse();
assertThat(callback.hasBeenCalled()).isFalse();
scheduler.unPause();
assertThat(future.isDone()).isTrue();
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void getHasFeatures_returnsTrueWhenAllFeaturesSatisfied() throws Exception {
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
shadowOf(am).setFeatures(account, new String[] { "FEATURE_1", "FEATURE_2" });
TestAccountManagerCallback<Boolean> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Boolean> future = am.hasFeatures(account, new String[] { "FEATURE_1", "FEATURE_2" }, callback, new Handler());
assertThat(future.isDone()).isTrue();
assertThat(future.getResult().booleanValue()).isEqualTo(true);
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void whenSchedulerPaused_getHasFeatures_returnsTrueWhenAllFeaturesSatisfied() throws Exception {
scheduler.pause();
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
shadowOf(am).setFeatures(account, new String[] { "FEATURE_1", "FEATURE_2" });
TestAccountManagerCallback<Boolean> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Boolean> future = am.hasFeatures(account, new String[] { "FEATURE_1", "FEATURE_2" }, callback, new Handler());
assertThat(future.isDone()).isFalse();
assertThat(callback.hasBeenCalled()).isFalse();
assertThat(future.getResult()).isNull();
scheduler.unPause();
assertThat(future.getResult().booleanValue()).isEqualTo(true);
assertThat(future.isDone()).isTrue();
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void getHasFeatures_returnsFalseWhenAllFeaturesNotSatisfied() throws Exception {
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
shadowOf(am).setFeatures(account, new String[] { "FEATURE_1" });
TestAccountManagerCallback<Boolean> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Boolean> future = am.hasFeatures(account, new String[] { "FEATURE_1", "FEATURE_2" }, callback, new Handler());
assertThat(future.isDone()).isTrue();
assertThat(future.getResult().booleanValue()).isEqualTo(false);
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void getAccountsByTypeAndFeatures() throws Exception {
Account accountWithCorrectTypeAndFeatures = new Account("account_1", "google.com");
shadowOf(am).addAccount(accountWithCorrectTypeAndFeatures);
shadowOf(am).setFeatures(accountWithCorrectTypeAndFeatures, new String[] { "FEATURE_1", "FEATURE_2" });
Account accountWithCorrectTypeButNotFeatures = new Account("account_2", "google.com");
shadowOf(am).addAccount(accountWithCorrectTypeButNotFeatures);
shadowOf(am).setFeatures(accountWithCorrectTypeButNotFeatures, new String[] { "FEATURE_1" });
Account accountWithCorrectFeaturesButNotType = new Account("account_3", "facebook.com");
shadowOf(am).addAccount(accountWithCorrectFeaturesButNotType);
shadowOf(am).setFeatures(accountWithCorrectFeaturesButNotType, new String[] { "FEATURE_1", "FEATURE_2" });
TestAccountManagerCallback<Account[]> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Account[]> future = am.getAccountsByTypeAndFeatures("google.com", new String[] { "FEATURE_1", "FEATURE_2" }, callback, new Handler());
assertThat(future.isDone()).isTrue();
assertThat(future.getResult()).containsOnly(accountWithCorrectTypeAndFeatures);
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
public void whenSchedulerPaused_getAccountsByTypeAndFeatures() throws Exception {
scheduler.pause();
Account accountWithCorrectTypeAndFeatures = new Account("account_1", "google.com");
shadowOf(am).addAccount(accountWithCorrectTypeAndFeatures);
shadowOf(am).setFeatures(accountWithCorrectTypeAndFeatures, new String[] { "FEATURE_1", "FEATURE_2" });
TestAccountManagerCallback<Account[]> callback = new TestAccountManagerCallback<>();
AccountManagerFuture<Account[]> future = am.getAccountsByTypeAndFeatures("google.com", new String[] { "FEATURE_1", "FEATURE_2" }, callback, new Handler());
assertThat(future.isDone()).isFalse();
assertThat(callback.hasBeenCalled()).isFalse();
scheduler.unPause();
assertThat(future.getResult()).containsOnly(accountWithCorrectTypeAndFeatures);
assertThat(future.isDone()).isTrue();
assertThat(callback.hasBeenCalled()).isTrue();
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void getAccountsByTypeForPackage() {
Account[] accountsByTypeForPackage = am.getAccountsByTypeForPackage(null, "org.somepackage");
assertThat(accountsByTypeForPackage).isEmpty();
Account accountVisibleToPackage = new Account("user@gmail.com", "gmail.com");
shadowOf(am).addAccount(accountVisibleToPackage, "org.somepackage");
accountsByTypeForPackage = am.getAccountsByTypeForPackage("other_type", "org.somepackage");
assertThat(accountsByTypeForPackage).isEmpty();
accountsByTypeForPackage = am.getAccountsByTypeForPackage("gmail.com", "org.somepackage");
assertThat(accountsByTypeForPackage).containsOnly(accountVisibleToPackage);
accountsByTypeForPackage = am.getAccountsByTypeForPackage(null, "org.somepackage");
assertThat(accountsByTypeForPackage).containsOnly(accountVisibleToPackage);
}
@Test
@Config(minSdk = LOLLIPOP_MR1)
public void removeAccountExplicitly() {
assertThat(am.removeAccountExplicitly(new Account("non_existant_account@gmail.com", "gmail.com"))).isFalse();
assertThat(am.removeAccountExplicitly(null)).isFalse();
Account account = new Account("name@gmail.com", "gmail.com");
shadowOf(am).addAccount(account);
assertThat(am.removeAccountExplicitly(account)).isTrue();
}
@Test
public void removeAllAccounts() throws Exception {
Account account = new Account("name@gmail.com", "gmail.com");
shadowOf(am).addAccount(account);
assertThat(am.getAccounts()).isNotEmpty();
shadowOf(am).removeAllAccounts();
assertThat(am.getAccounts()).isEmpty();
}
private static class TestAccountManagerCallback<T> implements AccountManagerCallback<T> {
private AccountManagerFuture<T> accountManagerFuture;
@Override
public void run(AccountManagerFuture<T> accountManagerFuture) {
this.accountManagerFuture = accountManagerFuture;
}
boolean hasBeenCalled() {
return accountManagerFuture != null;
}
T getResult() throws Exception {
return accountManagerFuture.getResult();
}
}
}