Home | History | Annotate | Download | only in google
      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/google/google_search_counter.h"
      6 #include "chrome/browser/google/google_search_metrics.h"
      7 #include "content/public/browser/navigation_controller.h"
      8 #include "content/public/browser/navigation_details.h"
      9 #include "content/public/browser/navigation_entry.h"
     10 #include "content/public/browser/notification_service.h"
     11 #include "content/public/browser/notification_types.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace {
     16 
     17 class MockSearchMetrics : public GoogleSearchMetrics {
     18  public:
     19   MOCK_CONST_METHOD1(RecordGoogleSearch,
     20       void(GoogleSearchMetrics::AccessPoint ap));
     21 };
     22 
     23 }  // namespace
     24 
     25 class GoogleSearchCounterTest : public testing::Test {
     26  protected:
     27   GoogleSearchCounterTest();
     28   virtual ~GoogleSearchCounterTest();
     29 
     30   // testing::Test
     31   virtual void SetUp();
     32   virtual void TearDown();
     33 
     34   // Test if |url| is a Google search for specific types. When |is_omnibox| is
     35   // true, this method will append Omnibox identifiers to the simulated URL
     36   // navigation. If |expected_metric| is set and not AP_BOUNDARY, we'll also use
     37   // the Search Metrics mock class to ensure that the type of metric recorded is
     38   // correct. Note that when |expected_metric| is AP_BOUNDARY, we strictly
     39   // forbid any metrics from being logged at all. See implementation below for
     40   // details.
     41   void TestGoogleSearch(const std::string& url,
     42                         bool is_omnibox,
     43                         GoogleSearchMetrics::AccessPoint expected_metric);
     44 
     45  private:
     46   void ExpectMetricsLogged(GoogleSearchMetrics::AccessPoint ap);
     47 
     48   // Weak ptr. Actual instance owned by GoogleSearchCounter.
     49   ::testing::StrictMock<MockSearchMetrics>* mock_search_metrics_;
     50 };
     51 
     52 GoogleSearchCounterTest::GoogleSearchCounterTest()
     53     : mock_search_metrics_(NULL) {
     54 }
     55 
     56 GoogleSearchCounterTest::~GoogleSearchCounterTest() {
     57 }
     58 
     59 void GoogleSearchCounterTest::SetUp() {
     60   // Keep a weak ptr to MockSearchMetrics so we can run expectations. The
     61   // GoogleSearchCounter singleton will own and clean up MockSearchMetrics.
     62   mock_search_metrics_ = new ::testing::StrictMock<MockSearchMetrics>;
     63   GoogleSearchCounter::GetInstance()->SetSearchMetricsForTesting(
     64       mock_search_metrics_);
     65 }
     66 
     67 void GoogleSearchCounterTest::TearDown() {
     68   mock_search_metrics_ = NULL;
     69 }
     70 
     71 void GoogleSearchCounterTest::TestGoogleSearch(
     72     const std::string& url,
     73     bool is_omnibox,
     74     GoogleSearchMetrics::AccessPoint expected_metric) {
     75   content::LoadCommittedDetails details;
     76   scoped_ptr<content::NavigationEntry> entry(
     77       content::NavigationEntry::Create());
     78   if (is_omnibox)
     79     entry->SetTransitionType(content::PAGE_TRANSITION_GENERATED);
     80   entry->SetURL(GURL(url));
     81   details.entry = entry.get();
     82 
     83   // Since the internal mocked metrics object is strict, if |expect_metrics| is
     84   // false, the absence of this call to ExpectMetricsLogged will be noticed and
     85   // cause the test to complain, as expected. We use this behaviour to test
     86   // negative test cases (such as bad searches).
     87   if (expected_metric != GoogleSearchMetrics::AP_BOUNDARY)
     88     ExpectMetricsLogged(expected_metric);
     89 
     90   // For now we don't care about the notification source, but when we start
     91   // listening for additional access points, we will have to pass in a valid
     92   // controller.
     93   GoogleSearchCounter::GetInstance()->Observe(
     94       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
     95       content::Source<content::NavigationController>(NULL),
     96       content::Details<content::LoadCommittedDetails>(&details));
     97 }
     98 
     99 void GoogleSearchCounterTest::ExpectMetricsLogged(
    100     GoogleSearchMetrics::AccessPoint ap) {
    101   EXPECT_CALL(*mock_search_metrics_, RecordGoogleSearch(ap)).Times(1);
    102 }
    103 
    104 TEST_F(GoogleSearchCounterTest, EmptySearch) {
    105   TestGoogleSearch(std::string(), false, GoogleSearchMetrics::AP_BOUNDARY);
    106 }
    107 
    108 TEST_F(GoogleSearchCounterTest, GoodOmniboxSearch) {
    109   TestGoogleSearch("http://www.google.com/search?q=something", true,
    110                    GoogleSearchMetrics::AP_OMNIBOX);
    111 }
    112 
    113 TEST_F(GoogleSearchCounterTest, BadOmniboxSearch) {
    114   TestGoogleSearch("http://www.google.com/search?other=something", true,
    115                    GoogleSearchMetrics::AP_BOUNDARY);
    116 }
    117 
    118 TEST_F(GoogleSearchCounterTest, EmptyOmniboxSearch) {
    119   TestGoogleSearch(std::string(), true, GoogleSearchMetrics::AP_BOUNDARY);
    120 }
    121 
    122 TEST_F(GoogleSearchCounterTest, GoodOtherSearch) {
    123   TestGoogleSearch("http://www.google.com/search?q=something", false,
    124                    GoogleSearchMetrics::AP_OTHER);
    125 }
    126 
    127 TEST_F(GoogleSearchCounterTest, BadOtherSearch) {
    128   TestGoogleSearch("http://www.google.com/search?other=something", false,
    129                    GoogleSearchMetrics::AP_BOUNDARY);
    130 }
    131 
    132 TEST_F(GoogleSearchCounterTest, SearchAppSearch) {
    133   TestGoogleSearch("http://www.google.com/webhp?source=search_app#q=something",
    134                    false, GoogleSearchMetrics::AP_SEARCH_APP);
    135 }
    136 
    137 TEST_F(GoogleSearchCounterTest, SearchAppStart) {
    138   // Starting the search app takes you to this URL, but it should not be
    139   // considered an actual search event. Note that this URL is not considered an
    140   // actual search because it has no query string parameter ("q").
    141   TestGoogleSearch("http://www.google.com/webhp?source=search_app",
    142                    false, GoogleSearchMetrics::AP_BOUNDARY);
    143 }
    144 
    145 // TODO(stevet): Add a regression test to protect against the particular
    146 // bad-flags handling case that asvitkine pointed out.
    147