1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/signin/account_consistency_mode_manager.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/command_line.h"
11 #include "base/test/scoped_command_line.h"
12 #include "build/build_config.h"
13 #include "build/buildflag.h"
14 #include "chrome/browser/prefs/browser_prefs.h"
15 #include "chrome/browser/supervised_user/supervised_user_constants.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "components/prefs/pref_notifier_impl.h"
19 #include "components/prefs/testing_pref_store.h"
20 #include "components/signin/public/base/account_consistency_method.h"
21 #include "components/signin/public/base/signin_buildflags.h"
22 #include "components/signin/public/base/signin_pref_names.h"
23 #include "components/sync_preferences/testing_pref_service_syncable.h"
24 #include "content/public/test/browser_task_environment.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 
27 namespace {
28 
BuildTestingProfile(bool is_new_profile)29 std::unique_ptr<TestingProfile> BuildTestingProfile(bool is_new_profile) {
30   TestingProfile::Builder profile_builder;
31   profile_builder.OverrideIsNewProfile(is_new_profile);
32   std::unique_ptr<TestingProfile> profile = profile_builder.Build();
33   EXPECT_EQ(is_new_profile, profile->IsNewProfile());
34   return profile;
35 }
36 
37 }  // namespace
38 
39 // Check the default account consistency method.
TEST(AccountConsistencyModeManagerTest,DefaultValue)40 TEST(AccountConsistencyModeManagerTest, DefaultValue) {
41   content::BrowserTaskEnvironment task_environment;
42   std::unique_ptr<TestingProfile> profile =
43       BuildTestingProfile(/*is_new_profile=*/false);
44 
45 #if BUILDFLAG(ENABLE_MIRROR) || defined(OS_CHROMEOS)
46   EXPECT_EQ(signin::AccountConsistencyMethod::kMirror,
47             AccountConsistencyModeManager::GetMethodForProfile(profile.get()));
48   EXPECT_TRUE(
49       AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile.get()));
50   EXPECT_FALSE(
51       AccountConsistencyModeManager::IsDiceEnabledForProfile(profile.get()));
52 #elif BUILDFLAG(ENABLE_DICE_SUPPORT)
53   EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
54             AccountConsistencyModeManager::GetMethodForProfile(profile.get()));
55   EXPECT_FALSE(
56       AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile.get()));
57   EXPECT_TRUE(
58       AccountConsistencyModeManager::IsDiceEnabledForProfile(profile.get()));
59 #else
60 #error Either Dice or Mirror should be enabled
61 #endif
62 }
63 
64 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
65 // Checks that changing the signin-allowed pref changes the Dice state on next
66 // startup.
TEST(AccountConsistencyModeManagerTest,SigninAllowedChangesDiceState)67 TEST(AccountConsistencyModeManagerTest, SigninAllowedChangesDiceState) {
68   content::BrowserTaskEnvironment task_environment;
69   std::unique_ptr<TestingProfile> profile =
70       BuildTestingProfile(/*is_new_profile=*/false);
71 
72   {
73     // First startup.
74     AccountConsistencyModeManager manager(profile.get());
75     EXPECT_TRUE(profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
76     EXPECT_TRUE(
77         profile->GetPrefs()->GetBoolean(prefs::kSigninAllowedOnNextStartup));
78     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
79               manager.GetAccountConsistencyMethod());
80 
81     // User changes their settings.
82     profile->GetPrefs()->SetBoolean(prefs::kSigninAllowedOnNextStartup, false);
83     // Dice should remain in the same state until restart.
84     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
85               manager.GetAccountConsistencyMethod());
86   }
87 
88   {
89     // Second startup.
90     AccountConsistencyModeManager manager(profile.get());
91     // The signin-allowed pref should be disabled.
92     EXPECT_FALSE(profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
93     EXPECT_FALSE(
94         profile->GetPrefs()->GetBoolean(prefs::kSigninAllowedOnNextStartup));
95     // Dice should be disabled.
96     EXPECT_EQ(signin::AccountConsistencyMethod::kDisabled,
97               manager.GetAccountConsistencyMethod());
98   }
99 }
100 
TEST(AccountConsistencyModeManagerTest,AllowBrowserSigninSwitch)101 TEST(AccountConsistencyModeManagerTest, AllowBrowserSigninSwitch) {
102   content::BrowserTaskEnvironment task_environment;
103   std::unique_ptr<TestingProfile> profile =
104       BuildTestingProfile(/*is_new_profile=*/false);
105   {
106     base::test::ScopedCommandLine scoped_command_line;
107     scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
108         "allow-browser-signin", "false");
109     AccountConsistencyModeManager manager(profile.get());
110     EXPECT_FALSE(profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
111     // Dice should be disabled.
112     EXPECT_EQ(signin::AccountConsistencyMethod::kDisabled,
113               manager.GetAccountConsistencyMethod());
114   }
115 
116   {
117     base::test::ScopedCommandLine scoped_command_line;
118     scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
119         "allow-browser-signin", "true");
120     AccountConsistencyModeManager manager(profile.get());
121     EXPECT_TRUE(profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
122     // Dice should be enabled.
123     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
124               manager.GetAccountConsistencyMethod());
125   }
126 
127   {
128     AccountConsistencyModeManager manager(profile.get());
129     EXPECT_TRUE(profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
130     EXPECT_TRUE(
131         profile->GetPrefs()->GetBoolean(prefs::kSigninAllowedOnNextStartup));
132     // Dice should be enabled.
133     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
134               manager.GetAccountConsistencyMethod());
135   }
136 }
137 
138 // Checks that Dice migration happens when the manager is created.
TEST(AccountConsistencyModeManagerTest,MigrateAtCreation)139 TEST(AccountConsistencyModeManagerTest, MigrateAtCreation) {
140   content::BrowserTaskEnvironment task_environment;
141   std::unique_ptr<TestingProfile> profile =
142       BuildTestingProfile(/*is_new_profile=*/false);
143   AccountConsistencyModeManager manager(profile.get());
144   EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
145             manager.GetAccountConsistencyMethod());
146 }
147 
TEST(AccountConsistencyModeManagerTest,ForceDiceMigration)148 TEST(AccountConsistencyModeManagerTest, ForceDiceMigration) {
149   content::BrowserTaskEnvironment task_environment;
150   std::unique_ptr<TestingProfile> profile =
151       BuildTestingProfile(/*is_new_profile=*/false);
152   profile->GetPrefs()->SetBoolean(prefs::kTokenServiceDiceCompatible, true);
153   AccountConsistencyModeManager manager(profile.get());
154   EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
155             manager.GetAccountConsistencyMethod());
156   // Migration is not completed yet, |kDiceMigrationCompletePref| should not
157   // be written.
158   EXPECT_FALSE(manager.IsDiceMigrationCompleted(profile.get()));
159   manager.SetDiceMigrationCompleted();
160   EXPECT_TRUE(manager.IsDiceMigrationCompleted(profile.get()));
161 }
162 
163 // Checks that new profiles are migrated at creation.
TEST(AccountConsistencyModeManagerTest,NewProfile)164 TEST(AccountConsistencyModeManagerTest, NewProfile) {
165   content::BrowserTaskEnvironment task_environment;
166   std::unique_ptr<TestingProfile> profile =
167       BuildTestingProfile(/*is_new_profile=*/true);
168   EXPECT_TRUE(
169       AccountConsistencyModeManager::IsDiceEnabledForProfile(profile.get()));
170   EXPECT_TRUE(
171       AccountConsistencyModeManager::IsDiceMigrationCompleted(profile.get()));
172 }
173 
TEST(AccountConsistencyModeManagerTest,DiceOnlyForRegularProfile)174 TEST(AccountConsistencyModeManagerTest, DiceOnlyForRegularProfile) {
175   content::BrowserTaskEnvironment task_environment;
176 
177   {
178     // Regular profile.
179     TestingProfile profile;
180     EXPECT_TRUE(
181         AccountConsistencyModeManager::IsDiceEnabledForProfile(&profile));
182     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
183               AccountConsistencyModeManager::GetMethodForProfile(&profile));
184     EXPECT_TRUE(
185         AccountConsistencyModeManager::ShouldBuildServiceForProfile(&profile));
186 
187     // Incognito profile.
188     Profile* incognito_profile = profile.GetPrimaryOTRProfile();
189     EXPECT_FALSE(AccountConsistencyModeManager::IsDiceEnabledForProfile(
190         incognito_profile));
191     EXPECT_FALSE(
192         AccountConsistencyModeManager::GetForProfile(incognito_profile));
193     EXPECT_EQ(
194         signin::AccountConsistencyMethod::kDisabled,
195         AccountConsistencyModeManager::GetMethodForProfile(incognito_profile));
196     EXPECT_FALSE(AccountConsistencyModeManager::ShouldBuildServiceForProfile(
197         incognito_profile));
198 
199     // Non-primary off-the-record profile.
200     Profile* otr_profile = profile.GetOffTheRecordProfile(
201         Profile::OTRProfileID("Test::AccountConsistency"));
202     EXPECT_FALSE(
203         AccountConsistencyModeManager::IsDiceEnabledForProfile(otr_profile));
204     EXPECT_FALSE(AccountConsistencyModeManager::GetForProfile(otr_profile));
205     EXPECT_EQ(signin::AccountConsistencyMethod::kDisabled,
206               AccountConsistencyModeManager::GetMethodForProfile(otr_profile));
207     EXPECT_FALSE(AccountConsistencyModeManager::ShouldBuildServiceForProfile(
208         otr_profile));
209   }
210 
211   {
212     // Guest profile.
213     TestingProfile::Builder profile_builder;
214     profile_builder.SetGuestSession();
215     std::unique_ptr<Profile> profile = profile_builder.Build();
216     ASSERT_TRUE(profile->IsGuestSession());
217     EXPECT_FALSE(
218         AccountConsistencyModeManager::IsDiceEnabledForProfile(profile.get()));
219     EXPECT_EQ(
220         signin::AccountConsistencyMethod::kDisabled,
221         AccountConsistencyModeManager::GetMethodForProfile(profile.get()));
222     EXPECT_FALSE(AccountConsistencyModeManager::ShouldBuildServiceForProfile(
223         profile.get()));
224   }
225 
226   {
227     // Legacy supervised profile.
228     TestingProfile::Builder profile_builder;
229     profile_builder.SetSupervisedUserId("supervised_id");
230     std::unique_ptr<Profile> profile = profile_builder.Build();
231     ASSERT_TRUE(profile->IsLegacySupervised());
232     EXPECT_FALSE(
233         AccountConsistencyModeManager::IsDiceEnabledForProfile(profile.get()));
234     EXPECT_EQ(
235         signin::AccountConsistencyMethod::kDisabled,
236         AccountConsistencyModeManager::GetMethodForProfile(profile.get()));
237   }
238 }
239 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
240 
241 #if defined(OS_CHROMEOS)
242 // Mirror is enabled by default on Chrome OS, unless specified otherwise.
TEST(AccountConsistencyModeManagerTest,MirrorEnabledByDefault)243 TEST(AccountConsistencyModeManagerTest, MirrorEnabledByDefault) {
244   // Creation of this object sets the current thread's id as UI thread.
245   content::BrowserTaskEnvironment task_environment;
246 
247   TestingProfile profile;
248   EXPECT_TRUE(
249       AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile));
250   EXPECT_FALSE(
251       AccountConsistencyModeManager::IsDiceEnabledForProfile(&profile));
252   EXPECT_EQ(signin::AccountConsistencyMethod::kMirror,
253             AccountConsistencyModeManager::GetMethodForProfile(&profile));
254 }
255 
TEST(AccountConsistencyModeManagerTest,MirrorDisabledForGuestSession)256 TEST(AccountConsistencyModeManagerTest, MirrorDisabledForGuestSession) {
257   // Creation of this object sets the current thread's id as UI thread.
258   content::BrowserTaskEnvironment task_environment;
259 
260   TestingProfile profile;
261   profile.SetGuestSession(true);
262   EXPECT_FALSE(
263       AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile));
264   EXPECT_FALSE(
265       AccountConsistencyModeManager::IsDiceEnabledForProfile(&profile));
266   EXPECT_EQ(signin::AccountConsistencyMethod::kDisabled,
267             AccountConsistencyModeManager::GetMethodForProfile(&profile));
268 }
269 
TEST(AccountConsistencyModeManagerTest,MirrorDisabledForOffTheRecordProfile)270 TEST(AccountConsistencyModeManagerTest, MirrorDisabledForOffTheRecordProfile) {
271   // Creation of this object sets the current thread's id as UI thread.
272   content::BrowserTaskEnvironment task_environment;
273 
274   TestingProfile profile;
275   Profile* incognito_profile = profile.GetPrimaryOTRProfile();
276   EXPECT_FALSE(AccountConsistencyModeManager::IsMirrorEnabledForProfile(
277       incognito_profile));
278   EXPECT_FALSE(AccountConsistencyModeManager::IsDiceEnabledForProfile(
279       incognito_profile));
280   EXPECT_EQ(
281       signin::AccountConsistencyMethod::kDisabled,
282       AccountConsistencyModeManager::GetMethodForProfile(incognito_profile));
283 
284   Profile* otr_profile = profile.GetOffTheRecordProfile(
285       Profile::OTRProfileID("Test::AccountConsistency"));
286   EXPECT_FALSE(
287       AccountConsistencyModeManager::IsMirrorEnabledForProfile(otr_profile));
288   EXPECT_FALSE(
289       AccountConsistencyModeManager::IsDiceEnabledForProfile(otr_profile));
290   EXPECT_EQ(signin::AccountConsistencyMethod::kDisabled,
291             AccountConsistencyModeManager::GetMethodForProfile(otr_profile));
292 }
293 #endif  // defined(OS_CHROMEOS)
294 
295 #if BUILDFLAG(ENABLE_MIRROR)
296 // Test that Mirror is enabled for child accounts.
TEST(AccountConsistencyModeManagerTest,MirrorChildAccount)297 TEST(AccountConsistencyModeManagerTest, MirrorChildAccount) {
298   content::BrowserTaskEnvironment task_environment;
299   TestingProfile profile;
300   profile.SetSupervisedUserId(supervised_users::kChildAccountSUID);
301   EXPECT_TRUE(
302       AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile));
303   EXPECT_FALSE(
304       AccountConsistencyModeManager::IsDiceEnabledForProfile(&profile));
305   EXPECT_EQ(signin::AccountConsistencyMethod::kMirror,
306             AccountConsistencyModeManager::GetMethodForProfile(&profile));
307 }
308 #endif  // BUILDFLAG(ENABLE_MIRROR)
309