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