// Copyright 2020 The Chromium Authors
// 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.profiles;
import androidx.test.filters.LargeTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.RequiresRestart;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
import org.chromium.components.profile_metrics.BrowserProfileType;
/** This test class checks if incognito and non-incognito OTR profiles can be distinctly created. */
@RunWith(ChromeJUnit4ClassRunner.class)
@Batch(Batch.PER_CLASS)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class ProfileTest {
@ClassRule
public static final ChromeTabbedActivityTestRule sActivityTestRule =
new ChromeTabbedActivityTestRule();
@Rule
public final BlankCTATabInitialStateRule mInitialStateRule =
new BlankCTATabInitialStateRule(sActivityTestRule, false);
public Profile mRegularProfile;
@Before
public void setUp() {
ThreadUtils.runOnUiThreadBlocking(
() -> {
mRegularProfile =
sActivityTestRule
.getActivity()
.getTabModelSelector()
.getModel(false)
.getProfile();
});
}
/** Test if two calls for incognito profile return the same object. */
@Test
@LargeTest
public void testIncognitoProfileConsistency() throws Exception {
Assert.assertNull(mRegularProfile.getOTRProfileID());
// Open an new Incognito Tab page to create a new primary OTR profile.
sActivityTestRule.loadUrlInNewTab("about:blank", true);
Profile incognitoProfile1 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true));
Assert.assertTrue(
"isOffTheRecord should be true for Incognito profiles",
incognitoProfile1.isOffTheRecord());
Assert.assertTrue(
"isIncognitoBranded should be true for Incognito profiles",
incognitoProfile1.isIncognitoBranded());
Assert.assertTrue(
"isPrimaryOTRProfile should be true for Incognito profiles",
incognitoProfile1.isPrimaryOTRProfile());
Assert.assertTrue(
"isNativeInitialized should be true for Incognito profiles",
incognitoProfile1.isNativeInitialized());
Assert.assertTrue(
"The regular profile should be the Incognito profile",
mRegularProfile.hasPrimaryOTRProfile());
Profile incognitoProfile2 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true));
Assert.assertSame(
"Two calls to get incognito profile should return the same object.",
incognitoProfile1,
incognitoProfile2);
}
/** Test if two calls to get non-primary profile with the same id return the same object. */
@Test
@LargeTest
public void testNonPrimaryProfileConsistency() throws Exception {
OTRProfileID profileID = new OTRProfileID("test::OTRProfile");
Profile nonPrimaryOtrProfile1 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID, /* createIfNeeded= */ true));
Assert.assertTrue(
"isOffTheRecord should be true for non-primary OTR profiles",
nonPrimaryOtrProfile1.isOffTheRecord());
Assert.assertFalse(
"isIncognitoBranded should be false for non-primary, non-iCCT OTR profiles",
nonPrimaryOtrProfile1.isIncognitoBranded());
Assert.assertFalse(
"isPrimaryOTRProfile should be false for non-primary OTR profiles",
nonPrimaryOtrProfile1.isPrimaryOTRProfile());
Assert.assertTrue(
"isNativeInitialized should be true for non-primary OTR profiles",
nonPrimaryOtrProfile1.isNativeInitialized());
Assert.assertTrue(
"The regular profile should return the OTR profile from the OTR profile id",
mRegularProfile.hasOffTheRecordProfile(profileID));
Assert.assertFalse(
"hasPrimaryOTRProfile should be false for non-primary, non-incognito profiles",
mRegularProfile.hasPrimaryOTRProfile());
Assert.assertEquals(
"OTR profile id should be returned as it is set.",
nonPrimaryOtrProfile1.getOTRProfileID(),
profileID);
Profile nonPrimaryOtrProfile2 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
new OTRProfileID("test::OTRProfile"),
/* createIfNeeded= */ true));
Assert.assertSame(
"Two calls to get non-primary OTR profile with the same ID "
+ "should return the same object.",
nonPrimaryOtrProfile1,
nonPrimaryOtrProfile2);
}
/** Test if creating two non-primary profiles result in different objects. */
@Test
@LargeTest
public void testCreatingTwoNonPrimaryProfiles() throws Exception {
OTRProfileID profileID1 = new OTRProfileID("test::OTRProfile-1");
Profile nonPrimaryOtrProfile1 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID1, /* createIfNeeded= */ true));
OTRProfileID profileID2 = new OTRProfileID("test::OTRProfile-2");
Profile nonPrimaryOtrProfile2 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID2, /* createIfNeeded= */ true));
Assert.assertTrue(
"isOffTheRecord should be true for non-primary OTR profiles",
nonPrimaryOtrProfile1.isOffTheRecord());
Assert.assertFalse(
"isIncognitoBranded should be false for non-primary, non-iCCT OTR profiles",
nonPrimaryOtrProfile1.isIncognitoBranded());
Assert.assertFalse(
"isPrimaryOTRProfile should be false for non-primary OTR profiles",
nonPrimaryOtrProfile1.isPrimaryOTRProfile());
Assert.assertTrue(
"isNativeInitialized should be true for non-primary OTR profiles",
nonPrimaryOtrProfile1.isNativeInitialized());
Assert.assertTrue(
"The regular profile should return the OTR profile from the OTR profile id",
mRegularProfile.hasOffTheRecordProfile(profileID1));
Assert.assertTrue(
"isOffTheRecord should be true for non-primary OTR profiles",
nonPrimaryOtrProfile2.isOffTheRecord());
Assert.assertFalse(
"isIncognitoBranded should be false for non-primary, non-iCCT OTR profiles",
nonPrimaryOtrProfile2.isIncognitoBranded());
Assert.assertFalse(
"isPrimaryOTRProfile should be false for non-primary OTR profiles",
nonPrimaryOtrProfile2.isPrimaryOTRProfile());
Assert.assertTrue(
"isNativeInitialized should be true for non-primary OTR profiles",
nonPrimaryOtrProfile2.isNativeInitialized());
Assert.assertTrue(
"The regular profile should return the OTR profile from the OTR profile id",
mRegularProfile.hasOffTheRecordProfile(profileID2));
Assert.assertNotSame(
"Two calls to get non-primary OTR profile with different IDs"
+ "should return different objects.",
nonPrimaryOtrProfile1,
nonPrimaryOtrProfile2);
}
/** Test if creating unique otr profile ids works as expected. */
@Test
@LargeTest
public void testCreatingUniqueOTRProfileIDs() throws Exception {
ThreadUtils.runOnUiThreadBlocking(
() -> {
OTRProfileID profileID1 = OTRProfileID.createUnique("test::OTRProfile");
OTRProfileID profileID2 = OTRProfileID.createUnique("test::OTRProfile");
Assert.assertNotSame(
"Two calls to OTRProfileID.CreateUnique with the same prefix"
+ "should return different objects.",
profileID1,
profileID2);
});
}
/** Test if creating unique iCCT profile ids works as expected. */
@Test
@LargeTest
public void testCreatingUniqueIncognitoCCTOTRProfileIDs() throws Exception {
ThreadUtils.runOnUiThreadBlocking(
() -> {
OTRProfileID incognitoCCTId1 = OTRProfileID.createUniqueIncognitoCCTId();
OTRProfileID incognitoCCTId2 = OTRProfileID.createUniqueIncognitoCCTId();
Assert.assertNotSame(
"Two calls to OTRProfileID.createUniqueIncognitoCCTId"
+ "should return different objects.",
incognitoCCTId1,
incognitoCCTId2);
Assert.assertTrue(incognitoCCTId1.isIncognitoCCId());
Assert.assertTrue(incognitoCCTId2.isIncognitoCCId());
});
}
/** Tests creating iCCT profile. */
@Test
@LargeTest
public void testIncognitoCCTProfileCreation() throws Exception {
OTRProfileID incognitoCCTId = OTRProfileID.createUniqueIncognitoCCTId();
Profile incognitoCCTProfile =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
incognitoCCTId, /* createIfNeeded= */ true));
Assert.assertTrue(
"isOffTheRecord should be true for Incognito CCT profiles",
incognitoCCTProfile.isOffTheRecord());
Assert.assertTrue(
"isIncognitoBranded should be true for Incognito CCT profiles",
incognitoCCTProfile.isIncognitoBranded());
Assert.assertFalse(
"isPrimaryOTRProfile should be false for Incognito CCT profiles",
incognitoCCTProfile.isPrimaryOTRProfile());
Assert.assertTrue(
"isNativeInitialized should be true for Incognito CCT profiles",
incognitoCCTProfile.isNativeInitialized());
Assert.assertTrue(
"The regular profile should return the Incognito CCT profile from the OTR profile"
+ " id",
mRegularProfile.hasOffTheRecordProfile(incognitoCCTId));
}
@Test
@LargeTest
public void testBrowserProfileTypeFromRegularProfile() throws Exception {
ThreadUtils.runOnUiThreadBlocking(
() -> {
Assert.assertEquals(
BrowserProfileType.REGULAR,
Profile.getBrowserProfileTypeFromProfile(mRegularProfile));
});
}
@Test
@LargeTest
public void testBrowserProfileTypeFromPrimaryOTRProfile() throws Exception {
// Open an new Incognito Tab page to create a new primary OTR profile.
sActivityTestRule.loadUrlInNewTab("about:blank", true);
ThreadUtils.runOnUiThreadBlocking(
() -> {
Profile primaryOTRProfile =
mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true);
Assert.assertEquals(
BrowserProfileType.INCOGNITO,
Profile.getBrowserProfileTypeFromProfile(primaryOTRProfile));
});
}
@Test
@LargeTest
public void testBrowserProfileTypeFromNonPrimaryOTRProfile() throws Exception {
ThreadUtils.runOnUiThreadBlocking(
() -> {
OTRProfileID otrProfileID = new OTRProfileID("test::OTRProfile");
Profile nonPrimaryOtrProfile =
mRegularProfile.getOffTheRecordProfile(
otrProfileID, /* createIfNeeded= */ true);
Assert.assertEquals(
BrowserProfileType.OTHER_OFF_THE_RECORD_PROFILE,
Profile.getBrowserProfileTypeFromProfile(nonPrimaryOtrProfile));
});
}
/** Tests createIfNeeded parameter of getOffTheRecordProfile. */
@Test
@LargeTest
@RequiresRestart(
"crbug/1161449 - Other tests create profiles which invalidate the first assertion.")
public void testGetOffTheRecordProfile() throws Exception {
OTRProfileID profileID = new OTRProfileID("test::OTRProfile");
// Ask for a non-existing profile with createIfNeeded set to false, and exepct null.
Profile profile1 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID, /* createIfNeeded= */ false));
Assert.assertNull(profile1);
Assert.assertFalse(mRegularProfile.hasOffTheRecordProfile(profileID));
// Ask for a non-existing profile with createIfNeeded set to true and expect creation.
Profile profile2 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID, /* createIfNeeded= */ true));
Assert.assertNotNull(profile2);
Assert.assertTrue(mRegularProfile.hasOffTheRecordProfile(profileID));
// Ask for an existing profile with createIfNeeded set to false and expect getting the
// existing profile.
Profile profile3 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID, /* createIfNeeded= */ false));
Assert.assertNotNull(profile3);
Assert.assertSame(profile2, profile3);
// Ask for an existing profile with createIfNeeded set to true and expect getting the
// existing profile.
Profile profile4 =
ThreadUtils.runOnUiThreadBlocking(
() ->
mRegularProfile.getOffTheRecordProfile(
profileID, /* createIfNeeded= */ true));
Assert.assertNotNull(profile4);
Assert.assertSame(profile2, profile4);
}
/** Tests createIfNeeded parameter of getPrimaryOTRProfile. */
@Test
@LargeTest
public void testGetPrimaryOTRProfile() throws Exception {
// Ask for a non-existing profile with createIfNeeded set to false, and exepct null.
Profile profile1 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ false));
Assert.assertNull(profile1);
Assert.assertFalse(mRegularProfile.hasPrimaryOTRProfile());
// Ask for a non-existing profile with createIfNeeded set to true and expect creation.
Profile profile2 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true));
Assert.assertNotNull(profile2);
Assert.assertTrue(mRegularProfile.hasPrimaryOTRProfile());
// Ask for an existing profile with createIfNeeded set to false and expect getting the
// existing profile.
Profile profile3 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ false));
Assert.assertNotNull(profile3);
Assert.assertSame(profile2, profile3);
// Ask for an existing profile with createIfNeeded set to true and expect getting the
// existing profile.
Profile profile4 =
ThreadUtils.runOnUiThreadBlocking(
() -> mRegularProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true));
Assert.assertNotNull(profile4);
Assert.assertSame(profile2, profile4);
}
}