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

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: rogers nit and a signed variable type so mac compiles 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 }
Alexei Svitkine (slow) 2015/05/19 15:23:49 Nit: // namespace
Mike Lerman 2015/05/19 16:53:17 Done.
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() {
50 promo_->RemoveObserver(this);
51 }
52
53 void OnPromoActivationChanged(bool active) override {
54 active_ = active;
55 active ? set_active_++ : set_inactive_++;
56 }
57
58 bool IsActive() { return active_; }
59 int TimesBecameActive() { return set_active_; }
60 int TimesBecameInactive() { return set_inactive_; }
61
62 private:
63 bool active_;
64 int set_active_;
65 int set_inactive_;
66 CrossDevicePromo* promo_;
67 };
Alexei Svitkine (slow) 2015/05/19 15:23:49 DISALLOW_COPY_AND_ASSIGN()
Mike Lerman 2015/05/19 16:53:17 Done.
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(
96 "CrossDevicePromo", "A", 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(std::make_pair(
124 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_ =
137 static_cast<FakeGaiaCookieManagerService*>(
138 GaiaCookieManagerServiceFactory::GetForProfile(profile()));
139 cookie_manager_service_->Init(&fake_url_fetcher_factory_);
140
141 signin_manager_ =
142 static_cast<FakeSigninManagerForTesting*>(
143 SigninManagerFactory::GetForProfile(profile()));
144 cross_device_promo_ = CrossDevicePromoFactory::GetForProfile(profile());
145 }
146
147 CrossDevicePromoTest::CrossDevicePromoTest()
148 : fake_url_fetcher_factory_(NULL) {
149 ResetFieldTrialList();
150 }
151
152 void CrossDevicePromoTest::ResetFieldTrialList() {
153 // Destroy the existing FieldTrialList before creating a new one to avoid
154 // a DCHECK.
155 field_trial_list_.reset();
156 field_trial_list_.reset(new base::FieldTrialList(
157 new metrics::SHA1EntropyProvider("foo")));
158 variations::testing::ClearAllVariationParams();
159 }
160
161 TEST_F(CrossDevicePromoTest, Uninitialized) {
162 ASSERT_TRUE(promo());
163 histogram_tester()->ExpectUniqueSample(
164 "Signin.XDevicePromo.Initialized",
165 signin_metrics::NO_VARIATIONS_CONFIG, 1);
166
167 promo()->CheckPromoEligibilityForTesting();
168 histogram_tester()->ExpectUniqueSample(
169 "Signin.XDevicePromo.Initialized",
170 signin_metrics::NO_VARIATIONS_CONFIG, 2);
171 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
172 ASSERT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
173 }
174
175 TEST_F(CrossDevicePromoTest, UnitializedOptedOut) {
176 CrossDevicePromoObserver observer(promo());
177
178 promo()->OptOut();
179 // Opting out doesn't de-activate a never-active promo.
180 ASSERT_EQ(0, observer.TimesBecameInactive());
181 ASSERT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoOptedOut));
182
183 // Never initialize a promo that is opted out.
184 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
185 histogram_tester()->ExpectBucketCount(
186 "Signin.XDevicePromo.Initialized",
187 signin_metrics::NO_VARIATIONS_CONFIG, 1);
188 histogram_tester()->ExpectBucketCount(
189 "Signin.XDevicePromo.Initialized",
190 signin_metrics::UNINITIALIZED_OPTED_OUT, 1);
191 histogram_tester()->ExpectTotalCount("Signin.XDevicePromo.Eligibility", 0);
192 }
193
194 TEST_F(CrossDevicePromoTest, PartiallyInitialized) {
195 histogram_tester()->ExpectUniqueSample(
196 "Signin.XDevicePromo.Initialized",
197 signin_metrics::NO_VARIATIONS_CONFIG, 1);
198
199 std::map<std::string, std::string> variations_params;
200 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
201 variations_params["DaysToVerifySingleUserProfile"] = "1";
202 ASSERT_TRUE(variations::AssociateVariationParams(
203 "CrossDevicePromo", "A", variations_params));
204 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
205
206 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
207 histogram_tester()->ExpectUniqueSample(
208 "Signin.XDevicePromo.Initialized",
209 signin_metrics::NO_VARIATIONS_CONFIG, 2);
210 ASSERT_FALSE(histogram_tester()->GetHistogramSamplesSinceCreation(
211 "Signin.XDevicePromo.Eligibility"));
212 }
213
214 TEST_F(CrossDevicePromoTest, FullyInitialized) {
215 histogram_tester()->ExpectUniqueSample(
216 "Signin.XDevicePromo.Initialized",
217 signin_metrics::NO_VARIATIONS_CONFIG, 1);
218
219 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
220 histogram_tester()->ExpectUniqueSample(
221 "Signin.XDevicePromo.Initialized",
222 signin_metrics::NO_VARIATIONS_CONFIG, 2);
223
224 InitPromoVariation();
225 signin_manager()->SignIn("12345", "foo@bar.com", "password");
226 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
227 histogram_tester()->ExpectBucketCount(
228 "Signin.XDevicePromo.Initialized", signin_metrics::INITIALIZED, 1);
229 histogram_tester()->ExpectBucketCount(
230 "Signin.XDevicePromo.Initialized",
231 signin_metrics::NO_VARIATIONS_CONFIG, 2);
232
233 histogram_tester()->ExpectUniqueSample(
234 "Signin.XDevicePromo.Eligibility", signin_metrics::SIGNED_IN, 1);
235 }
236
237 TEST_F(CrossDevicePromoTest, InitializedOptOut) {
238 // In a normal browser, the variations get set before the CrossDevicePromo is
239 // created. Here, we need to force another Init() by calling
240 // CheckPromoEligibilityForTesting().
241 InitPromoVariation();
242 signin_manager()->SignIn("12345", "foo@bar.com", "password");
243 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
244
245 histogram_tester()->ExpectBucketCount(
246 "Signin.XDevicePromo.Initialized", signin_metrics::INITIALIZED, 1);
247 histogram_tester()->ExpectUniqueSample(
248 "Signin.XDevicePromo.Eligibility", signin_metrics::SIGNED_IN, 1);
249
250 // After opting out the initialized state remains; eligibility changes.
251 promo()->OptOut();
252 promo()->CheckPromoEligibilityForTesting();
253 histogram_tester()->ExpectBucketCount(
254 "Signin.XDevicePromo.Initialized", signin_metrics::INITIALIZED, 1);
255 histogram_tester()->ExpectBucketCount(
256 "Signin.XDevicePromo.Eligibility", signin_metrics::OPTED_OUT, 1);
257 }
258
259 TEST_F(CrossDevicePromoTest, SignedInAndOut) {
260 InitPromoVariation();
261
262 {
263 base::HistogramTester test_signed_in;
264 signin_manager()->SignIn("12345", "foo@bar.com", "password");
265 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
266 test_signed_in.ExpectUniqueSample(
267 "Signin.XDevicePromo.Eligibility", signin_metrics::SIGNED_IN, 1);
268 }
269
270 {
271 base::HistogramTester test_signed_out;
272 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
273 promo()->CheckPromoEligibilityForTesting();
274 test_signed_out.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
275 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
276 }
277 }
278
279 TEST_F(CrossDevicePromoTest, TrackAccountsInCookie) {
280 InitPromoVariation();
281 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
282
283 ASSERT_FALSE(prefs()->HasPrefPath(
284 prefs::kCrossDevicePromoObservedSingleAccountCookie));
285 std::vector<std::pair<std::string, bool>> accounts;
286
287 // Setting a single cookie sets the time.
288 base::Time before_setting_cookies = base::Time::Now();
289 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
290 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
291 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
292 base::RunLoop().RunUntilIdle();
293
294 base::Time after_setting_cookies = base::Time::Now();
295 ASSERT_TRUE(prefs()->HasPrefPath(
296 prefs::kCrossDevicePromoObservedSingleAccountCookie));
297 ASSERT_LE(before_setting_cookies.ToInternalValue(), prefs()->GetInt64(
298 prefs::kCrossDevicePromoObservedSingleAccountCookie));
299 ASSERT_GE(after_setting_cookies.ToInternalValue(), prefs()->GetInt64(
300 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));
Alexei Svitkine (slow) 2015/05/19 15:23:49 Nit: Wrong indent. "git cl format"?
Mike Lerman 2015/05/19 16:53:17 Done.
310 ASSERT_GE(after_setting_cookies.ToInternalValue(), prefs()->GetInt64(
311 prefs::kCrossDevicePromoObservedSingleAccountCookie));
312
313 // Setting accounts with an auth error doesn't change the time.
314 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
315 cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
316 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
317 base::RunLoop().RunUntilIdle();
318
319 ASSERT_TRUE(prefs()->HasPrefPath(
320 prefs::kCrossDevicePromoObservedSingleAccountCookie));
321 ASSERT_LE(before_setting_cookies.ToInternalValue(), prefs()->GetInt64(
322 prefs::kCrossDevicePromoObservedSingleAccountCookie));
323 ASSERT_GE(after_setting_cookies.ToInternalValue(), prefs()->GetInt64(
324 prefs::kCrossDevicePromoObservedSingleAccountCookie));
325
326 // Seeing zero accounts clears the pref.
327 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
328 cookie_manager_service()->SetListAccountsResponseNoAccounts();
329 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
330 base::RunLoop().RunUntilIdle();
331
332 ASSERT_FALSE(prefs()->HasPrefPath(
333 prefs::kCrossDevicePromoObservedSingleAccountCookie));
334 }
335
336 TEST_F(CrossDevicePromoTest, SingleAccountEligibility) {
337 InitPromoVariation();
338
339 {
340 base::HistogramTester test_single_account;
341 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
342 test_single_account.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
343 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
344 }
345
346 // Notice a single account.
347 {
348 base::HistogramTester test_single_account;
349 std::vector<std::pair<std::string, bool>> accounts;
350 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
351 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
352 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
353 base::RunLoop().RunUntilIdle();
354
355 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
356 test_single_account.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
357 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
358 }
359
360 // Set a single account that hasn't been around for "long enough".
361 {
362 base::HistogramTester test_single_account;
363 prefs()->SetInt64(prefs::kCrossDevicePromoObservedSingleAccountCookie,
364 InOneHour());
365 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
366 test_single_account.ExpectBucketCount("Signin.XDevicePromo.Eligibility",
367 signin_metrics::NOT_SINGLE_GAIA_ACCOUNT, 1);
368 }
369 }
370
371 TEST_F(CrossDevicePromoTest, NumDevicesEligibility) {
372 // Start with a variation, signed in, and one account in the cookie jar.
373 InitPromoVariation();
374 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
375 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
376 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
377 std::vector<std::pair<std::string, bool>> accounts;
378 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
379 base::RunLoop().RunUntilIdle();
380
381 // Ensure we appropriate schedule a check for listing devices.
382 {
383 base::HistogramTester test_missing_list_devices;
384 int64 earliest_time_to_check_list_devices = base::Time::Now().
385 ToInternalValue();
386 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
387 int64 latest_time_to_check_list_devices = InOneHour();
388 test_missing_list_devices.ExpectUniqueSample(
389 "Signin.XDevicePromo.Eligibility",
390 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
391 EXPECT_TRUE(prefs()->HasPrefPath(
392 prefs::kCrossDevicePromoNextFetchListDevicesTime));
393 int64 when_to_check_list_devices =
394 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime);
395 EXPECT_LT(earliest_time_to_check_list_devices, when_to_check_list_devices);
396 EXPECT_GT(latest_time_to_check_list_devices, when_to_check_list_devices);
397 }
398
399 // Don't reschedule the list devices check if there's one pending.
400 {
401 base::HistogramTester test_unknown_devices;
402 int64 list_devices_time = InOneHour();
403 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
404 list_devices_time);
405 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
406 test_unknown_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
407 signin_metrics::UNKNOWN_COUNT_DEVICES, 1);
408 // The scheduled time to call ListDevices should not have changed.
409 ASSERT_EQ(list_devices_time, prefs()->GetInt64(
410 prefs::kCrossDevicePromoNextFetchListDevicesTime));
411 }
412
413 // Execute the list devices check if it's time.
414 {
415 base::HistogramTester test_unknown_devices;
416 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
417 base::Time::Now().ToInternalValue());
418 // The DeviceActivityFetcher will return an error to the promo service.
419 fetcher_factory()->SetFakeResponse(
420 GaiaUrls::GetInstance()->oauth2_iframe_url(),
421 "not json", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
422 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
423 base::RunLoop().RunUntilIdle();
424 test_unknown_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
425 signin_metrics::ERROR_FETCHING_DEVICE_ACTIVITY, 1);
426 }
427 }
428
429 TEST_F(CrossDevicePromoTest, ThrottleDeviceActivityCall) {
430 // Start with a variation (fully throttled), signed in, one account in cookie.
431 std::map<std::string, std::string> variations_params;
432 variations_params["HoursBetweenSyncDeviceChecks"] = "1";
433 variations_params["DaysToVerifySingleUserProfile"] = "0";
434 variations_params["MinutesBetweenBrowsingSessions"] = "0";
435 variations_params["MinutesMaxContextSwitchDuration"] = "10";
436 variations_params["RPCThrottle"] = "101";
437 EXPECT_TRUE(variations::AssociateVariationParams(
438 "CrossDevicePromo", "A", variations_params));
439 base::FieldTrialList::CreateFieldTrial("CrossDevicePromo", "A");
440
441 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
442 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
443 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
444 std::vector<std::pair<std::string, bool>> accounts;
445 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
446 base::RunLoop().RunUntilIdle();
447
448 // Ensure Device Activity Fetch gets throttled.
449 {
450 base::HistogramTester test_throttle_rpc;
451 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
452 base::Time::Now().ToInternalValue());
453 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
454 test_throttle_rpc.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
455 signin_metrics::THROTTLED_FETCHING_DEVICE_ACTIVITY, 1);
456 }
457 }
458
459 TEST_F(CrossDevicePromoTest, NumDevicesKnown) {
460 // Start with a variation, signed in, and one account, sync devices in 1 hour.
461 InitPromoVariation();
462 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
463 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
464 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
465 std::vector<std::pair<std::string, bool>> accounts;
466 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
467 base::RunLoop().RunUntilIdle();
468 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
469 InOneHour());
470
471 // If there is no device present.
472 {
473 base::HistogramTester test_no_devices;
474 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 0);
475 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
476 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
477 signin_metrics::ZERO_DEVICES, 1);
478 }
479
480 // If there is one device present.
481 {
482 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
483 EXPECT_TRUE(promo()->CheckPromoEligibilityForTesting());
484 }
485 }
486
487 TEST_F(CrossDevicePromoTest, FetchDeviceResults) {
488 // Start with a variation, signed in, and one account, sync devices in 1 hour.
489 InitPromoVariation();
490 EXPECT_FALSE(promo()->CheckPromoEligibilityForTesting());
491 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
492 cookie_manager_service()->SetListAccountsResponseOneAccount("foo@bar.com");
493 std::vector<std::pair<std::string, bool>> accounts;
494 EXPECT_FALSE(cookie_manager_service()->ListAccounts(&accounts));
495 base::RunLoop().RunUntilIdle();
496 prefs()->SetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime,
497 base::Time::Now().ToInternalValue());
498 prefs()->SetInteger(prefs::kCrossDevicePromoNumDevices, 1);
499
500 // If there is no device found.
501 {
502 base::HistogramTester test_no_devices;
503 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
504 int64 in_one_hour = InOneHour();
505 promo()->OnFetchDeviceActivitySuccess(devices);
506 EXPECT_LE(in_one_hour,
507 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
508 EXPECT_EQ(0, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
509 test_no_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
510 signin_metrics::ZERO_DEVICES, 1);
511 }
512
513 // If there is one device found. It was recently active.
514 {
515 CrossDevicePromoObserver observer(promo());
516 ASSERT_FALSE(observer.IsActive());
517 base::HistogramTester test_one_device;
518 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
519 base::Time device_last_active =
520 base::Time::Now() - base::TimeDelta::FromMinutes(4);
521 DeviceActivityFetcher::DeviceActivity device;
522 device.last_active = device_last_active;
523 device.name = "Aslan";
524 devices.push_back(device);
525
526 int64 in_one_hour = InOneHour();
527 promo()->OnFetchDeviceActivitySuccess(devices);
528 EXPECT_LE(in_one_hour,
529 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
530 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
531 EXPECT_EQ(device_last_active.ToInternalValue(),
532 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
533 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
534 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
535 signin_metrics::ELIGIBLE, 1);
536 EXPECT_TRUE(observer.IsActive());
537 EXPECT_EQ(1, observer.TimesBecameActive());
538 }
539
540 // If there is one device found. It was not recently active.
541 {
542 CrossDevicePromoObserver observer(promo());
543 ASSERT_FALSE(observer.IsActive());
544 base::HistogramTester test_one_device;
545 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
546 base::Time device_last_active =
547 base::Time::Now() - base::TimeDelta::FromMinutes(30);
548 DeviceActivityFetcher::DeviceActivity device;
549 device.last_active = device_last_active;
550 device.name = "Aslan";
551 devices.push_back(device);
552
553 int64 in_one_hour = InOneHour();
554 promo()->OnFetchDeviceActivitySuccess(devices);
555 EXPECT_LE(in_one_hour,
556 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
557 EXPECT_EQ(1, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
558 EXPECT_EQ(device_last_active.ToInternalValue(),
559 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
560 EXPECT_FALSE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
561 test_one_device.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
562 signin_metrics::NO_ACTIVE_DEVICES, 1);
563 EXPECT_FALSE(observer.IsActive());
564 }
565
566 // If there are two devices found, one recently.
567 {
568 CrossDevicePromoObserver observer(promo());
569 ASSERT_FALSE(observer.IsActive());
570 base::HistogramTester test_two_devices;
571 std::vector<DeviceActivityFetcher::DeviceActivity> devices;
572 base::Time device1_last_active =
573 base::Time::Now() - base::TimeDelta::FromMinutes(30);
574 base::Time device2_last_active =
575 base::Time::Now() - base::TimeDelta::FromMinutes(3);
576 DeviceActivityFetcher::DeviceActivity device1;
577 device1.last_active = device1_last_active;
578 device1.name = "Aslan";
579 devices.push_back(device1);
580 DeviceActivityFetcher::DeviceActivity device2;
581 device2.last_active = device2_last_active;
582 device2.name = "Balrog";
583 devices.push_back(device2);
584
585 int64 in_one_hour = InOneHour();
586 promo()->OnFetchDeviceActivitySuccess(devices);
587 EXPECT_LE(in_one_hour,
588 prefs()->GetInt64(prefs::kCrossDevicePromoNextFetchListDevicesTime));
589 EXPECT_EQ(2, prefs()->GetInteger(prefs::kCrossDevicePromoNumDevices));
590 EXPECT_EQ(device2_last_active.ToInternalValue(),
591 prefs()->GetInt64(prefs::kCrossDevicePromoLastDeviceActiveTime));
592 EXPECT_TRUE(prefs()->GetBoolean(prefs::kCrossDevicePromoActive));
593 test_two_devices.ExpectUniqueSample("Signin.XDevicePromo.Eligibility",
594 signin_metrics::ELIGIBLE, 1);
595 EXPECT_TRUE(observer.IsActive());
596 EXPECT_EQ(1, observer.TimesBecameActive());
597 }
598 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698