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 "components/google/core/browser/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::PageTransitionFromInt(
     80         content::PAGE_TRANSITION_GENERATED |
     81             content::PAGE_TRANSITION_FROM_ADDRESS_BAR));
     82   }
     83   entry->SetURL(GURL(url));
     84   details.entry = entry.get();
     85 
     86   // Since the internal mocked metrics object is strict, if |expect_metrics| is
     87   // false, the absence of this call to ExpectMetricsLogged will be noticed and
     88   // cause the test to complain, as expected. We use this behaviour to test
     89   // negative test cases (such as bad searches).
     90   if (expected_metric != GoogleSearchMetrics::AP_BOUNDARY)
     91     ExpectMetricsLogged(expected_metric);
     92 
     93   // For now we don't care about the notification source, but when we start
     94   // listening for additional access points, we will have to pass in a valid
     95   // controller.
     96   GoogleSearchCounter::GetInstance()->Observe(
     97       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
     98       content::Source<content::NavigationController>(NULL),
     99       content::Details<content::LoadCommittedDetails>(&details));
    100 }
    101 
    102 void GoogleSearchCounterTest::ExpectMetricsLogged(
    103     GoogleSearchMetrics::AccessPoint ap) {
    104   EXPECT_CALL(*mock_search_metrics_, RecordGoogleSearch(ap)).Times(1);
    105 }
    106 
    107 TEST_F(GoogleSearchCounterTest, EmptySearch) {
    108   TestGoogleSearch(std::string(), false, GoogleSearchMetrics::AP_BOUNDARY);
    109 }
    110 
    111 TEST_F(GoogleSearchCounterTest, GoodOmniboxSearch) {
    112   TestGoogleSearch("http://www.google.com/search?q=something", true,
    113                    GoogleSearchMetrics::AP_OMNIBOX);
    114 }
    115 
    116 TEST_F(GoogleSearchCounterTest, BadOmniboxSearch) {
    117   TestGoogleSearch("http://www.google.com/search?other=something", true,
    118                    GoogleSearchMetrics::AP_BOUNDARY);
    119 }
    120 
    121 TEST_F(GoogleSearchCounterTest, EmptyOmniboxSearch) {
    122   TestGoogleSearch(std::string(), true, GoogleSearchMetrics::AP_BOUNDARY);
    123 }
    124 
    125 TEST_F(GoogleSearchCounterTest, GoodOtherSearch) {
    126   TestGoogleSearch("http://www.google.com/search?q=something", false,
    127                    GoogleSearchMetrics::AP_OTHER);
    128 }
    129 
    130 TEST_F(GoogleSearchCounterTest, BadOtherSearch) {
    131   TestGoogleSearch("http://www.google.com/search?other=something", false,
    132                    GoogleSearchMetrics::AP_BOUNDARY);
    133 }
    134 
    135 TEST_F(GoogleSearchCounterTest, SearchAppSearch) {
    136   TestGoogleSearch("http://www.google.com/webhp?source=search_app#q=something",
    137                    false, GoogleSearchMetrics::AP_SEARCH_APP);
    138 }
    139 
    140 TEST_F(GoogleSearchCounterTest, SearchAppStart) {
    141   // Starting the search app takes you to this URL, but it should not be
    142   // considered an actual search event. Note that this URL is not considered an
    143   // actual search because it has no query string parameter ("q").
    144   TestGoogleSearch("http://www.google.com/webhp?source=search_app",
    145                    false, GoogleSearchMetrics::AP_BOUNDARY);
    146 }
    147 
    148 // TODO(stevet): Add a regression test to protect against the particular
    149 // bad-flags handling case that asvitkine pointed out.
    150