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

Side by Side Diff: chrome/browser/signin/cross_device_promo_unittest.cc

Issue 1087933002: Cross Device Promo - Main Eligibility Flow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format Created 5 years, 7 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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/cross_device_promo.h"
6
7 #include "base/metrics/field_trial.h"
8 #include "base/run_loop.h"
9 #include "base/test/histogram_tester.h"
10 #include "chrome/browser/prefs/browser_prefs.h"
11 #include "chrome/browser/prefs/pref_service_syncable.h"
12 #include "chrome/browser/signin/chrome_signin_client_factory.h"
13 #include "chrome/browser/signin/cross_device_promo_factory.h"
14 #include "chrome/browser/signin/fake_gaia_cookie_manager_service.h"
15 #include "chrome/browser/signin/fake_signin_manager.h"
16 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/browser/signin/test_signin_client_builder.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_browser_process.h"
21 #include "chrome/test/base/testing_pref_service_syncable.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/signin/core/browser/signin_manager.h"
25 #include "components/signin/core/browser/signin_metrics.h"
26 #include "components/signin/core/browser/test_signin_client.h"
27 #include "components/variations/entropy_provider.h"
28 #include "components/variations/variations_associated_data.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "google_apis/gaia/gaia_urls.h"
31 #include "net/url_request/test_url_fetcher_factory.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 namespace {
35
36 int64 InOneHour() {
37 return (base::Time::Now() + base::TimeDelta::FromHours(1)).ToInternalValue();
38 }
39
40 } // namespace
41
42 class CrossDevicePromoObserver : public CrossDevicePromo::Observer {
43 public:
44 explicit CrossDevicePromoObserver(CrossDevicePromo* promo)
45 : active_(false), set_active_(0), set_inactive_(0), promo_(promo) {
46 promo->AddObserver(this);
47 }
48
49 ~CrossDevicePromoObserver() { promo_->RemoveObserver(this); }
50
51 void OnPromoActivationChanged(bool active) override {
52 active_ = active;
53 active ? set_active_++ : set_inactive_++;
Alexei Svitkine (slow) 2015/05/19 17:10:37 Just use an if.
Mike Lerman 2015/05/19 18:17:34 Really? so much longer! but ok.
54 }
55
56 bool IsActive() { return active_; }
Alexei Svitkine (slow) 2015/05/19 17:10:37 Nit: Just use a hacker_style accessor - is_active(
Mike Lerman 2015/05/19 18:17:34 Done. The others are now times_set_active and time
57 int TimesBecameActive() { return set_active_; }
58 int TimesBecameInactive() { return set_inactive_; }
59
60 private:
61 bool active_;
62 int set_active_;
63 int set_inactive_;
64 CrossDevicePromo* promo_;
65
66 DISALLOW_COPY_AND_ASSIGN(CrossDevicePromoObserver);
67 };
68
69 class CrossDevicePromoTest : public ::testing::Test {
70 public:
71 CrossDevicePromoTest();
72 void SetUp() override;
73
74 void ResetFieldTrialList();
75
76 CrossDevicePromo* promo() { return cross_device_promo_; }
77 TestingProfile* profile() { return profile_; }
78 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
79 base::HistogramTester* histogram_tester() { return &histogram_tester_; }
80 TestingPrefServiceSyncable* prefs() { return pref_service_; }
81 FakeGaiaCookieManagerService* cookie_manager_service() {
82 return cookie_manager_service_;
83 }
84 net::FakeURLFetcherFactory* fetcher_factory() {
85 return &fake_url_fetcher_factory_;
86 }
87
88 void InitPromoVariation() {
89 std::map<std::string, std::string> variations_params;
90 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
91 variations_params["DaysToVerifySingleUserProfile"] = "0";
92 variations_params["MinutesBetweenBrowsingSessions"] = "0";
93 variations_params["MinutesMaxContextSwitchDuration"] = "10";
94 variations_params["RPCThrottle"] = "0";
95 EXPECT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
96 variations_params));
97 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
98 }
99
100 private:
101 content::TestBrowserThreadBundle bundle_;
102 CrossDevicePromo* cross_device_promo_;
103 TestingProfile* profile_;
104 FakeSigninManagerForTesting* signin_manager_;
105 FakeGaiaCookieManagerService* cookie_manager_service_;
106 TestingPrefServiceSyncable* pref_service_;
107 scoped_ptr<TestingProfileManager> testing_profile_manager_;
108 base::HistogramTester histogram_tester_;
109 scoped_ptr<base::FieldTrialList> field_trial_list_;
110 net::FakeURLFetcherFactory fake_url_fetcher_factory_;
111
112 DISALLOW_COPY_AND_ASSIGN(CrossDevicePromoTest);
113 };
114
115 void CrossDevicePromoTest::SetUp() {
116 testing_profile_manager_.reset(
117 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
118 ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
119
120 TestingProfile::TestingFactories factories;
121 factories.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
122 signin::BuildTestSigninClient));
123 factories.push_back(
124 std::make_pair(GaiaCookieManagerServiceFactory::GetInstance(),
125 FakeGaiaCookieManagerService::Build));
126 factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
127 FakeSigninManagerBase::Build));
128
129 pref_service_ = new TestingPrefServiceSyncable();
130 chrome::RegisterUserProfilePrefs(pref_service_->registry());
131
132 profile_ = testing_profile_manager_.get()->CreateTestingProfile(
133 "name", make_scoped_ptr<PrefServiceSyncable>(pref_service_),
134 base::UTF8ToUTF16("name"), 0, std::string(), factories);
135
136 cookie_manager_service_ = static_cast<FakeGaiaCookieManagerService*>(
137 GaiaCookieManagerServiceFactory::GetForProfile(profile()));
138 cookie_manager_service_->Init(&fake_url_fetcher_factory_);
139
140 signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
141 SigninManagerFactory::GetForProfile(profile()));
142 cross_device_promo_ = CrossDevicePromoFactory::GetForProfile(profile());
143 }
144
145 CrossDevicePromoTest::CrossDevicePromoTest() : fake_url_fetcher_factory_(NULL) {
146 ResetFieldTrialList();
147 }
148
149 void CrossDevicePromoTest::ResetFieldTrialList() {
150 // Destroy the existing FieldTrialList before creating a new one to avoid
151 // a DCHECK.
152 field_trial_list_.reset();
153 field_trial_list_.reset(
154 new base::FieldTrialList(new metrics::SHA1EntropyProvider("foo")));
155 variations::testing::ClearAllVariationParams();
156 }
157
158 TEST_F(CrossDevicePromoTest, Uninitialized) {
159 ASSERT_TRUE(promo());
160 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
161 signin_metrics::NO_VARIATIONS_CONFIG,
162 1);
163
164 promo()->CheckPromoEligibilityForTesting();
165 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
166 signin_metrics::NO_VARIATIONS_CONFIG,
167 2);
168 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
169 ASSERT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
170 }
171
172 TEST_F(CrossDevicePromoTest, UnitializedOptedOut) {
173 CrossDevicePromoObserver observer(promo());
174
175 promo()->OptOut();
176 // Opting out doesn't de-activate a never-active promo.
177 ASSERT_EQ(0, observer.TimesBecameInactive());
178 ASSERT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
179
180 // Never initialize a promo that is opted out.
181 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
182 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
183 signin_metrics::NO_VARIATIONS_CONFIG,
184 1);
185 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
186 signin_metrics::UNINITIALIZED_OPTED_OUT,
187 1);
188 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
189 }
190
191 TEST_F(CrossDevicePromoTest, PartiallyInitialized) {
192 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
193 signin_metrics::NO_VARIATIONS_CONFIG,
194 1);
195
196 std::map<std::string, std::string> variations_params;
197 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
198 variations_params["DaysToVerifySingleUserProfile"] = "1";
199 ASSERT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
200 variations_params));
201 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
202
203 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
204 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
205 signin_metrics::NO_VARIATIONS_CONFIG,
206 2);
207 ASSERT_FALSE(histogram_tester()->GetHistogramSamplesSinceCreation(
208 "Signin.XDevicePromo.Eligibility"));
209 }
210
211 TEST_F(CrossDevicePromoTest, FullyInitialized) {
212 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
213 signin_metrics::NO_VARIATIONS_CONFIG,
214 1);
215
216 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
217 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
218 signin_metrics::NO_VARIATIONS_CONFIG,
219 2);
220
221 InitPromoVariation();
222 signin_manager()->SignIn("12345", "foo@bar.com", "password");
223 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
224 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
225 signin_metrics::INITIALIZED, 1);
226 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
227 signin_metrics::NO_VARIATIONS_CONFIG,
228 2);
229
230 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
231 signin_metrics::SIGNED_IN, 1);
232 }
233
234 TEST_F(CrossDevicePromoTest, InitializedOptOut) {
235 // In a normal browser, the variations get set before the CrossDevicePromo is
236 // created. Here, we need to force another Init() by calling
237 // CheckPromoEligibilityForTesting().
238 InitPromoVariation();
239 signin_manager()->SignIn("12345", "foo@bar.com", "password");
240 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
241
242 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
243 signin_metrics::INITIALIZED, 1);
244 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
245 signin_metrics::SIGNED_IN, 1);
246
247 // After opting out the initialized state remains; eligibility changes.
248 promo()->OptOut();
249 promo()->CheckPromoEligibilityForTesting();
250 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
251 signin_metrics::INITIALIZED, 1);
252 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Eligibility",
253 signin_metrics::OPTED_OUT, 1);
254 }
255
256 TEST_F(CrossDevicePromoTest, SignedInAndOut) {
257 InitPromoVariation();
258
259 {
260 base::HistogramTester test_signed_in;
261 signin_manager()->SignIn("12345", "foo@bar.com", "password");
262 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
263 test_signed_in.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
264 signin_metrics::SIGNED_IN, 1);
265 }
266
267 {
268 base::HistogramTester test_signed_out;
269 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
270 promo()->CheckPromoEligibilityForTesting();
271 test_signed_out.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
272 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT,
273 1);
274 }
275 }
276
277 TEST_F(CrossDevicePromoTest, TrackAccountsInCookie) {
278 InitPromoVariation();
279 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
280
281 ASSERT_FALSE(prefs()->HasPrefPath(
282 prefs::kCrossDevicePromoObservedSingleAccountCookie));
283 std::vector<std::pair<std::string, bool>> accounts;
284
285 // Setting a single cookie sets the time.
286 base::Time before_setting_cookies = base::Time::Now();
287 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
288 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
289 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
290 base::RunLoop().RunUntilIdle();
291
292 base::Time after_setting_cookies = base::Time::Now();
293 ASSERT_TRUE(prefs()->HasPrefPath(
294 prefs::kCrossDevicePromoObservedSingleAccountCookie));
295 ASSERT_LE(
296 before_setting_cookies.ToInternalValue(),
297 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
298 ASSERT_GE(
299 after_setting_cookies.ToInternalValue(),
300 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
301
302 // A single cookie a second time doesn't change the time.
303 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
304 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
305 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
306 base::RunLoop().RunUntilIdle();
307
308 ASSERT_TRUE(prefs()->HasPrefPath(
309 prefs::kCrossDevicePromoObservedSingleAccountCookie));
310 ASSERT_GE(
311 after_setting_cookies.ToInternalValue(),
312 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
313
314 // Setting accounts with an auth error doesn't change the time.
315 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
316 cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
317 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
318 base::RunLoop().RunUntilIdle();
319
320 ASSERT_TRUE(prefs()->HasPrefPath(
321 prefs::kCrossDevicePromoObservedSingleAccountCookie));
322 ASSERT_LE(
323 before_setting_cookies.ToInternalValue(),
324 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
325 ASSERT_GE(
326 after_setting_cookies.ToInternalValue(),
327 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
328
329 // Seeing zero accounts clears the pref.
330 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
331 cookie_manager_service()->SetListAccountsResponseNoAccounts();
332 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
333 base::RunLoop().RunUntilIdle();
334
335 ASSERT_FALSE(prefs()->HasPrefPath(
336 prefs::kCrossDevicePromoObservedSingleAccountCookie));
337 }
338
339 TEST_F(CrossDevicePromoTest, SingleAccountEligibility) {
340 InitPromoVariation();
341
342 {
343 base::HistogramTester test_single_account;
344 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
345 test_single_account.ExpectUniqueSample(
346 "Signin.XDevicePromo.Eligibility",
347 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
348 }
349
350 // Notice a single account.
351 {
352 base::HistogramTester test_single_account;
353 std::vector<std::pair<std::string, bool>> accounts;
354 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
355 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
356 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
357 base::RunLoop().RunUntilIdle();
358
359 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
360 test_single_account.ExpectUniqueSample(
361 "Signin.XDevicePromo.Eligibility",
362 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
363 }
364
365 // Set a single account that hasn't been around for "long enough".
366 {
367 base::HistogramTester test_single_account;
368 prefs()->SetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie,
369 InOneHour());
370 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
371 test_single_account.ExpectBucketCount(
372 "Signin.XDevicePromo.Eligibility",
373 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
374 }
375 }
376
377 TEST_F(CrossDevicePromoTest, NumDevicesEligibility) {
378 // Start with a variation, signed in, and one account in the cookie jar.
379 InitPromoVariation();
380 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
381 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
382 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
383 std::vector<std::pair<std::string, bool>> accounts;
384 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
385 base::RunLoop().RunUntilIdle();
386
387 // Ensure we appropriate schedule a check for listing devices.
388 {
389 base::HistogramTester test_missing_list_devices;
390 int64 earliest_time_to_check_list_devices =
391 base::Time::Now().ToInternalValue();
392 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
393 int64 latest_time_to_check_list_devices = InOneHour();
394 test_missing_list_devices.ExpectUniqueSample(
395 "Signin.XDevicePromo.Eligibility",
396 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
397 EXPECT_TRUE(
398 prefs()->HasPrefPath(prefs::kCrossDevicePromoNextFetchListDevicesTime));
399 int64 when_to_check_list_devices =
400 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime);
401 EXPECT_LT(earliest_time_to_check_list_devices, when_to_check_list_devices);
402 EXPECT_GT(latest_time_to_check_list_devices, when_to_check_list_devices);
403 }
404
405 // Don't reschedule the list devices check if there's one pending.
406 {
407 base::HistogramTester test_unknown_devices;
408 int64 list_devices_time = InOneHour();
409 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
410 list_devices_time);
411 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
412 test_unknown_devices.ExpectUniqueSample(
413 "Signin.XDevicePromo.Eligibility",
414 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
415 // The scheduled time to call ListDevices should not have changed.
416 ASSERT_EQ(
417 list_devices_time,
418 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
419 }
420
421 // Execute the list devices check if it's time.
422 {
423 base::HistogramTester test_unknown_devices;
424 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
425 base::Time::Now().ToInternalValue());
426 // The DeviceActivityFetcher will return an error to the promo service.
427 fetcher_factory()->SetFakeResponse(
428 GaiaUrls::GetInstance()->oauth2_iframe_url(), "not json", net::HTTP_OK,
429 net::URLRequestStatus::SUCCESS);
430 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
431 base::RunLoop().RunUntilIdle();
432 test_unknown_devices.ExpectUniqueSample(
433 "Signin.XDevicePromo.Eligibility",
434 signin_metrics::ERROR_FETCHING_DEVICE_ACTIVITY, 1);
435 }
436 }
437
438 TEST_F(CrossDevicePromoTest, ThrottleDeviceActivityCall) {
439 // Start with a variation (fully throttled), signed in, one account in cookie.
440 std::map<std::string, std::string> variations_params;
441 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
442 variations_params["DaysToVerifySingleUserProfile"] = "0";
443 variations_params["MinutesBetweenBrowsingSessions"] = "0";
444 variations_params["MinutesMaxContextSwitchDuration"] = "10";
445 variations_params["RPCThrottle"] = "101";
446 EXPECT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
447 variations_params));
448 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
449
450 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
451 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
452 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
453 std::vector<std::pair<std::string, bool>> accounts;
454 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
455 base::RunLoop().RunUntilIdle();
456
457 // Ensure Device Activity Fetch gets throttled.
458 {
459 base::HistogramTester test_throttle_rpc;
460 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
461 base::Time::Now().ToInternalValue());
462 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
463 test_throttle_rpc.ExpectUniqueSample(
464 "Signin.XDevicePromo.Eligibility",
465 signin_metrics::THROTTLED_FETCHING_DEVICE_ACTIVITY, 1);
466 }
467 }
468
469 TEST_F(CrossDevicePromoTest, NumDevicesKnown) {
470 // Start with a variation, signed in, and one account, sync devices in 1 hour.
471 InitPromoVariation();
472 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
473 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
474 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
475 std::vector<std::pair<std::string, bool>> accounts;
476 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
477 base::RunLoop().RunUntilIdle();
478 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
479 InOneHour());
480
481 // If there is no device present.
482 {
483 base::HistogramTester test_no_devices;
484 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 0);
485 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
486 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
487 signin_metrics::ZERO_DEVICES, 1);
488 }
489
490 // If there is one device present.
491 {
492 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
493 EXPECT_TRUE(promo()->CheckPromoEligibilityForTesting());
494 }
495 }
496
497 TEST_F(CrossDevicePromoTest, FetchDeviceResults) {
498 // Start with a variation, signed in, and one account, sync devices in 1 hour.
499 InitPromoVariation();
500 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
501 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
502 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
503 std::vector<std::pair<std::string, bool>> accounts;
504 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
505 base::RunLoop().RunUntilIdle();
506 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
507 base::Time::Now().ToInternalValue());
508 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
509
510 // If there is no device found.
511 {
512 base::HistogramTester test_no_devices;
513 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
514 int64 in_one_hour = InOneHour();
515 promo()->OnFetchDeviceActivitySuccess(devices);
516 EXPECT_LE(
517 in_one_hour,
518 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
519 EXPECT_EQ(0, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
520 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
521 signin_metrics::ZERO_DEVICES, 1);
522 }
523
524 // If there is one device found. It was recently active.
525 {
526 CrossDevicePromoObserver observer(promo());
527 ASSERT_FALSE(observer.IsActive());
528 base::HistogramTester test_one_device;
529 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
530 base::Time device_last_active =
531 base::Time::Now() - base::TimeDelta::FromMinutes(4);
532 DeviceActivityFetcher::DeviceActivity device;
533 device.last_active = device_last_active;
534 device.name = "Aslan";
535 devices.push_back(device);
536
537 int64 in_one_hour = InOneHour();
538 promo()->OnFetchDeviceActivitySuccess(devices);
539 EXPECT_LE(
540 in_one_hour,
541 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
542 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
543 EXPECT_EQ(device_last_active.ToInternalValue(),
544 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
545 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
546 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
547 signin_metrics::ELIGIBLE, 1);
548 EXPECT_TRUE(observer.IsActive());
549 EXPECT_EQ(1, observer.TimesBecameActive());
550 }
551
552 // If there is one device found. It was not recently active.
553 {
554 CrossDevicePromoObserver observer(promo());
555 ASSERT_FALSE(observer.IsActive());
556 base::HistogramTester test_one_device;
557 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
558 base::Time device_last_active =
559 base::Time::Now() - base::TimeDelta::FromMinutes(30);
560 DeviceActivityFetcher::DeviceActivity device;
561 device.last_active = device_last_active;
562 device.name = "Aslan";
563 devices.push_back(device);
564
565 int64 in_one_hour = InOneHour();
566 promo()->OnFetchDeviceActivitySuccess(devices);
567 EXPECT_LE(
568 in_one_hour,
569 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
570 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
571 EXPECT_EQ(device_last_active.ToInternalValue(),
572 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
573 EXPECT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
574 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
575 signin_metrics::NO_ACTIVE_DEVICES, 1);
576 EXPECT_FALSE(observer.IsActive());
577 }
578
579 // If there are two devices found, one recently.
580 {
581 CrossDevicePromoObserver observer(promo());
582 ASSERT_FALSE(observer.IsActive());
583 base::HistogramTester test_two_devices;
584 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
585 base::Time device1_last_active =
586 base::Time::Now() - base::TimeDelta::FromMinutes(30);
587 base::Time device2_last_active =
588 base::Time::Now() - base::TimeDelta::FromMinutes(3);
589 DeviceActivityFetcher::DeviceActivity device1;
590 device1.last_active = device1_last_active;
591 device1.name = "Aslan";
592 devices.push_back(device1);
593 DeviceActivityFetcher::DeviceActivity device2;
594 device2.last_active = device2_last_active;
595 device2.name = "Balrog";
596 devices.push_back(device2);
597
598 int64 in_one_hour = InOneHour();
599 promo()->OnFetchDeviceActivitySuccess(devices);
600 EXPECT_LE(
601 in_one_hour,
602 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
603 EXPECT_EQ(2, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
604 EXPECT_EQ(device2_last_active.ToInternalValue(),
605 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
606 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
607 test_two_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
608 signin_metrics::ELIGIBLE, 1);
609 EXPECT_TRUE(observer.IsActive());
610 EXPECT_EQ(1, observer.TimesBecameActive());
611 }
612 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698