Componentize HistoryURLProvider/ScoredHistoryMatch.
[chromium-blink-merge.git] / chrome / browser / signin / cross_device_promo_unittest.cc
blob1450884e7af5e86b93c4ef90a57bc610dfd20197
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.
5 #include "chrome/browser/signin/cross_device_promo.h"
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"
34 namespace {
36 int64 InOneHour() {
37 return (base::Time::Now() + base::TimeDelta::FromHours(1)).ToInternalValue();
40 } // namespace
42 class CrossDevicePromoObserver : public CrossDevicePromo::Observer {
43 public:
44 explicit CrossDevicePromoObserver(CrossDevicePromo* promo)
45 : active_(false),
46 times_set_active_(0),
47 times_set_inactive_(0),
48 promo_(promo) {
49 promo->AddObserver(this);
52 ~CrossDevicePromoObserver() { promo_->RemoveObserver(this); }
54 void OnPromoActivationChanged(bool active) override {
55 active_ = active;
56 if (active)
57 times_set_active_++;
58 else
59 times_set_inactive_++;
62 bool is_active() { return active_; }
63 int times_set_active() { return times_set_active_; }
64 int times_set_inactive() { return times_set_inactive_; }
66 private:
67 bool active_;
68 int times_set_active_;
69 int times_set_inactive_;
70 CrossDevicePromo* promo_;
72 DISALLOW_COPY_AND_ASSIGN(CrossDevicePromoObserver);
75 class CrossDevicePromoTest : public ::testing::Test {
76 public:
77 CrossDevicePromoTest();
78 void SetUp() override;
80 void ResetFieldTrialList();
82 CrossDevicePromo* promo() { return cross_device_promo_; }
83 TestingProfile* profile() { return profile_; }
84 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
85 base::HistogramTester* histogram_tester() { return &histogram_tester_; }
86 TestingPrefServiceSyncable* prefs() { return pref_service_; }
87 FakeGaiaCookieManagerService* cookie_manager_service() {
88 return cookie_manager_service_;
90 net::FakeURLFetcherFactory* fetcher_factory() {
91 return &fake_url_fetcher_factory_;
94 void InitPromoVariation() {
95 std::map<std::string, std::string> variations_params;
96 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
97 variations_params["DaysToVerifySingleUserProfile"] = "0";
98 variations_params["MinutesBetweenBrowsingSessions"] = "0";
99 variations_params["MinutesMaxContextSwitchDuration"] = "10";
100 variations_params["RPCThrottle"] = "0";
101 EXPECT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
102 variations_params));
103 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
106 private:
107 content::TestBrowserThreadBundle bundle_;
108 CrossDevicePromo* cross_device_promo_;
109 TestingProfile* profile_;
110 FakeSigninManagerForTesting* signin_manager_;
111 FakeGaiaCookieManagerService* cookie_manager_service_;
112 TestingPrefServiceSyncable* pref_service_;
113 scoped_ptr<TestingProfileManager> testing_profile_manager_;
114 base::HistogramTester histogram_tester_;
115 scoped_ptr<base::FieldTrialList> field_trial_list_;
116 net::FakeURLFetcherFactory fake_url_fetcher_factory_;
118 DISALLOW_COPY_AND_ASSIGN(CrossDevicePromoTest);
121 void CrossDevicePromoTest::SetUp() {
122 testing_profile_manager_.reset(
123 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
124 ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
126 TestingProfile::TestingFactories factories;
127 factories.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
128 signin::BuildTestSigninClient));
129 factories.push_back(
130 std::make_pair(GaiaCookieManagerServiceFactory::GetInstance(),
131 FakeGaiaCookieManagerService::Build));
132 factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
133 FakeSigninManagerBase::Build));
135 pref_service_ = new TestingPrefServiceSyncable();
136 chrome::RegisterUserProfilePrefs(pref_service_->registry());
138 profile_ = testing_profile_manager_.get()->CreateTestingProfile(
139 "name", make_scoped_ptr<PrefServiceSyncable>(pref_service_),
140 base::UTF8ToUTF16("name"), 0, std::string(), factories);
142 cookie_manager_service_ = static_cast<FakeGaiaCookieManagerService*>(
143 GaiaCookieManagerServiceFactory::GetForProfile(profile()));
144 cookie_manager_service_->Init(&fake_url_fetcher_factory_);
146 signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
147 SigninManagerFactory::GetForProfile(profile()));
148 cross_device_promo_ = CrossDevicePromoFactory::GetForProfile(profile());
151 CrossDevicePromoTest::CrossDevicePromoTest() : fake_url_fetcher_factory_(NULL) {
152 ResetFieldTrialList();
155 void CrossDevicePromoTest::ResetFieldTrialList() {
156 // Destroy the existing FieldTrialList before creating a new one to avoid
157 // a DCHECK.
158 field_trial_list_.reset();
159 field_trial_list_.reset(
160 new base::FieldTrialList(new metrics::SHA1EntropyProvider("foo")));
161 variations::testing::ClearAllVariationParams();
164 TEST_F(CrossDevicePromoTest, Uninitialized) {
165 ASSERT_TRUE(promo());
166 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
167 signin_metrics::NO_VARIATIONS_CONFIG,
170 promo()->CheckPromoEligibilityForTesting();
171 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
172 signin_metrics::NO_VARIATIONS_CONFIG,
174 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
175 ASSERT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
178 TEST_F(CrossDevicePromoTest, UnitializedOptedOut) {
179 CrossDevicePromoObserver observer(promo());
181 promo()->OptOut();
182 // Opting out doesn't de-activate a never-active promo.
183 ASSERT_EQ(0, observer.times_set_inactive());
184 ASSERT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
186 // Never initialize a promo that is opted out.
187 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
188 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
189 signin_metrics::NO_VARIATIONS_CONFIG,
191 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
192 signin_metrics::UNINITIALIZED_OPTED_OUT,
194 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
197 TEST_F(CrossDevicePromoTest, PartiallyInitialized) {
198 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
199 signin_metrics::NO_VARIATIONS_CONFIG,
202 std::map<std::string, std::string> variations_params;
203 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
204 variations_params["DaysToVerifySingleUserProfile"] = "1";
205 ASSERT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
206 variations_params));
207 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
209 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
210 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
211 signin_metrics::NO_VARIATIONS_CONFIG,
213 ASSERT_FALSE(histogram_tester()->GetHistogramSamplesSinceCreation(
214 "Signin.XDevicePromo.Eligibility"));
217 TEST_F(CrossDevicePromoTest, FullyInitialized) {
218 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
219 signin_metrics::NO_VARIATIONS_CONFIG,
222 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
223 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Initialized",
224 signin_metrics::NO_VARIATIONS_CONFIG,
227 InitPromoVariation();
228 signin_manager()->SignIn("12345", "foo@bar.com", "password");
229 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
230 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
231 signin_metrics::INITIALIZED, 1);
232 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
233 signin_metrics::NO_VARIATIONS_CONFIG,
236 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
237 signin_metrics::SIGNED_IN, 1);
240 TEST_F(CrossDevicePromoTest, InitializedOptOut) {
241 // In a normal browser, the variations get set before the CrossDevicePromo is
242 // created. Here, we need to force another Init() by calling
243 // CheckPromoEligibilityForTesting().
244 InitPromoVariation();
245 signin_manager()->SignIn("12345", "foo@bar.com", "password");
246 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
248 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
249 signin_metrics::INITIALIZED, 1);
250 histogram_tester()->ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
251 signin_metrics::SIGNED_IN, 1);
253 // After opting out the initialized state remains; eligibility changes.
254 promo()->OptOut();
255 promo()->CheckPromoEligibilityForTesting();
256 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Initialized",
257 signin_metrics::INITIALIZED, 1);
258 histogram_tester()->ExpectBucketCount("Signin.XDevicePromo.Eligibility",
259 signin_metrics::OPTED_OUT, 1);
262 TEST_F(CrossDevicePromoTest, SignedInAndOut) {
263 InitPromoVariation();
266 base::HistogramTester test_signed_in;
267 signin_manager()->SignIn("12345", "foo@bar.com", "password");
268 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
269 test_signed_in.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
270 signin_metrics::SIGNED_IN, 1);
274 base::HistogramTester test_signed_out;
275 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
276 promo()->CheckPromoEligibilityForTesting();
277 test_signed_out.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
278 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT,
283 TEST_F(CrossDevicePromoTest, TrackAccountsInCookie) {
284 InitPromoVariation();
285 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
287 ASSERT_FALSE(prefs()->HasPrefPath(
288 prefs::kCrossDevicePromoObservedSingleAccountCookie));
289 std::vector<gaia::ListedAccount> accounts;
291 // Setting a single cookie sets the time.
292 base::Time before_setting_cookies = base::Time::Now();
293 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
294 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
295 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
296 base::RunLoop().RunUntilIdle();
298 base::Time after_setting_cookies = base::Time::Now();
299 ASSERT_TRUE(prefs()->HasPrefPath(
300 prefs::kCrossDevicePromoObservedSingleAccountCookie));
301 ASSERT_LE(
302 before_setting_cookies.ToInternalValue(),
303 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
304 ASSERT_GE(
305 after_setting_cookies.ToInternalValue(),
306 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
308 // A single cookie a second time doesn't change the time.
309 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
310 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
311 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
312 base::RunLoop().RunUntilIdle();
314 ASSERT_TRUE(prefs()->HasPrefPath(
315 prefs::kCrossDevicePromoObservedSingleAccountCookie));
316 ASSERT_GE(
317 after_setting_cookies.ToInternalValue(),
318 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
320 // Setting accounts with an auth error doesn't change the time.
321 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
322 cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
323 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
324 base::RunLoop().RunUntilIdle();
326 ASSERT_TRUE(prefs()->HasPrefPath(
327 prefs::kCrossDevicePromoObservedSingleAccountCookie));
328 ASSERT_LE(
329 before_setting_cookies.ToInternalValue(),
330 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
331 ASSERT_GE(
332 after_setting_cookies.ToInternalValue(),
333 prefs()->GetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie));
335 // Seeing zero accounts clears the pref.
336 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
337 cookie_manager_service()->SetListAccountsResponseNoAccounts();
338 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
339 base::RunLoop().RunUntilIdle();
341 ASSERT_FALSE(prefs()->HasPrefPath(
342 prefs::kCrossDevicePromoObservedSingleAccountCookie));
345 TEST_F(CrossDevicePromoTest, SingleAccountEligibility) {
346 InitPromoVariation();
349 base::HistogramTester test_single_account;
350 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
351 test_single_account.ExpectUniqueSample(
352 "Signin.XDevicePromo.Eligibility",
353 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
356 // Notice a single account.
358 base::HistogramTester test_single_account;
359 std::vector<gaia::ListedAccount> accounts;
360 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
361 cookie_manager_service()->SetListAccountsResponseOneAccount("a@b.com", "1");
362 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
363 base::RunLoop().RunUntilIdle();
365 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
366 test_single_account.ExpectUniqueSample(
367 "Signin.XDevicePromo.Eligibility",
368 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
371 // Set a single account that hasn't been around for "long enough".
373 base::HistogramTester test_single_account;
374 prefs()->SetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie,
375 InOneHour());
376 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
377 test_single_account.ExpectBucketCount(
378 "Signin.XDevicePromo.Eligibility",
379 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
383 TEST_F(CrossDevicePromoTest, NumDevicesEligibility) {
384 // Start with a variation, signed in, and one account in the cookie jar.
385 InitPromoVariation();
386 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
387 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
388 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
389 std::vector<gaia::ListedAccount> accounts;
390 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
391 base::RunLoop().RunUntilIdle();
393 // Ensure we appropriate schedule a check for listing devices.
395 base::HistogramTester test_missing_list_devices;
396 int64 earliest_time_to_check_list_devices =
397 base::Time::Now().ToInternalValue();
398 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
399 int64 latest_time_to_check_list_devices = InOneHour();
400 test_missing_list_devices.ExpectUniqueSample(
401 "Signin.XDevicePromo.Eligibility",
402 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
403 EXPECT_TRUE(
404 prefs()->HasPrefPath(prefs::kCrossDevicePromoNextFetchListDevicesTime));
405 int64 when_to_check_list_devices =
406 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime);
407 EXPECT_LT(earliest_time_to_check_list_devices, when_to_check_list_devices);
408 EXPECT_GT(latest_time_to_check_list_devices, when_to_check_list_devices);
411 // Don't reschedule the list devices check if there's one pending.
413 base::HistogramTester test_unknown_devices;
414 int64 list_devices_time = InOneHour();
415 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
416 list_devices_time);
417 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
418 test_unknown_devices.ExpectUniqueSample(
419 "Signin.XDevicePromo.Eligibility",
420 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
421 // The scheduled time to call ListDevices should not have changed.
422 ASSERT_EQ(
423 list_devices_time,
424 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
427 // Execute the list devices check if it's time.
429 base::HistogramTester test_unknown_devices;
430 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
431 base::Time::Now().ToInternalValue());
432 // The DeviceActivityFetcher will return an error to the promo service.
433 fetcher_factory()->SetFakeResponse(
434 GaiaUrls::GetInstance()->oauth2_iframe_url(), "not json", net::HTTP_OK,
435 net::URLRequestStatus::SUCCESS);
436 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
437 base::RunLoop().RunUntilIdle();
438 test_unknown_devices.ExpectUniqueSample(
439 "Signin.XDevicePromo.Eligibility",
440 signin_metrics::ERROR_FETCHING_DEVICE_ACTIVITY, 1);
444 TEST_F(CrossDevicePromoTest, ThrottleDeviceActivityCall) {
445 // Start with a variation (fully throttled), signed in, one account in cookie.
446 std::map<std::string, std::string> variations_params;
447 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
448 variations_params["DaysToVerifySingleUserProfile"] = "0";
449 variations_params["MinutesBetweenBrowsingSessions"] = "0";
450 variations_params["MinutesMaxContextSwitchDuration"] = "10";
451 variations_params["RPCThrottle"] = "101";
452 EXPECT_TRUE(variations::AssociateVariationParams("CrossDevicePromo", "A",
453 variations_params));
454 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
456 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
457 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
458 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
459 std::vector<gaia::ListedAccount> accounts;
460 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
461 base::RunLoop().RunUntilIdle();
463 // Ensure Device Activity Fetch gets throttled.
465 base::HistogramTester test_throttle_rpc;
466 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
467 base::Time::Now().ToInternalValue());
468 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
469 test_throttle_rpc.ExpectUniqueSample(
470 "Signin.XDevicePromo.Eligibility",
471 signin_metrics::THROTTLED_FETCHING_DEVICE_ACTIVITY, 1);
475 TEST_F(CrossDevicePromoTest, NumDevicesKnown) {
476 // Start with a variation, signed in, and one account, sync devices in 1 hour.
477 InitPromoVariation();
478 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
479 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
480 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
481 std::vector<gaia::ListedAccount> accounts;
482 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
483 base::RunLoop().RunUntilIdle();
484 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
485 InOneHour());
487 // If there is no device present.
489 base::HistogramTester test_no_devices;
490 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 0);
491 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
492 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
493 signin_metrics::ZERO_DEVICES, 1);
496 // If there is one device present.
498 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
499 EXPECT_TRUE(promo()->CheckPromoEligibilityForTesting());
503 TEST_F(CrossDevicePromoTest, FetchDeviceResults) {
504 // Start with a variation, signed in, and one account, sync devices in 1 hour.
505 InitPromoVariation();
506 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
507 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
508 cookie_manager_service()->SetListAccountsResponseOneAccount("f@bar.com", "1");
509 std::vector<gaia::ListedAccount> accounts;
510 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
511 base::RunLoop().RunUntilIdle();
512 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
513 base::Time::Now().ToInternalValue());
514 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
516 // If there is no device found.
518 base::HistogramTester test_no_devices;
519 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
520 int64 in_one_hour = InOneHour();
521 promo()->OnFetchDeviceActivitySuccess(devices);
522 EXPECT_LE(
523 in_one_hour,
524 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
525 EXPECT_EQ(0, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
526 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
527 signin_metrics::ZERO_DEVICES, 1);
530 // If there is one device found. It was recently active.
532 CrossDevicePromoObserver observer(promo());
533 ASSERT_FALSE(observer.is_active());
534 base::HistogramTester test_one_device;
535 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
536 base::Time device_last_active =
537 base::Time::Now() - base::TimeDelta::FromMinutes(4);
538 DeviceActivityFetcher::DeviceActivity device;
539 device.last_active = device_last_active;
540 device.name = "Aslan";
541 devices.push_back(device);
543 int64 in_one_hour = InOneHour();
544 promo()->OnFetchDeviceActivitySuccess(devices);
545 EXPECT_LE(
546 in_one_hour,
547 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
548 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
549 EXPECT_EQ(device_last_active.ToInternalValue(),
550 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
551 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
552 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
553 signin_metrics::ELIGIBLE, 1);
554 EXPECT_TRUE(observer.is_active());
555 EXPECT_EQ(1, observer.times_set_active());
558 // If there is one device found. It was not recently active.
560 CrossDevicePromoObserver observer(promo());
561 ASSERT_FALSE(observer.is_active());
562 base::HistogramTester test_one_device;
563 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
564 base::Time device_last_active =
565 base::Time::Now() - base::TimeDelta::FromMinutes(30);
566 DeviceActivityFetcher::DeviceActivity device;
567 device.last_active = device_last_active;
568 device.name = "Aslan";
569 devices.push_back(device);
571 int64 in_one_hour = InOneHour();
572 promo()->OnFetchDeviceActivitySuccess(devices);
573 EXPECT_LE(
574 in_one_hour,
575 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
576 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
577 EXPECT_EQ(device_last_active.ToInternalValue(),
578 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
579 EXPECT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
580 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
581 signin_metrics::NO_ACTIVE_DEVICES, 1);
582 EXPECT_FALSE(observer.is_active());
585 // If there are two devices found, one recently.
587 CrossDevicePromoObserver observer(promo());
588 ASSERT_FALSE(observer.is_active());
589 base::HistogramTester test_two_devices;
590 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
591 base::Time device1_last_active =
592 base::Time::Now() - base::TimeDelta::FromMinutes(30);
593 base::Time device2_last_active =
594 base::Time::Now() - base::TimeDelta::FromMinutes(3);
595 DeviceActivityFetcher::DeviceActivity device1;
596 device1.last_active = device1_last_active;
597 device1.name = "Aslan";
598 devices.push_back(device1);
599 DeviceActivityFetcher::DeviceActivity device2;
600 device2.last_active = device2_last_active;
601 device2.name = "Balrog";
602 devices.push_back(device2);
604 int64 in_one_hour = InOneHour();
605 promo()->OnFetchDeviceActivitySuccess(devices);
606 EXPECT_LE(
607 in_one_hour,
608 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
609 EXPECT_EQ(2, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
610 EXPECT_EQ(device2_last_active.ToInternalValue(),
611 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
612 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
613 test_two_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
614 signin_metrics::ELIGIBLE, 1);
615 EXPECT_TRUE(observer.is_active());
616 EXPECT_EQ(1, observer.times_set_active());