Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3656)

Unified Diff: chrome/android/junit/src/org/chromium/chrome/browser/childaccounts/ChildAccountServiceTest.java

Issue 1362723006: Revert of ChildAccountService[Java] delegates everything to native side. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@child
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/junit/src/org/chromium/chrome/browser/childaccounts/ChildAccountServiceTest.java
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/childaccounts/ChildAccountServiceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/childaccounts/ChildAccountServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3bdc79c9d75cccf460e2da1e4bd1f9c29aea9d1f
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/childaccounts/ChildAccountServiceTest.java
@@ -0,0 +1,363 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.childaccounts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.google.android.collect.Sets;
+
+import org.chromium.base.CommandLine;
+import org.chromium.chrome.browser.childaccounts.ChildAccountService.HasChildAccountCallback;
+import org.chromium.sync.signin.AccountManagerHelper;
+import org.chromium.sync.test.util.AccountHolder;
+import org.chromium.sync.test.util.MockAccountManager;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * Robolectric-based unit test for ChildAccountService.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ChildAccountServiceTest {
+ private static final Account USER_ACCOUNT =
+ new Account("user@gmail.com", AccountManagerHelper.GOOGLE_ACCOUNT_TYPE);
+
+ private static final Account CHILD_ACCOUNT =
+ new Account("child@gmail.com", AccountManagerHelper.GOOGLE_ACCOUNT_TYPE);
+
+ private ChildAccountService mService;
+
+ private MockAccountManager mAccountManager;
+
+ private Context mContext = spy(Robolectric.application);
+
+ private class TestingChildAccountService extends ChildAccountService {
+ private Boolean mLastStatus;
+
+ public TestingChildAccountService(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onChildAccountStatusUpdated(Boolean oldValue) {
+ assertEquals(mLastStatus, oldValue);
+ mLastStatus = hasChildAccount();
+ }
+ }
+
+ private class MockChildAccountCallback implements HasChildAccountCallback {
+ @Override
+ public void onChildAccountChecked(boolean hasChildAccount) {
+ assertEquals(hasChildAccount, mService.hasChildAccount());
+ }
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mService = spy(new TestingChildAccountService(mContext));
+ when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mContext.checkPermission(
+ Matchers.anyString(), Matchers.anyInt(), Matchers.anyInt()))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+ doReturn(true).when(mService).nativeIsChildAccountDetectionEnabled();
+ doThrow(new AssertionError()).when(mService).nativeGetIsChildAccount();
+ mAccountManager = new MockAccountManager(mContext, mContext);
+ AccountManagerHelper.overrideAccountManagerHelperForTests(mContext, mAccountManager);
+
+ CommandLine.init(new String[] {});
+
+ // Run the main looper manually.
+ Robolectric.pauseMainLooper();
+ }
+
+ @Test
+ public void testNoAccounts() {
+ // Add no accounts.
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+
+ // The child account status is immediately updated to false.
+ verify(mService).onChildAccountStatusUpdated(null);
+
+ // The callback is only run on the next turn of the event loop, however.
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ Robolectric.idleMainLooper(0);
+
+ verify(callback).onChildAccountChecked(false);
+ }
+
+ @Test
+ public void testMultipleAccounts() {
+ // Add multiple accounts.
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create().account(CHILD_ACCOUNT).build());
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create().account(USER_ACCOUNT).build());
+
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+
+ // The child account status is immediately updated to false.
+ verify(mService).onChildAccountStatusUpdated(null);
+
+ // The callback is only run on the next turn of the event loop, however.
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ Robolectric.idleMainLooper(0);
+
+ verify(callback).onChildAccountChecked(false);
+ }
+
+ @Test
+ public void testSingleRegularAccount() {
+ // Add one regular account.
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create().account(USER_ACCOUNT).featureSet(null).build());
+
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ // The account features have not been fetched yet, so the child account status is
+ // indeterminate.
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // When the account features have been fetched, the child account status is set to false and
+ // the callback is run.
+ mAccountManager.notifyFeaturesFetched(USER_ACCOUNT, Collections.<String>emptySet());
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(false);
+ }
+
+ @Test
+ public void testSingleChildAccount() {
+ // Add one child account.
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create().account(CHILD_ACCOUNT).featureSet(null).build());
+
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ // The account features have not been fetched yet, so the child account status is
+ // indeterminate.
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // When the account features have been fetched, the child account status is set to true and
+ // the callback is run.
+ mAccountManager.notifyFeaturesFetched(
+ CHILD_ACCOUNT, Sets.newHashSet(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY));
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(true);
+ }
+
+ @Test
+ public void testCheckAfterChildAccountStatusHasBeenDetermined() {
+ // Add one child account.
+ Account account = CHILD_ACCOUNT;
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create()
+ .account(account)
+ .addFeature(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY)
+ .build());
+
+ // Check the child account status with a callback and wait for it to resolve.
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(true);
+
+ // Checking the status again will call the callback, but not update the child account
+ // status.
+ HasChildAccountCallback callback2 = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback2);
+ Robolectric.idleMainLooper(0);
+
+ verify(callback2).onChildAccountChecked(true);
+ }
+
+ @Test
+ public void testCachedHasChildAccount() {
+ // If the child account status has not been determined, the native method will be called.
+ // Using the inverted `do...().when()...` syntax to ensure that the non-overridden method
+ // is not called.
+ doReturn(true).when(mService).nativeGetIsChildAccount();
+
+ assertTrue(mService.hasChildAccount());
+ }
+
+ @Test
+ public void testAccountRemoved() {
+ // Add one child account.
+ AccountHolder accountHolder =
+ AccountHolder.create()
+ .account(CHILD_ACCOUNT)
+ .addFeature(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY)
+ .build();
+ mAccountManager.addAccountHolderExplicitly(accountHolder);
+
+ // Check the child account status with a callback and wait for it to resolve.
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(true);
+
+ // Removing the account and rechecking changes the child account status to false.
+ mAccountManager.removeAccountHolderExplicitly(accountHolder);
+ mService.recheckChildAccountStatus();
+
+ verify(mService).onChildAccountStatusUpdated(true);
+ assertFalse(mService.hasChildAccount());
+ }
+
+ @Test
+ public void testAccountGraduated() {
+ // Add one child account.
+ AccountHolder accountHolder =
+ AccountHolder.create()
+ .account(CHILD_ACCOUNT)
+ .addFeature(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY)
+ .build();
+ mAccountManager.addAccountHolderExplicitly(accountHolder);
+
+ // Check the child account status with a callback and wait for it to resolve.
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(true);
+
+ // Replace the account holder with one where the account features are not fetched yet.
+ mAccountManager.removeAccountHolderExplicitly(accountHolder);
+ mAccountManager.addAccountHolderExplicitly(
+ AccountHolder.create().account(CHILD_ACCOUNT).featureSet(null).build());
+ mService.recheckChildAccountStatus();
+
+ // While the check is still in progress, the child account status has its old value, and no
+ // additional calls to onChildAccountStatusUpdated() were made.
+ verify(mService).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ assertTrue(mService.hasChildAccount());
+
+ // When the features are fetched, the child account status changes to false.
+ mAccountManager.notifyFeaturesFetched(CHILD_ACCOUNT, new HashSet<String>());
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(true);
+ assertFalse(mService.hasChildAccount());
+ }
+
+ @Test
+ public void testAccountRemovedDuringInitialCheck() {
+ // Add one child account.
+ AccountHolder accountHolder =
+ AccountHolder.create().account(CHILD_ACCOUNT).featureSet(null).build();
+ mAccountManager.addAccountHolderExplicitly(accountHolder);
+
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ // The account features have not been fetched yet, so the child account status is
+ // indeterminate.
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ mAccountManager.removeAccountHolderExplicitly(accountHolder);
+ mService.recheckChildAccountStatus();
+
+ // When the account is removed, the child account status is set to false.
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // Fetching the features for the removed account should not trigger a status update,
+ // but the original callback will run.
+ accountHolder.didFetchFeatures(
+ Sets.newHashSet(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY));
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback).onChildAccountChecked(false);
+ }
+
+ @Test
+ public void testAccountGraduatedDuringInitialCheck() {
+ // Add one child account.
+ AccountHolder.Builder builder =
+ AccountHolder.create().account(CHILD_ACCOUNT).featureSet(null);
+ AccountHolder accountHolder = builder.build();
+ mAccountManager.addAccountHolderExplicitly(accountHolder);
+
+ HasChildAccountCallback callback = spy(new MockChildAccountCallback());
+ mService.checkHasChildAccount(callback);
+ Robolectric.idleMainLooper(0);
+
+ // The account features have not been fetched yet, so the child account status is
+ // undetermined.
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // Replace the account holder with a copy.
+ mAccountManager.removeAccountHolderExplicitly(accountHolder);
+ AccountHolder accountHolder2 = builder.build();
+ mAccountManager.addAccountHolderExplicitly(accountHolder2);
+ mService.recheckChildAccountStatus();
+
+ // The child account status is still undetermined.
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // The first request for the account features returns, but the child account status stays
+ // undetermined.
+ accountHolder.didFetchFeatures(
+ Sets.newHashSet(AccountManagerHelper.FEATURE_IS_CHILD_ACCOUNT_KEY));
+ Robolectric.idleMainLooper(0);
+ verify(mService, never()).onChildAccountStatusUpdated(Matchers.any(Boolean.class));
+ verify(callback, never()).onChildAccountChecked(Matchers.anyBoolean());
+
+ // Only when the second request for the account features returns, the child account status
+ // is set to false.
+ accountHolder2.didFetchFeatures(new HashSet<String>());
+ Robolectric.idleMainLooper(0);
+
+ verify(mService).onChildAccountStatusUpdated(null);
+ verify(callback).onChildAccountChecked(false);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698