Commit 52288533 authored by Boris Sazonov's avatar Boris Sazonov Committed by Commit Bot

[Signin][Android] Revise SigninManagerTest

Refactors SigninManagerTest:
* Switches to explicit creation for SigninManager, thus allowing writing
  tests for SigninManager ctor. Such a test will be added in a
  subsequent CL.
* Adds explicit SigninManager.destroy call.
* Removes redundant Mockito stubs (doNothing & doReturn(null)) where
  they don't improve the readability of the test.
* Switches to @Mock annotations instead of manual mock(...) in setUp.

Bug: 1132290
Change-Id: I630cc95d84c6ba4f5d2fc737dbb8a786e6dd6f8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2431486
Commit-Queue: Boris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarAlice Wang <aliceywang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811684}
parent c851f41f
...@@ -12,20 +12,18 @@ import static org.mockito.ArgumentMatchers.anyInt; ...@@ -12,20 +12,18 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
...@@ -54,65 +52,66 @@ public class SigninManagerTest { ...@@ -54,65 +52,66 @@ public class SigninManagerTest {
@Rule @Rule
public final JniMocker mocker = new JniMocker(); public final JniMocker mocker = new JniMocker();
@Mock private static final AccountInfo ACCOUNT_INFO = new AccountInfo(
SigninManager.Natives mNativeMock; new CoreAccountId("gaia-id-user"), "user@domain.com", "gaia-id-user", null);
private AccountTrackerService mAccountTrackerService; private final SigninManager.Natives mNativeMock = mock(SigninManager.Natives.class);
private final AccountTrackerService mAccountTrackerService = mock(AccountTrackerService.class);
private final IdentityMutator mIdentityMutator = mock(IdentityMutator.class);
private final AndroidSyncSettings mAndroidSyncSettings = mock(AndroidSyncSettings.class);
private final ExternalAuthUtils mExternalAuthUtils = mock(ExternalAuthUtils.class);
private IdentityManager mIdentityManager; private IdentityManager mIdentityManager;
private IdentityMutator mIdentityMutator;
private SigninManager mSigninManager; private SigninManager mSigninManager;
private CoreAccountInfo mAccount;
private AndroidSyncSettings mAndroidSyncSettings;
@Before @Before
public void setUp() { public void setUp() {
initMocks(this);
mocker.mock(SigninManagerJni.TEST_HOOKS, mNativeMock); mocker.mock(SigninManagerJni.TEST_HOOKS, mNativeMock);
doReturn(true).when(mNativeMock).isSigninAllowedByPolicy(anyLong()); doReturn(true).when(mNativeMock).isSigninAllowedByPolicy(anyLong());
// Pretend Google Play services are available as it is required for the sign-in
mAccountTrackerService = mock(AccountTrackerService.class); doReturn(false).when(mExternalAuthUtils).isGooglePlayServicesMissing(any());
mIdentityMutator = mock(IdentityMutator.class);
mIdentityManager = spy( mIdentityManager = spy(
new IdentityManager(0 /* nativeIdentityManager */, null /* OAuth2TokenService */)); new IdentityManager(0 /* nativeIdentityManager */, null /* OAuth2TokenService */));
doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(anyInt());
}
mAndroidSyncSettings = mock(AndroidSyncSettings.class); @After
public void tearDown() {
ExternalAuthUtils externalAuthUtils = mock(ExternalAuthUtils.class); if (mSigninManager != null) {
// Pretend Google Play services are available as it is required for the sign-in mSigninManager.destroy();
doReturn(false).when(externalAuthUtils).isGooglePlayServicesMissing(any()); mSigninManager = null;
}
}
doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(anyInt()); private void createSigninManager() {
mSigninManager = new SigninManager(0 /* nativeSigninManagerAndroid */, mSigninManager = new SigninManager(0 /* nativeSigninManagerAndroid */,
mAccountTrackerService, mIdentityManager, mIdentityMutator, mAndroidSyncSettings, mAccountTrackerService, mIdentityManager, mIdentityMutator, mAndroidSyncSettings,
externalAuthUtils); mExternalAuthUtils);
mAccount = new AccountInfo(
new CoreAccountId("gaia-id-user"), "user@domain.com", "gaia-id-user", null);
} }
@Test @Test
public void signinAndTurnSyncOn() { public void signinAndTurnSyncOn() {
doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts(); doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
doReturn(mAccount) doReturn(ACCOUNT_INFO)
.when(mIdentityManager) .when(mIdentityManager)
.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
eq(mAccount.getEmail())); eq(ACCOUNT_INFO.getEmail()));
doReturn(true).when(mIdentityMutator).setPrimaryAccount(any(), anyInt()); doReturn(true).when(mIdentityMutator).setPrimaryAccount(any(), anyInt());
createSigninManager();
mSigninManager.onFirstRunCheckDone(); mSigninManager.onFirstRunCheckDone();
SigninManager.SignInCallback callback = mock(SigninManager.SignInCallback.class); SigninManager.SignInCallback callback = mock(SigninManager.SignInCallback.class);
mSigninManager.signinAndEnableSync(SigninAccessPoint.START_PAGE, mAccount, callback); mSigninManager.signinAndEnableSync(SigninAccessPoint.START_PAGE, ACCOUNT_INFO, callback);
verify(mNativeMock).fetchAndApplyCloudPolicy(anyLong(), eq(mAccount), any()); verify(mNativeMock).fetchAndApplyCloudPolicy(anyLong(), eq(ACCOUNT_INFO), any());
mSigninManager.finishSignInAfterPolicyEnforced(); mSigninManager.finishSignInAfterPolicyEnforced();
verify(mIdentityMutator).setPrimaryAccount(mAccount.getId(), ConsentLevel.SYNC); verify(mIdentityMutator).setPrimaryAccount(ACCOUNT_INFO.getId(), ConsentLevel.SYNC);
verify(mAndroidSyncSettings).updateAccount(CoreAccountInfo.getAndroidAccountFrom(mAccount)); verify(mAndroidSyncSettings)
.updateAccount(CoreAccountInfo.getAndroidAccountFrom(ACCOUNT_INFO));
verify(mAndroidSyncSettings).enableChromeSync(); verify(mAndroidSyncSettings).enableChromeSync();
// Signin should be complete and callback should be invoked. // Signin should be complete and callback should be invoked.
verify(callback).onSignInComplete(); verify(callback).onSignInComplete();
...@@ -122,21 +121,22 @@ public class SigninManagerTest { ...@@ -122,21 +121,22 @@ public class SigninManagerTest {
@Test @Test
public void signinNoTurnSyncOn() { public void signinNoTurnSyncOn() {
doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts(); doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
doReturn(mAccount) doReturn(ACCOUNT_INFO)
.when(mIdentityManager) .when(mIdentityManager)
.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
eq(mAccount.getEmail())); eq(ACCOUNT_INFO.getEmail()));
doReturn(true).when(mIdentityMutator).setPrimaryAccount(any(), anyInt()); doReturn(true).when(mIdentityMutator).setPrimaryAccount(any(), anyInt());
createSigninManager();
mSigninManager.onFirstRunCheckDone(); mSigninManager.onFirstRunCheckDone();
SigninManager.SignInCallback callback = mock(SigninManager.SignInCallback.class); SigninManager.SignInCallback callback = mock(SigninManager.SignInCallback.class);
mSigninManager.signin(mAccount, callback); mSigninManager.signin(ACCOUNT_INFO, callback);
// Signin without turning on sync shouldn't apply policies. // Signin without turning on sync shouldn't apply policies.
verify(mNativeMock, never()).fetchAndApplyCloudPolicy(anyLong(), any(), any()); verify(mNativeMock, never()).fetchAndApplyCloudPolicy(anyLong(), any(), any());
verify(mIdentityMutator).setPrimaryAccount(mAccount.getId(), ConsentLevel.NOT_REQUIRED); verify(mIdentityMutator).setPrimaryAccount(ACCOUNT_INFO.getId(), ConsentLevel.NOT_REQUIRED);
verify(mAndroidSyncSettings, never()).updateAccount(any()); verify(mAndroidSyncSettings, never()).updateAccount(any());
verify(mAndroidSyncSettings, never()).enableChromeSync(); verify(mAndroidSyncSettings, never()).enableChromeSync();
...@@ -147,14 +147,10 @@ public class SigninManagerTest { ...@@ -147,14 +147,10 @@ public class SigninManagerTest {
@Test @Test
public void signOutFromJavaWithManagedDomain() { public void signOutFromJavaWithManagedDomain() {
// Stub out various native calls. Some of these are verified as never called
// and those stubs simply allow that verification to catch any issues.
doNothing().when(mNativeMock).wipeProfileData(anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(anyLong(), any());
// See verification of nativeWipeProfileData below. // See verification of nativeWipeProfileData below.
doReturn("TestDomain").when(mNativeMock).getManagementDomain(anyLong()); doReturn("TestDomain").when(mNativeMock).getManagementDomain(anyLong());
createSigninManager();
// Trigger the sign out flow! // Trigger the sign out flow!
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
...@@ -164,7 +160,7 @@ public class SigninManagerTest { ...@@ -164,7 +160,7 @@ public class SigninManagerTest {
verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any()); verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any());
// Simulate native callback to trigger clearing of account data. // Simulate native callback to trigger clearing of account data.
mIdentityManager.onPrimaryAccountCleared(mAccount); mIdentityManager.onPrimaryAccountCleared(ACCOUNT_INFO);
// Sign-out should only clear the profile when the user is managed. // Sign-out should only clear the profile when the user is managed.
verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any()); verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any());
...@@ -173,15 +169,10 @@ public class SigninManagerTest { ...@@ -173,15 +169,10 @@ public class SigninManagerTest {
@Test @Test
public void signOutFromJavaWithNullDomain() { public void signOutFromJavaWithNullDomain() {
// Stub out various native calls. Some of these are verified as never called // Simulate sign-out with non-managed account.
// and those stubs simply allow that verification to catch any issues.
doNothing().when(mNativeMock).wipeProfileData(anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(anyLong(), any());
// See verification of nativeWipeGoogleServiceWorkerCaches below.
doReturn(null).when(mNativeMock).getManagementDomain(anyLong()); doReturn(null).when(mNativeMock).getManagementDomain(anyLong());
// Trigger the sign out flow! createSigninManager();
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
// PrimaryAccountCleared should be called *before* clearing any account data. // PrimaryAccountCleared should be called *before* clearing any account data.
...@@ -190,7 +181,7 @@ public class SigninManagerTest { ...@@ -190,7 +181,7 @@ public class SigninManagerTest {
verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any()); verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any());
// Simulate native callback to trigger clearing of account data. // Simulate native callback to trigger clearing of account data.
mIdentityManager.onPrimaryAccountCleared(mAccount); mIdentityManager.onPrimaryAccountCleared(ACCOUNT_INFO);
// Sign-out should only clear the service worker cache when the user is not managed. // Sign-out should only clear the service worker cache when the user is not managed.
verify(mNativeMock, never()).wipeProfileData(anyLong(), any()); verify(mNativeMock, never()).wipeProfileData(anyLong(), any());
...@@ -199,15 +190,10 @@ public class SigninManagerTest { ...@@ -199,15 +190,10 @@ public class SigninManagerTest {
@Test @Test
public void signOutFromJavaWithNullDomainAndForceWipe() { public void signOutFromJavaWithNullDomainAndForceWipe() {
// Stub out various native calls. Some of these are verified as never called
// and those stubs simply allow that verification to catch any issues.
doNothing().when(mNativeMock).wipeProfileData(anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(anyLong(), any());
// See verification of nativeWipeGoogleServiceWorkerCaches below. // See verification of nativeWipeGoogleServiceWorkerCaches below.
doReturn(null).when(mNativeMock).getManagementDomain(anyLong()); doReturn(null).when(mNativeMock).getManagementDomain(anyLong());
// Trigger the sign out flow createSigninManager();
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST, null, true); mSigninManager.signOut(SignoutReason.SIGNOUT_TEST, null, true);
// PrimaryAccountCleared should be called *before* clearing any account data. // PrimaryAccountCleared should be called *before* clearing any account data.
...@@ -216,7 +202,7 @@ public class SigninManagerTest { ...@@ -216,7 +202,7 @@ public class SigninManagerTest {
verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any()); verify(mNativeMock, never()).wipeGoogleServiceWorkerCaches(anyLong(), any());
// Simulate native callback to trigger clearing of account data. // Simulate native callback to trigger clearing of account data.
mIdentityManager.onPrimaryAccountCleared(mAccount); mIdentityManager.onPrimaryAccountCleared(ACCOUNT_INFO);
// Sign-out should only clear the service worker cache when the user is not managed. // Sign-out should only clear the service worker cache when the user is not managed.
verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any()); verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any());
...@@ -225,13 +211,9 @@ public class SigninManagerTest { ...@@ -225,13 +211,9 @@ public class SigninManagerTest {
@Test @Test
public void signOutFromNative() { public void signOutFromNative() {
// Stub out various native calls. Some of these are verified as never called createSigninManager();
// and those stubs simply allow that verification to catch any issues. // Simulate native initiating the sign-out.
doNothing().when(mNativeMock).wipeProfileData(anyLong(), any()); mIdentityManager.onPrimaryAccountCleared(ACCOUNT_INFO);
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(anyLong(), any());
// Trigger the sign out flow!
mIdentityManager.onPrimaryAccountCleared(mAccount);
// Sign-out should only clear the profile when the user is managed. // Sign-out should only clear the profile when the user is managed.
verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any()); verify(mNativeMock, times(1)).wipeProfileData(anyLong(), any());
...@@ -240,10 +222,8 @@ public class SigninManagerTest { ...@@ -240,10 +222,8 @@ public class SigninManagerTest {
@Test @Test
public void clearingAccountCookiesTriggersSignout() { public void clearingAccountCookiesTriggersSignout() {
// Stub out various native calls. Some of these are verified as never called // Create SigninManager so it adds an observer for onAccountsCookieDeletedByUserAction.
// and those stubs simply allow that verification to catch any issues. createSigninManager();
doNothing().when(mNativeMock).wipeProfileData(anyLong(), any());
doNothing().when(mNativeMock).wipeGoogleServiceWorkerCaches(anyLong(), any());
// Clearing cookies shouldn't do anything when there's no primary account. // Clearing cookies shouldn't do anything when there's no primary account.
doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(anyInt()); doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(anyInt());
...@@ -251,12 +231,14 @@ public class SigninManagerTest { ...@@ -251,12 +231,14 @@ public class SigninManagerTest {
verify(mIdentityMutator, never()).clearPrimaryAccount(anyInt(), anyInt(), anyInt()); verify(mIdentityMutator, never()).clearPrimaryAccount(anyInt(), anyInt(), anyInt());
// Clearing cookies shouldn't do anything when there's sync account. // Clearing cookies shouldn't do anything when there's sync account.
doReturn(mAccount).when(mIdentityManager).getPrimaryAccountInfo(anyInt()); doReturn(ACCOUNT_INFO).when(mIdentityManager).getPrimaryAccountInfo(anyInt());
mIdentityManager.onAccountsCookieDeletedByUserAction(); mIdentityManager.onAccountsCookieDeletedByUserAction();
verify(mIdentityMutator, never()).clearPrimaryAccount(anyInt(), anyInt(), anyInt()); verify(mIdentityMutator, never()).clearPrimaryAccount(anyInt(), anyInt(), anyInt());
// Clearing cookies when there's only an unconsented account should trigger sign-out. // Clearing cookies when there's only an unconsented account should trigger sign-out.
doReturn(mAccount).when(mIdentityManager).getPrimaryAccountInfo(ConsentLevel.NOT_REQUIRED); doReturn(ACCOUNT_INFO)
.when(mIdentityManager)
.getPrimaryAccountInfo(ConsentLevel.NOT_REQUIRED);
doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(ConsentLevel.SYNC); doReturn(null).when(mIdentityManager).getPrimaryAccountInfo(ConsentLevel.SYNC);
mIdentityManager.onAccountsCookieDeletedByUserAction(); mIdentityManager.onAccountsCookieDeletedByUserAction();
verify(mIdentityMutator) verify(mIdentityMutator)
...@@ -270,6 +252,7 @@ public class SigninManagerTest { ...@@ -270,6 +252,7 @@ public class SigninManagerTest {
@Test @Test
public void callbackNotifiedWhenNoOperationIsInProgress() { public void callbackNotifiedWhenNoOperationIsInProgress() {
createSigninManager();
assertFalse(mSigninManager.isOperationInProgress()); assertFalse(mSigninManager.isOperationInProgress());
AtomicInteger callCount = new AtomicInteger(0); AtomicInteger callCount = new AtomicInteger(0);
...@@ -280,12 +263,13 @@ public class SigninManagerTest { ...@@ -280,12 +263,13 @@ public class SigninManagerTest {
@Test @Test
public void callbackNotifiedOnSignout() { public void callbackNotifiedOnSignout() {
doAnswer(invocation -> { doAnswer(invocation -> {
mIdentityManager.onPrimaryAccountCleared(mAccount); mIdentityManager.onPrimaryAccountCleared(ACCOUNT_INFO);
return null; return null;
}) })
.when(mIdentityMutator) .when(mIdentityMutator)
.clearPrimaryAccount(anyInt(), anyInt(), anyInt()); .clearPrimaryAccount(anyInt(), anyInt(), anyInt());
createSigninManager();
mSigninManager.signOut(SignoutReason.SIGNOUT_TEST); mSigninManager.signOut(SignoutReason.SIGNOUT_TEST);
assertTrue(mSigninManager.isOperationInProgress()); assertTrue(mSigninManager.isOperationInProgress());
AtomicInteger callCount = new AtomicInteger(0); AtomicInteger callCount = new AtomicInteger(0);
...@@ -304,9 +288,6 @@ public class SigninManagerTest { ...@@ -304,9 +288,6 @@ public class SigninManagerTest {
// No need to seed accounts to the native code. // No need to seed accounts to the native code.
doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts(); doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
// Request that policy is loaded. It will pause sign-in until onPolicyCheckedBeforeSignIn is
// invoked.
doNothing().when(mNativeMock).fetchAndApplyCloudPolicy(anyLong(), any(), any());
doReturn(account) doReturn(account)
.when(mIdentityManager) .when(mIdentityManager)
...@@ -320,8 +301,8 @@ public class SigninManagerTest { ...@@ -320,8 +301,8 @@ public class SigninManagerTest {
doAnswer(setPrimaryAccountAnswer) doAnswer(setPrimaryAccountAnswer)
.when(mIdentityMutator) .when(mIdentityMutator)
.setPrimaryAccount(account.getId(), ConsentLevel.SYNC); .setPrimaryAccount(account.getId(), ConsentLevel.SYNC);
doNothing().when(mIdentityMutator).reloadAllAccountsFromSystemWithPrimaryAccount(any());
createSigninManager();
mSigninManager.onFirstRunCheckDone(); // Allow sign-in. mSigninManager.onFirstRunCheckDone(); // Allow sign-in.
mSigninManager.signinAndEnableSync(SigninAccessPoint.UNKNOWN, account, null); mSigninManager.signinAndEnableSync(SigninAccessPoint.UNKNOWN, account, null);
...@@ -342,15 +323,13 @@ public class SigninManagerTest { ...@@ -342,15 +323,13 @@ public class SigninManagerTest {
// No need to seed accounts to the native code. // No need to seed accounts to the native code.
doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts(); doReturn(true).when(mAccountTrackerService).checkAndSeedSystemAccounts();
// Request that policy is loaded. It will pause sign-in until onPolicyCheckedBeforeSignIn is
// invoked.
doNothing().when(mNativeMock).fetchAndApplyCloudPolicy(anyLong(), any(), any());
doReturn(account) doReturn(account)
.when(mIdentityManager) .when(mIdentityManager)
.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(any()); .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(any());
doReturn(true).when(mIdentityManager).hasPrimaryAccount(); doReturn(true).when(mIdentityManager).hasPrimaryAccount();
createSigninManager();
mSigninManager.onFirstRunCheckDone(); // Allow sign-in. mSigninManager.onFirstRunCheckDone(); // Allow sign-in.
mSigninManager.signinAndEnableSync(SigninAccessPoint.UNKNOWN, account, null); mSigninManager.signinAndEnableSync(SigninAccessPoint.UNKNOWN, account, null);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment