1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop.h"
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/google/google_search_counter.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/google/google_search_counter_android.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/prerender/prerender_manager.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/test/base/testing_profile.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/google/core/browser/google_search_metrics.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/navigation_controller.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/navigation_details.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/navigation_entry.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/notification_service.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/notification_types.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/test_browser_thread.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gmock/include/gmock/gmock.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MockSearchMetrics : public GoogleSearchMetrics {
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MOCK_CONST_METHOD2(RecordAndroidGoogleSearch,
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     void(AccessPoint ap, bool prerender_enabled));
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass GoogleSearchCounterAndroidTest : public testing::Test {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protected:
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GoogleSearchCounterAndroidTest();
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~GoogleSearchCounterAndroidTest();
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // testing::Test
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void SetUp();
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void TearDown();
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Test if |url| is a Google search for specific types. When |is_omnibox| is
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // true, this method will append Omnibox identifiers to the simulated URL
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // navigation. If |expected_metric| is set and not AP_BOUNDARY, we'll also use
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the Search Metrics mock class to ensure that the type of metric recorded is
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // correct. Note that when |expected_metric| is AP_BOUNDARY, we strictly
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // forbid any metrics from being logged at all. See implementation below for
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // details.
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TestGoogleSearch(const std::string& url,
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        bool is_omnibox,
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        GoogleSearchMetrics::AccessPoint expected_metric,
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        bool expected_prerender_enabled);
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ExpectMetricsLogged(GoogleSearchMetrics::AccessPoint ap,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           bool prerender_enabled);
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Needed to pass PrerenderManager's DCHECKs.
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::MessageLoop message_loop_;
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::TestBrowserThread ui_thread_;
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<TestingProfile> profile_;
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<GoogleSearchCounterAndroid> search_counter_;
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Weak ptr. Actual instance owned by GoogleSearchCounter.
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ::testing::StrictMock<MockSearchMetrics>* mock_search_metrics_;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
65116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGoogleSearchCounterAndroidTest::GoogleSearchCounterAndroidTest()
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : ui_thread_(content::BrowserThread::UI, &message_loop_),
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      profile_(new TestingProfile()),
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      search_counter_(new GoogleSearchCounterAndroid(profile_.get())),
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      mock_search_metrics_(NULL) {
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
72116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGoogleSearchCounterAndroidTest::~GoogleSearchCounterAndroidTest() {
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GoogleSearchCounterAndroidTest::SetUp() {
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Keep a weak ptr to MockSearchMetrics so we can run expectations. The
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // GoogleSearchCounter singleton will own and clean up MockSearchMetrics.
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mock_search_metrics_ = new ::testing::StrictMock<MockSearchMetrics>;
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GoogleSearchCounter::GetInstance()->SetSearchMetricsForTesting(
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      mock_search_metrics_);
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  prerender::PrerenderManager::SetMode(
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      prerender::PrerenderManager::PRERENDER_MODE_ENABLED);
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GoogleSearchCounterAndroidTest::TearDown() {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mock_search_metrics_ = NULL;
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GoogleSearchCounterAndroidTest::TestGoogleSearch(
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& url,
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool is_omnibox,
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GoogleSearchMetrics::AccessPoint expected_metric,
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool expected_prerender_enabled) {
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::LoadCommittedDetails details;
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<content::NavigationEntry> entry(
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::NavigationEntry::Create());
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (is_omnibox) {
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    entry->SetTransitionType(ui::PageTransitionFromInt(
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ui::PAGE_TRANSITION_GENERATED |
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  entry->SetURL(GURL(url));
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  details.entry = entry.get();
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Since the internal mocked metrics object is strict, if |expect_metrics| is
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // false, the absence of this call to ExpectMetricsLogged will be noticed and
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // cause the test to complain, as expected. We use this behaviour to test
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // negative test cases (such as bad searches).
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (expected_metric != GoogleSearchMetrics::AP_BOUNDARY)
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ExpectMetricsLogged(expected_metric, expected_prerender_enabled);
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // For now we don't care about the notification source, but when we start
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // listening for additional access points, we will have to pass in a valid
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // controller.
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  search_counter_->Observe(
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::Source<content::NavigationController>(NULL),
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::Details<content::LoadCommittedDetails>(&details));
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GoogleSearchCounterAndroidTest::ExpectMetricsLogged(
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GoogleSearchMetrics::AccessPoint ap, bool prerender_enabled) {
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*mock_search_metrics_,
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              RecordAndroidGoogleSearch(ap, prerender_enabled)).Times(1);
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
127116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, EmptySearch) {
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch(std::string(), false, GoogleSearchMetrics::AP_BOUNDARY,
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   true);
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
132116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, GoodOmniboxSearch) {
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/search?q=something", true,
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   GoogleSearchMetrics::AP_OMNIBOX, true);
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
137116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, BadOmniboxSearch) {
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/search?other=something", true,
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   GoogleSearchMetrics::AP_BOUNDARY, true);
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
142116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, EmptyOmniboxSearch) {
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch(std::string(), true, GoogleSearchMetrics::AP_BOUNDARY, true);
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
146116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, GoodOtherSearch) {
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/search?q=something", false,
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   GoogleSearchMetrics::AP_OTHER, true);
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, BadOtherSearch) {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/search?other=something", false,
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   GoogleSearchMetrics::AP_BOUNDARY, true);
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
156116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, SearchAppSearch) {
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/webhp?source=search_app#q=something",
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   false, GoogleSearchMetrics::AP_SEARCH_APP, true);
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
161116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, SearchAppStart) {
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Starting the search app takes you to this URL, but it should not be
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // considered an actual search event. Note that this URL is not considered an
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // actual search because it has no query string parameter ("q").
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/webhp?source=search_app",
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   false, GoogleSearchMetrics::AP_BOUNDARY, true);
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
169116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(GoogleSearchCounterAndroidTest, GoodOmniboxSearch_PrerenderDisabled) {
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  prerender::PrerenderManager::SetMode(
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestGoogleSearch("http://www.google.com/search?q=something", true,
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   GoogleSearchMetrics::AP_OMNIBOX, false);
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
175