Commit 6097fa03 authored by Tanmoy Mollik's avatar Tanmoy Mollik Committed by Commit Bot

Add support to override ProfileSyncService in SyncTestRule

SyncTestRule doesn't provide a way to override the instance of
ProfileSyncService it holds. For this reason some tests might override
the ProfileSyncService with a subclass but SyncTestRule will hold a copy
of the old ProfileSyncService instance. This cl adds a method in
SyncTestRule to override ProfileSyncService and refactors some tests
that need to use it.


Bug: 1030725
Change-Id: I9fc1b770df4c153e726a4e071e432fc585561889
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2012380
Commit-Queue: Tanmoy Mollik <triploblastic@chromium.org>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#742596}
parent eddd5af6
......@@ -461,8 +461,10 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/sync/FakeProfileSyncService.java",
"javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java",
"javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java",
"javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsWithFakeProfileSyncServiceTest.java",
"javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
"javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsTest.java",
"javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsWithFakeProfileSyncServiceTest.java",
"javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
"javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java",
"javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
......
......@@ -44,7 +44,7 @@
</intent-filter>
</activity>
<activity android:name="org.chromium.chrome.browser.sync.ManageSyncSettingsTest$DummyKeyRetrievalActivity"
<activity android:name="org.chromium.chrome.browser.sync.ManageSyncSettingsWithFakeProfileSyncServiceTest$DummyKeyRetrievalActivity"
android:exported="true"/>
<activity android:name="org.chromium.chrome.browser.browserservices.TestTrustedWebActivityService"
......
......@@ -4,14 +4,8 @@
package org.chromium.chrome.browser.sync;
import android.app.Activity;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
......@@ -21,24 +15,17 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.chromium.base.Promise;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.FlakyTest;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.autofill.PersonalDataManager;
......@@ -51,7 +38,6 @@ import org.chromium.chrome.browser.sync.ui.PassphraseTypeDialogFragment;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ActivityUtils;
import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.sync.ModelType;
import org.chromium.components.sync.PassphraseType;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
......@@ -60,7 +46,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -70,43 +55,6 @@ import java.util.Set;
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class ManageSyncSettingsTest {
/**
* Simple activity that mimics a trusted vault key retrieval flow that succeeds immediately.
*/
public static class DummyKeyRetrievalActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_OK);
finish();
}
};
/**
* Stub backend for TrustedVaultClient used to test the key retrieval flow.
*/
private static class FakeTrustedVaultClientBackend implements TrustedVaultClient.Backend {
public FakeTrustedVaultClientBackend() {}
@Override
public Promise<List<byte[]>> fetchKeys(CoreAccountInfo accountInfo) {
return Promise.rejected();
}
@Override
public Promise<PendingIntent> createKeyRetrievalIntent(CoreAccountInfo accountInfo) {
Context context = InstrumentationRegistry.getContext();
Intent intent = new Intent(context, DummyKeyRetrievalActivity.class);
return Promise.fulfilled(
PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */));
}
@Override
public Promise<Boolean> markKeysAsStale(CoreAccountInfo accountInfo) {
return Promise.rejected();
}
}
private static final String TAG = "ManageSyncSettingsTest";
/**
......@@ -128,29 +76,9 @@ public class ManageSyncSettingsTest {
@Rule
public SyncTestRule mSyncTestRule = new SyncTestRule();
@Rule
public JniMocker mJniMocker = new JniMocker();
@Mock
TrustedVaultClient.Natives mTrustedVaultClientNativesMock;
private static final long TRUSTED_VAULT_CLIENT_NATIVE_PTR = 12345;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mJniMocker.mock(TrustedVaultClientJni.TEST_HOOKS, mTrustedVaultClientNativesMock);
// Register a mock native for calls to be forwarded to mTrustedVaultClientNativesMock.
TrustedVaultClient.setInstanceForTesting(
new TrustedVaultClient(new FakeTrustedVaultClientBackend()));
TrustedVaultClient.registerNative(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
}
@After
public void tearDown() {
TrustedVaultClient.unregisterNative(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
TestThreadUtils.runOnUiThreadBlocking(() -> ProfileSyncService.resetForTests());
TrustedVaultClient.setInstanceForTesting(null);
}
@Test
......@@ -405,41 +333,6 @@ public class ManageSyncSettingsTest {
// No crash means we passed.
}
/**
* Test that triggering OnPassphraseAccepted dismisses PassphraseDialogFragment.
*/
@Test
@SmallTest
@Feature({"Sync"})
@DisabledTest(message = "https://crbug.com/986243")
public void testPassphraseDialogDismissed() {
final FakeProfileSyncService pss = overrideProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
// Trigger PassphraseDialogFragment to be shown when taping on Encryption.
pss.setPassphraseRequiredForPreferredDataTypes(true);
final ManageSyncSettings fragment = startManageSyncPreferences();
Preference encryption = getEncryption(fragment);
clickPreference(encryption);
final PassphraseDialogFragment passphraseFragment = getPassphraseDialogFragment();
Assert.assertTrue(passphraseFragment.isAdded());
// Simulate OnPassphraseAccepted from external event by setting PassphraseRequired to false
// and triggering syncStateChanged().
// PassphraseDialogFragment should be dismissed.
pss.setPassphraseRequiredForPreferredDataTypes(false);
TestThreadUtils.runOnUiThreadBlocking(() -> {
pss.syncStateChanged();
fragment.getFragmentManager().executePendingTransactions();
Assert.assertNull("PassphraseDialogFragment should be dismissed.",
mSettingsActivity.getFragmentManager().findFragmentByTag(
ManageSyncSettings.FRAGMENT_ENTER_PASSPHRASE));
});
}
@Test
@SmallTest
@Feature({"Sync"})
......@@ -505,43 +398,6 @@ public class ManageSyncSettingsTest {
Assert.assertFalse(pcdf.isResumed());
}
/**
* Test the trusted vault key retrieval flow, which involves launching an intent and finally
* calling TrustedVaultClient.notifyKeysChanged().
*/
@Test
@LargeTest
@Feature({"Sync"})
public void testTrustedVaultKeyRetrieval() {
final FakeProfileSyncService pss = overrideProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
pss.setEngineInitialized(true);
pss.setTrustedVaultKeyRequired(true);
final ManageSyncSettings fragment = startManageSyncPreferences();
// Mimic the user tapping on Encryption.
Preference encryption = getEncryption(fragment);
clickPreference(encryption);
// Wait for DummyKeyRetrievalActivity to finish.
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
// Verify that notifyKeysChanged has been called upon completion.
Mockito.verify(mTrustedVaultClientNativesMock)
.notifyKeysChanged(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
}
private FakeProfileSyncService overrideProfileSyncService() {
return TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
// PSS has to be constructed on the UI thread.
FakeProfileSyncService fakeProfileSyncService = new FakeProfileSyncService();
ProfileSyncService.overrideForTests(fakeProfileSyncService);
return fakeProfileSyncService;
});
}
private ManageSyncSettings startManageSyncPreferences() {
mSettingsActivity = mSyncTestRule.startSettingsActivity(ManageSyncSettings.class.getName());
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
......
// Copyright 2020 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.sync;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
import android.support.v7.preference.Preference;
import androidx.annotation.Nullable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.chromium.base.Promise;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.settings.SettingsActivity;
import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
import org.chromium.chrome.browser.sync.ui.PassphraseDialogFragment;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ActivityUtils;
import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.List;
/**
* Test for ManageSyncSettings with FakeProfileSyncService.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class ManageSyncSettingsWithFakeProfileSyncServiceTest {
private static final long TRUSTED_VAULT_CLIENT_NATIVE_PTR = 12345;
/**
* Simple activity that mimics a trusted vault key retrieval flow that succeeds immediately.
*/
public static class DummyKeyRetrievalActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_OK);
finish();
}
};
/**
* Stub backend for TrustedVaultClient used to test the key retrieval flow.
*/
private static class FakeTrustedVaultClientBackend implements TrustedVaultClient.Backend {
public FakeTrustedVaultClientBackend() {}
@Override
public Promise<List<byte[]>> fetchKeys(CoreAccountInfo accountInfo) {
return Promise.rejected();
}
@Override
public Promise<PendingIntent> createKeyRetrievalIntent(CoreAccountInfo accountInfo) {
Context context = InstrumentationRegistry.getContext();
Intent intent = new Intent(context, DummyKeyRetrievalActivity.class);
return Promise.fulfilled(
PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */));
}
@Override
public Promise<Boolean> markKeysAsStale(CoreAccountInfo accountInfo) {
return Promise.rejected();
}
}
@Rule
public SyncTestRule mSyncTestRule = new SyncTestRule() {
@Override
protected FakeProfileSyncService createProfileSyncService() {
return new FakeProfileSyncService();
}
};
@Rule
public JniMocker mJniMocker = new JniMocker();
@Mock
TrustedVaultClient.Natives mTrustedVaultClientNativesMock;
private SettingsActivity mSettingsActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mJniMocker.mock(TrustedVaultClientJni.TEST_HOOKS, mTrustedVaultClientNativesMock);
// Register a mock native for calls to be forwarded to mTrustedVaultClientNativesMock.
TrustedVaultClient.setInstanceForTesting(
new TrustedVaultClient(new FakeTrustedVaultClientBackend()));
TrustedVaultClient.registerNative(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
}
@After
public void tearDown() {
TrustedVaultClient.unregisterNative(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
TrustedVaultClient.setInstanceForTesting(null);
}
/**
* Test that triggering OnPassphraseAccepted dismisses PassphraseDialogFragment.
*/
@Test
@SmallTest
@Feature({"Sync"})
@DisabledTest(message = "https://crbug.com/986243")
public void testPassphraseDialogDismissed() {
final FakeProfileSyncService fakeProfileSyncService =
(FakeProfileSyncService) mSyncTestRule.getProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
// Trigger PassphraseDialogFragment to be shown when taping on Encryption.
fakeProfileSyncService.setPassphraseRequiredForPreferredDataTypes(true);
final ManageSyncSettings fragment = startManageSyncPreferences();
Preference encryption = fragment.findPreference(ManageSyncSettings.PREF_ENCRYPTION);
clickPreference(encryption);
final PassphraseDialogFragment passphraseFragment = ActivityUtils.waitForFragment(
mSettingsActivity, ManageSyncSettings.FRAGMENT_ENTER_PASSPHRASE);
Assert.assertTrue(passphraseFragment.isAdded());
// Simulate OnPassphraseAccepted from external event by setting PassphraseRequired to false
// and triggering syncStateChanged().
// PassphraseDialogFragment should be dismissed.
fakeProfileSyncService.setPassphraseRequiredForPreferredDataTypes(false);
TestThreadUtils.runOnUiThreadBlocking(() -> {
fakeProfileSyncService.syncStateChanged();
fragment.getFragmentManager().executePendingTransactions();
Assert.assertNull("PassphraseDialogFragment should be dismissed.",
mSettingsActivity.getFragmentManager().findFragmentByTag(
ManageSyncSettings.FRAGMENT_ENTER_PASSPHRASE));
});
}
/**
* Test the trusted vault key retrieval flow, which involves launching an intent and finally
* calling TrustedVaultClient.notifyKeysChanged().
*/
@Test
@LargeTest
@Feature({"Sync"})
public void testTrustedVaultKeyRetrieval() {
final FakeProfileSyncService fakeProfileSyncService =
(FakeProfileSyncService) mSyncTestRule.getProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
fakeProfileSyncService.setEngineInitialized(true);
fakeProfileSyncService.setTrustedVaultKeyRequired(true);
final ManageSyncSettings fragment = startManageSyncPreferences();
// Mimic the user tapping on Encryption.
Preference encryption = fragment.findPreference(ManageSyncSettings.PREF_ENCRYPTION);
clickPreference(encryption);
// Wait for DummyKeyRetrievalActivity to finish.
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
// Verify that notifyKeysChanged has been called upon completion.
Mockito.verify(mTrustedVaultClientNativesMock)
.notifyKeysChanged(TRUSTED_VAULT_CLIENT_NATIVE_PTR);
}
private ManageSyncSettings startManageSyncPreferences() {
mSettingsActivity = mSyncTestRule.startSettingsActivity(ManageSyncSettings.class.getName());
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
return (ManageSyncSettings) mSettingsActivity.getMainFragment();
}
private void clickPreference(final Preference pref) {
TestThreadUtils.runOnUiThreadBlockingNoException(
() -> pref.getOnPreferenceClickListener().onPreferenceClick(pref));
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
}
......@@ -244,21 +244,6 @@ public class SyncAndServicesSettingsTest {
Assert.assertNull("Sync error card should not be shown", getSyncErrorCard(fragment));
}
@Test
@LargeTest
@Feature({"Sync", "Preferences"})
public void testTrustedVaultKeyRequiredShowsSyncErrorCard() throws Exception {
final FakeProfileSyncService pss = overrideProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
pss.setEngineInitialized(true);
pss.setTrustedVaultKeyRequiredForPreferredDataTypes(true);
SyncAndServicesSettings fragment = startSyncAndServicesPreferences();
Assert.assertNotNull("Sync error card should be shown", getSyncErrorCard(fragment));
}
/**
* Test: if the onboarding was never shown, the AA chrome preference should not exist.
*
......@@ -357,16 +342,6 @@ public class SyncAndServicesSettingsTest {
ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, newValue);
}
// TODO(crbug.com/1030725): SyncTestRule should support overriding ProfileSyncService.
private FakeProfileSyncService overrideProfileSyncService() {
return TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
// PSS has to be constructed on the UI thread.
FakeProfileSyncService fakeProfileSyncService = new FakeProfileSyncService();
ProfileSyncService.overrideForTests(fakeProfileSyncService);
return fakeProfileSyncService;
});
}
/**
* Start SyncAndServicesSettings signin screen and dissmiss it without pressing confirm or
* cancel.
......
// Copyright 2020 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.sync;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.settings.SettingsActivity;
import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.browser.sync.SyncTestUtil;
/**
* Tests for SyncAndServicesSettings with FakeProfileSyncService.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class SyncAndServicesSettingsWithFakeProfileSyncServiceTest {
@Rule
public SyncTestRule mSyncTestRule = new SyncTestRule() {
@Override
protected FakeProfileSyncService createProfileSyncService() {
return new FakeProfileSyncService();
}
};
@Test
@LargeTest
@Feature({"Sync", "Preferences"})
public void testTrustedVaultKeyRequiredShowsSyncErrorCard() throws Exception {
FakeProfileSyncService fakeProfileSyncService =
(FakeProfileSyncService) mSyncTestRule.getProfileSyncService();
mSyncTestRule.setUpTestAccountAndSignIn();
SyncTestUtil.waitForSyncActive();
fakeProfileSyncService.setEngineInitialized(true);
fakeProfileSyncService.setTrustedVaultKeyRequiredForPreferredDataTypes(true);
SyncAndServicesSettings fragment = startSyncAndServicesPreferences();
Assert.assertNotNull("Sync error card should be shown", getSyncErrorCard(fragment));
}
private SyncAndServicesSettings startSyncAndServicesPreferences() {
SettingsActivity settingsActivity =
mSyncTestRule.startSettingsActivity(SyncAndServicesSettings.class.getName());
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
return (SyncAndServicesSettings) settingsActivity.getMainFragment();
}
private Preference getSyncErrorCard(SyncAndServicesSettings fragment) {
return ((PreferenceCategory) fragment.findPreference(
SyncAndServicesSettings.PREF_SYNC_CATEGORY))
.findPreference(SyncAndServicesSettings.PREF_SYNC_ERROR_CARD);
}
}
......@@ -256,8 +256,13 @@ public class SyncTestRule extends ChromeActivityTestRule<ChromeActivity> {
mFakeServerHelper = FakeServerHelper.get();
});
FakeServerHelper.useFakeServer(mContext);
TestThreadUtils.runOnUiThreadBlocking(
() -> { mProfileSyncService = ProfileSyncService.get(); });
TestThreadUtils.runOnUiThreadBlocking(() -> {
ProfileSyncService profileSyncService = createProfileSyncService();
if (profileSyncService != null) {
ProfileSyncService.overrideForTests(profileSyncService);
}
mProfileSyncService = ProfileSyncService.get();
});
UniqueIdentificationGeneratorFactory.registerGenerator(
UuidBasedUniqueIdentificationGenerator.GENERATOR_ID,
......@@ -335,6 +340,13 @@ public class SyncTestRule extends ChromeActivityTestRule<ChromeActivity> {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
/**
* Returns an instance of ProfileSyncService that can be overridden by subclasses.
*/
protected ProfileSyncService createProfileSyncService() {
return null;
}
private void signinAndEnableSyncInternal(final Account account, boolean setFirstSetupComplete) {
TestThreadUtils.runOnUiThreadBlocking(() -> {
IdentityServicesProvider.get().getSigninManager().signIn(
......
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