rlz_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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/rlz/rlz.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/stringprintf.h"
9#include "base/path_service.h"
10#include "base/scoped_temp_dir.h"
11#include "base/utf_string_conversions.h"
12#include "chrome/browser/autocomplete/autocomplete_log.h"
13#include "chrome/browser/google/google_util.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/common/chrome_notification_types.h"
16#include "chrome/common/env_vars.h"
17#include "chrome/installer/util/browser_distribution.h"
18#include "chrome/installer/util/google_update_constants.h"
19#include "content/public/browser/navigation_entry.h"
20#include "content/public/browser/notification_service.h"
21#include "content/public/browser/notification_details.h"
22#include "content/public/browser/notification_source.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
25#if defined(OS_WIN)
26#include "base/test/test_reg_util_win.h"
27#include "base/win/registry.h"
28#include "rlz/win/lib/rlz_lib.h"  // InitializeTempHivesForTesting
29#elif defined(OS_MACOSX)
30#include "rlz/lib/rlz_value_store.h"  // SetRlzStoreDirectory
31#endif
32
33using content::NavigationEntry;
34using testing::AssertionResult;
35using testing::AssertionSuccess;
36using testing::AssertionFailure;
37
38#if defined(OS_WIN)
39using base::win::RegKey;
40using registry_util::RegistryOverrideManager;
41#endif
42
43namespace {
44
45#if defined(OS_WIN)
46// Registry path to overridden hive.
47const wchar_t kRlzTempHkcu[] = L"rlz_hkcu";
48const wchar_t kRlzTempHklm[] = L"rlz_hklm";
49#endif
50
51// Dummy RLZ string for the access points.
52const char kOmniboxRlzString[] = "test_omnibox";
53const char kHomepageRlzString[] = "test_homepage";
54const char kNewOmniboxRlzString[] = "new_omnibox";
55const char kNewHomepageRlzString[] = "new_homepage";
56
57// Some helper macros to test it a string contains/does not contain a substring.
58
59AssertionResult CmpHelperSTRC(const char* str_expression,
60                              const char* substr_expression,
61                              const char* str,
62                              const char* substr) {
63  if (NULL != strstr(str, substr)) {
64    return AssertionSuccess();
65  }
66
67  return AssertionFailure() << "Expected: (" << substr_expression << ") in ("
68                            << str_expression << "), actual: '"
69                            << substr << "' not in '" << str << "'";
70}
71
72AssertionResult CmpHelperSTRNC(const char* str_expression,
73                               const char* substr_expression,
74                               const char* str,
75                               const char* substr) {
76  if (NULL == strstr(str, substr)) {
77    return AssertionSuccess();
78  }
79
80  return AssertionFailure() << "Expected: (" << substr_expression
81                            << ") not in (" << str_expression << "), actual: '"
82                            << substr << "' in '" << str << "'";
83}
84
85#define EXPECT_STR_CONTAINS(str, substr) \
86    EXPECT_PRED_FORMAT2(CmpHelperSTRC, str, substr)
87
88#define EXPECT_STR_NOT_CONTAIN(str, substr) \
89    EXPECT_PRED_FORMAT2(CmpHelperSTRNC, str, substr)
90
91}  // namespace
92
93// Test class for RLZ tracker. Makes some member functions public and
94// overrides others to make it easier to test.
95class TestRLZTracker : public RLZTracker {
96 public:
97  using RLZTracker::DelayedInit;
98  using RLZTracker::Observe;
99
100  TestRLZTracker() : assume_not_ui_thread_(false) {
101    set_tracker(this);
102  }
103
104  virtual ~TestRLZTracker() {
105    set_tracker(NULL);
106  }
107
108  bool was_ping_sent_for_brand(const std::string& brand) const {
109    return pinged_brands_.count(brand) > 0;
110  }
111
112  void set_assume_not_ui_thread(bool assume_not_ui_thread) {
113    assume_not_ui_thread_ = assume_not_ui_thread;
114  }
115
116 private:
117  virtual void ScheduleDelayedInit(int delay) OVERRIDE {
118    // If the delay is 0, invoke the delayed init now. Otherwise,
119    // don't schedule anything, it will be manually called during tests.
120    if (delay == 0)
121      DelayedInit();
122  }
123
124  virtual void ScheduleFinancialPing() OVERRIDE {
125    PingNowImpl();
126  }
127
128  virtual bool ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point) OVERRIDE {
129    return !assume_not_ui_thread_;
130  }
131
132  virtual bool SendFinancialPing(const std::string& brand,
133                                 const string16& lang,
134                                 const string16& referral) OVERRIDE {
135    // Don't ping the server during tests, just pretend as if we did.
136    EXPECT_FALSE(brand.empty());
137    pinged_brands_.insert(brand);
138
139    // Set new access points RLZ string, like the actual server ping would have
140    // done.
141    rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX,
142                               kNewOmniboxRlzString);
143    rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_HOME_PAGE,
144                               kNewHomepageRlzString);
145    return true;
146  }
147
148  std::set<std::string> pinged_brands_;
149  bool assume_not_ui_thread_;
150
151  DISALLOW_COPY_AND_ASSIGN(TestRLZTracker);
152};
153
154class RlzLibTest : public testing::Test {
155  virtual void SetUp() OVERRIDE;
156  virtual void TearDown() OVERRIDE;
157
158 protected:
159  void SetMainBrand(const char* brand);
160  void SetReactivationBrand(const char* brand);
161#if defined(OS_WIN)
162  void SetRegistryBrandValue(const wchar_t* name, const char* brand);
163#endif
164
165  void SimulateOmniboxUsage();
166  void SimulateHomepageUsage();
167  void InvokeDelayedInit();
168
169  void ExpectEventRecorded(const char* event_name, bool expected);
170  void ExpectRlzPingSent(bool expected);
171  void ExpectReactivationRlzPingSent(bool expected);
172
173  TestRLZTracker tracker_;
174#if defined(OS_WIN)
175  RegistryOverrideManager override_manager_;
176#elif defined(OS_MACOSX)
177  ScopedTempDir temp_dir_;
178  scoped_ptr<google_util::BrandForTesting> brand_override_;
179#endif
180};
181
182void RlzLibTest::SetUp() {
183  testing::Test::SetUp();
184
185#if defined(OS_WIN)
186  // Before overriding HKLM for the tests, we need to set it up correctly
187  // so that the rlz_lib calls work. This needs to be done before we do the
188  // override.
189
190  string16 temp_hklm_path = base::StringPrintf(
191      L"%ls\\%ls",
192      RegistryOverrideManager::kTempTestKeyPath,
193      kRlzTempHklm);
194
195  base::win::RegKey hklm;
196  ASSERT_EQ(ERROR_SUCCESS, hklm.Create(HKEY_CURRENT_USER,
197                                       temp_hklm_path.c_str(),
198                                       KEY_READ));
199
200  string16 temp_hkcu_path = base::StringPrintf(
201      L"%ls\\%ls",
202      RegistryOverrideManager::kTempTestKeyPath,
203      kRlzTempHkcu);
204
205  base::win::RegKey hkcu;
206  ASSERT_EQ(ERROR_SUCCESS, hkcu.Create(HKEY_CURRENT_USER,
207                                       temp_hkcu_path.c_str(),
208                                       KEY_READ));
209
210  rlz_lib::InitializeTempHivesForTesting(hklm, hkcu);
211
212  // Its important to override HKLM before HKCU because of the registry
213  // initialization performed above.
214  override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE, kRlzTempHklm);
215  override_manager_.OverrideRegistry(HKEY_CURRENT_USER, kRlzTempHkcu);
216#elif defined(OS_MACOSX)
217  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
218  rlz_lib::testing::SetRlzStoreDirectory(temp_dir_.path());
219#endif
220
221  // Make sure a non-organic brand code is set in the registry or the RLZTracker
222  // is pretty much a no-op.
223  SetMainBrand("TEST");
224  SetReactivationBrand("");
225}
226
227void RlzLibTest::TearDown() {
228#if defined(OS_MACOSX)
229  rlz_lib::testing::SetRlzStoreDirectory(FilePath());
230#endif
231  testing::Test::TearDown();
232}
233
234void RlzLibTest::SetMainBrand(const char* brand) {
235#if defined(OS_WIN)
236  SetRegistryBrandValue(google_update::kRegRLZBrandField, brand);
237#elif defined(OS_MACOSX)
238  brand_override_.reset(new google_util::BrandForTesting(brand));
239#endif
240  std::string check_brand;
241  google_util::GetBrand(&check_brand);
242  EXPECT_EQ(brand, check_brand);
243}
244
245void RlzLibTest::SetReactivationBrand(const char* brand) {
246  // TODO(thakis): Reactivation doesn't exist on Mac yet.
247#if defined(OS_WIN)
248  SetRegistryBrandValue(google_update::kRegRLZReactivationBrandField, brand);
249  std::string check_brand;
250  google_util::GetReactivationBrand(&check_brand);
251  EXPECT_EQ(brand, check_brand);
252#endif
253}
254
255#if defined(OS_WIN)
256void RlzLibTest::SetRegistryBrandValue(const wchar_t* name,
257                                       const char* brand) {
258  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
259  string16 reg_path = dist->GetStateKey();
260  RegKey key(HKEY_CURRENT_USER, reg_path.c_str(), KEY_SET_VALUE);
261  if (*brand == 0) {
262    LONG result = key.DeleteValue(name);
263    ASSERT_TRUE(ERROR_SUCCESS == result || ERROR_FILE_NOT_FOUND == result);
264  } else {
265    string16 brand16 = ASCIIToUTF16(brand);
266    ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name, brand16.c_str()));
267  }
268}
269#endif
270
271void RlzLibTest::SimulateOmniboxUsage() {
272  tracker_.Observe(chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
273                   content::NotificationService::AllSources(),
274                   content::Details<AutocompleteLog>(NULL));
275}
276
277void RlzLibTest::SimulateHomepageUsage() {
278  scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
279  entry->SetPageID(0);
280  entry->SetTransitionType(content::PAGE_TRANSITION_HOME_PAGE);
281  tracker_.Observe(content::NOTIFICATION_NAV_ENTRY_PENDING,
282                   content::NotificationService::AllSources(),
283                   content::Details<NavigationEntry>(entry.get()));
284}
285
286void RlzLibTest::InvokeDelayedInit() {
287  tracker_.DelayedInit();
288}
289
290void RlzLibTest::ExpectEventRecorded(const char* event_name, bool expected) {
291  char cgi[rlz_lib::kMaxCgiLength];
292  GetProductEventsAsCgi(rlz_lib::CHROME, cgi, arraysize(cgi));
293  if (expected) {
294    EXPECT_STR_CONTAINS(cgi, event_name);
295  } else {
296    EXPECT_STR_NOT_CONTAIN(cgi, event_name);
297  }
298}
299
300void RlzLibTest::ExpectRlzPingSent(bool expected) {
301  std::string brand;
302  google_util::GetBrand(&brand);
303  EXPECT_EQ(expected, tracker_.was_ping_sent_for_brand(brand.c_str()));
304}
305
306void RlzLibTest::ExpectReactivationRlzPingSent(bool expected) {
307  std::string brand;
308  google_util::GetReactivationBrand(&brand);
309  EXPECT_EQ(expected, tracker_.was_ping_sent_for_brand(brand.c_str()));
310}
311
312// The events that affect the different RLZ scenarios are the following:
313//
314//  A: the user starts chrome for the first time
315//  B: the user stops chrome
316//  C: the user start a subsequent time
317//  D: the user stops chrome again
318//  I: the RLZTracker::DelayedInit() method is invoked
319//  X: the user performs a search using the omnibox
320//  Y: the user performs a search using the home page
321//
322// The events A to D happen in chronological order, but the other events
323// may happen at any point between A-B or C-D, in no particular order.
324//
325// The visible results of the scenarios are:
326//
327//  C1I event is recorded
328//  C2I event is recorded
329//  C1F event is recorded
330//  C2F event is recorded
331//  C1S event is recorded
332//  C2S event is recorded
333//  RLZ ping sent
334//
335//  On Mac, C5 / C6 are sent instead of C1 / C2.
336//
337// Variations on the above scenarios:
338//
339//  - if the delay specified to InitRlzDelayed() is negative, then the RLZ
340//    ping should be sent out at the time of event X and not wait for I
341//
342// Also want to test that pre-warming the RLZ string cache works correctly.
343
344#if !defined(OS_MACOSX)
345const char kC1I[] = "C1I";
346const char kC1S[] = "C1S";
347const char kC1F[] = "C1F";
348
349const char kC2I[] = "C2I";
350const char kC2S[] = "C2S";
351const char kC2F[] = "C2F";
352#else
353const char kC1I[] = "C5I";
354const char kC1S[] = "C5S";
355const char kC1F[] = "C5F";
356
357const char kC2I[] = "C6I";
358const char kC2S[] = "C6S";
359const char kC2F[] = "C6F";
360#endif
361
362TEST_F(RlzLibTest, RecordProductEvent) {
363  RLZTracker::RecordProductEvent(rlz_lib::CHROME, RLZTracker::CHROME_OMNIBOX,
364                                 rlz_lib::FIRST_SEARCH);
365
366  ExpectEventRecorded(kC1F, true);
367}
368
369TEST_F(RlzLibTest, QuickStopAfterStart) {
370  RLZTracker::InitRlzDelayed(true, 20, true, true, true);
371
372  // Omnibox events.
373  ExpectEventRecorded(kC1I, false);
374  ExpectEventRecorded(kC1S, false);
375  ExpectEventRecorded(kC1F, false);
376
377  // Home page events.
378  ExpectEventRecorded(kC2I, false);
379  ExpectEventRecorded(kC2S, false);
380  ExpectEventRecorded(kC2F, false);
381
382  ExpectRlzPingSent(false);
383}
384
385TEST_F(RlzLibTest, DelayedInitOnly) {
386  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
387  InvokeDelayedInit();
388
389  // Omnibox events.
390  ExpectEventRecorded(kC1I, true);
391  ExpectEventRecorded(kC1S, true);
392  ExpectEventRecorded(kC1F, false);
393
394  // Home page events.
395  ExpectEventRecorded(kC2I, true);
396  ExpectEventRecorded(kC2S, true);
397  ExpectEventRecorded(kC2F, false);
398
399  ExpectRlzPingSent(true);
400}
401
402TEST_F(RlzLibTest, DelayedInitOnlyGoogleAsStartup) {
403  RLZTracker::InitRlzDelayed(true, 20, false, false, true);
404  InvokeDelayedInit();
405
406  // Omnibox events.
407  ExpectEventRecorded(kC1I, true);
408  ExpectEventRecorded(kC1S, false);
409  ExpectEventRecorded(kC1F, false);
410
411  // Home page events.
412  ExpectEventRecorded(kC2I, true);
413  ExpectEventRecorded(kC2S, true);
414  ExpectEventRecorded(kC2F, true);
415
416  ExpectRlzPingSent(true);
417}
418
419TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRunNoRlzStrings) {
420  RLZTracker::InitRlzDelayed(false, 20, true, true, false);
421  InvokeDelayedInit();
422
423  // Omnibox events.
424  ExpectEventRecorded(kC1I, true);
425  ExpectEventRecorded(kC1S, true);
426  ExpectEventRecorded(kC1F, false);
427
428  // Home page events.
429  ExpectEventRecorded(kC2I, true);
430  ExpectEventRecorded(kC2S, true);
431  ExpectEventRecorded(kC2F, false);
432
433  ExpectRlzPingSent(true);
434}
435
436TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRunNoRlzStringsGoogleAsStartup) {
437  RLZTracker::InitRlzDelayed(false, 20, false, false, true);
438  InvokeDelayedInit();
439
440  // Omnibox events.
441  ExpectEventRecorded(kC1I, true);
442  ExpectEventRecorded(kC1S, false);
443  ExpectEventRecorded(kC1F, false);
444
445  // Home page events.
446  ExpectEventRecorded(kC2I, true);
447  ExpectEventRecorded(kC2S, true);
448  ExpectEventRecorded(kC2F, true);
449
450  ExpectRlzPingSent(true);
451}
452
453TEST_F(RlzLibTest, DelayedInitOnlyNoFirstRun) {
454  // Set some dummy RLZ strings to simulate that we already ran before and
455  // performed a successful ping to the RLZ server.
456  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, kOmniboxRlzString);
457  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_HOME_PAGE, kHomepageRlzString);
458
459  RLZTracker::InitRlzDelayed(false, 20, true, true, true);
460  InvokeDelayedInit();
461
462  // Omnibox events.
463  ExpectEventRecorded(kC1I, true);
464  ExpectEventRecorded(kC1S, false);
465  ExpectEventRecorded(kC1F, false);
466
467  // Home page events.
468  ExpectEventRecorded(kC2I, true);
469  ExpectEventRecorded(kC2S, false);
470  ExpectEventRecorded(kC2F, true);
471
472  ExpectRlzPingSent(true);
473}
474
475TEST_F(RlzLibTest, DelayedInitOnlyNoGoogleDefaultSearchOrHomepageOrStartup) {
476  RLZTracker::InitRlzDelayed(true, 20, false, false, false);
477  InvokeDelayedInit();
478
479  // Omnibox events.
480  ExpectEventRecorded(kC1I, true);
481  ExpectEventRecorded(kC1S, false);
482  ExpectEventRecorded(kC1F, false);
483
484  // Home page events.
485  ExpectEventRecorded(kC2I, true);
486  ExpectEventRecorded(kC2S, false);
487  ExpectEventRecorded(kC2F, false);
488
489  ExpectRlzPingSent(true);
490}
491
492TEST_F(RlzLibTest, OmniboxUsageOnly) {
493  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
494  SimulateOmniboxUsage();
495
496  // Omnibox events.
497  ExpectEventRecorded(kC1I, false);
498  ExpectEventRecorded(kC1S, false);
499  ExpectEventRecorded(kC1F, true);
500
501  // Home page events.
502  ExpectEventRecorded(kC2I, false);
503  ExpectEventRecorded(kC2S, false);
504  ExpectEventRecorded(kC2F, false);
505
506  ExpectRlzPingSent(false);
507}
508
509TEST_F(RlzLibTest, HomepageUsageOnly) {
510  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
511  SimulateHomepageUsage();
512
513  // Omnibox events.
514  ExpectEventRecorded(kC1I, false);
515  ExpectEventRecorded(kC1S, false);
516  ExpectEventRecorded(kC1F, false);
517
518  // Home page events.
519  ExpectEventRecorded(kC2I, false);
520  ExpectEventRecorded(kC2S, false);
521  ExpectEventRecorded(kC2F, true);
522
523  ExpectRlzPingSent(false);
524}
525
526TEST_F(RlzLibTest, UsageBeforeDelayedInit) {
527  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
528  SimulateOmniboxUsage();
529  SimulateHomepageUsage();
530  InvokeDelayedInit();
531
532  // Omnibox events.
533  ExpectEventRecorded(kC1I, true);
534  ExpectEventRecorded(kC1S, true);
535  ExpectEventRecorded(kC1F, true);
536
537  // Home page events.
538  ExpectEventRecorded(kC2I, true);
539  ExpectEventRecorded(kC2S, true);
540  ExpectEventRecorded(kC2F, true);
541
542  ExpectRlzPingSent(true);
543}
544
545TEST_F(RlzLibTest, OmniboxUsageAfterDelayedInit) {
546  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
547  InvokeDelayedInit();
548  SimulateOmniboxUsage();
549  SimulateHomepageUsage();
550
551  // Omnibox events.
552  ExpectEventRecorded(kC1I, true);
553  ExpectEventRecorded(kC1S, true);
554  ExpectEventRecorded(kC1F, true);
555
556  // Home page events.
557  ExpectEventRecorded(kC2I, true);
558  ExpectEventRecorded(kC2S, true);
559  ExpectEventRecorded(kC2F, true);
560
561  ExpectRlzPingSent(true);
562}
563
564TEST_F(RlzLibTest, OmniboxUsageSendsPingWhenDelayNegative) {
565  RLZTracker::InitRlzDelayed(true, -20, true, true, false);
566  SimulateOmniboxUsage();
567
568  // Omnibox events.
569  ExpectEventRecorded(kC1I, true);
570  ExpectEventRecorded(kC1S, true);
571  ExpectEventRecorded(kC1F, true);
572
573  // Home page events.
574  ExpectEventRecorded(kC2I, true);
575  ExpectEventRecorded(kC2S, true);
576  ExpectEventRecorded(kC2F, false);
577
578  ExpectRlzPingSent(true);
579}
580
581TEST_F(RlzLibTest, HomepageUsageDoesNotSendPingWhenDelayNegative) {
582  RLZTracker::InitRlzDelayed(true, -20, true, true, false);
583  SimulateHomepageUsage();
584
585  // Omnibox events.
586  ExpectEventRecorded(kC1I, false);
587  ExpectEventRecorded(kC1S, false);
588  ExpectEventRecorded(kC1F, false);
589
590  // Home page events.
591  ExpectEventRecorded(kC2I, false);
592  ExpectEventRecorded(kC2S, false);
593  ExpectEventRecorded(kC2F, true);
594
595  ExpectRlzPingSent(false);
596}
597
598TEST_F(RlzLibTest, StartupUsageDoesNotSendPingWhenDelayNegative) {
599  RLZTracker::InitRlzDelayed(true, -20, true, false, true);
600  SimulateHomepageUsage();
601
602  // Omnibox events.
603  ExpectEventRecorded(kC1I, false);
604  ExpectEventRecorded(kC1S, false);
605  ExpectEventRecorded(kC1F, false);
606
607  // Home page events.
608  ExpectEventRecorded(kC2I, false);
609  ExpectEventRecorded(kC2S, false);
610  ExpectEventRecorded(kC2F, true);
611
612  ExpectRlzPingSent(false);
613}
614
615TEST_F(RlzLibTest, GetAccessPointRlzOnIoThread) {
616  // Set dummy RLZ string.
617  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, kOmniboxRlzString);
618
619  string16 rlz;
620
621  tracker_.set_assume_not_ui_thread(true);
622  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
623  EXPECT_STREQ(kOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
624}
625
626TEST_F(RlzLibTest, GetAccessPointRlzNotOnIoThread) {
627  // Set dummy RLZ string.
628  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, kOmniboxRlzString);
629
630  string16 rlz;
631
632  tracker_.set_assume_not_ui_thread(false);
633  EXPECT_FALSE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
634}
635
636TEST_F(RlzLibTest, GetAccessPointRlzIsCached) {
637  // Set dummy RLZ string.
638  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, kOmniboxRlzString);
639
640  string16 rlz;
641
642  tracker_.set_assume_not_ui_thread(false);
643  EXPECT_FALSE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
644
645  tracker_.set_assume_not_ui_thread(true);
646  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
647  EXPECT_STREQ(kOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
648
649  tracker_.set_assume_not_ui_thread(false);
650  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
651  EXPECT_STREQ(kOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
652}
653
654TEST_F(RlzLibTest, PingUpdatesRlzCache) {
655  // Set dummy RLZ string.
656  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, kOmniboxRlzString);
657  rlz_lib::SetAccessPointRlz(RLZTracker::CHROME_HOME_PAGE, kHomepageRlzString);
658
659  string16 rlz;
660
661  // Prime the cache.
662  tracker_.set_assume_not_ui_thread(true);
663
664  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
665  EXPECT_STREQ(kOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
666  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(
667        RLZTracker::CHROME_HOME_PAGE, &rlz));
668  EXPECT_STREQ(kHomepageRlzString, UTF16ToUTF8(rlz).c_str());
669
670  // Make sure cache is valid.
671  tracker_.set_assume_not_ui_thread(false);
672
673  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
674  EXPECT_STREQ(kOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
675  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(
676        RLZTracker::CHROME_HOME_PAGE, &rlz));
677  EXPECT_STREQ(kHomepageRlzString, UTF16ToUTF8(rlz).c_str());
678
679  // Perform ping.
680  tracker_.set_assume_not_ui_thread(true);
681  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
682  InvokeDelayedInit();
683  ExpectRlzPingSent(true);
684
685  // Make sure cache is now updated.
686  tracker_.set_assume_not_ui_thread(false);
687
688  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz));
689  EXPECT_STREQ(kNewOmniboxRlzString, UTF16ToUTF8(rlz).c_str());
690  EXPECT_TRUE(RLZTracker::GetAccessPointRlz(
691        RLZTracker::CHROME_HOME_PAGE, &rlz));
692  EXPECT_STREQ(kNewHomepageRlzString, UTF16ToUTF8(rlz).c_str());
693}
694
695TEST_F(RlzLibTest, ObserveHandlesBadArgs) {
696  scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
697  entry->SetPageID(0);
698  entry->SetTransitionType(content::PAGE_TRANSITION_LINK);
699  tracker_.Observe(content::NOTIFICATION_NAV_ENTRY_PENDING,
700                   content::NotificationService::AllSources(),
701                   content::Details<NavigationEntry>(NULL));
702  tracker_.Observe(content::NOTIFICATION_NAV_ENTRY_PENDING,
703                   content::NotificationService::AllSources(),
704                   content::Details<NavigationEntry>(entry.get()));
705}
706
707// TODO(thakis): Reactivation doesn't exist on Mac yet.
708#if defined(OS_WIN)
709TEST_F(RlzLibTest, ReactivationNonOrganicNonOrganic) {
710  SetReactivationBrand("REAC");
711
712  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
713  InvokeDelayedInit();
714
715  ExpectRlzPingSent(true);
716  ExpectReactivationRlzPingSent(true);
717}
718
719TEST_F(RlzLibTest, ReactivationOrganicNonOrganic) {
720  SetMainBrand("GGLS");
721  SetReactivationBrand("REAC");
722
723  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
724  InvokeDelayedInit();
725
726  ExpectRlzPingSent(false);
727  ExpectReactivationRlzPingSent(true);
728}
729
730TEST_F(RlzLibTest, ReactivationNonOrganicOrganic) {
731  SetMainBrand("TEST");
732  SetReactivationBrand("GGLS");
733
734  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
735  InvokeDelayedInit();
736
737  ExpectRlzPingSent(true);
738  ExpectReactivationRlzPingSent(false);
739}
740
741TEST_F(RlzLibTest, ReactivationOrganicOrganic) {
742  SetMainBrand("GGLS");
743  SetReactivationBrand("GGRS");
744
745  RLZTracker::InitRlzDelayed(true, 20, true, true, false);
746  InvokeDelayedInit();
747
748  ExpectRlzPingSent(false);
749  ExpectReactivationRlzPingSent(false);
750}
751#endif  // defined(OS_WIN)
752