• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 <string>
6 
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_vector.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/search/instant_service.h"
11 #include "chrome/browser/search/instant_service_observer.h"
12 #include "chrome/browser/search/instant_unittest_base.h"
13 #include "chrome/browser/search/search.h"
14 #include "chrome/browser/ui/browser_instant_controller.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/navigation_controller.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_contents_observer.h"
22 
23 namespace chrome {
24 
25 namespace {
26 
27 class BrowserInstantControllerTest : public InstantUnitTestBase {
28  protected:
29   friend class FakeWebContentsObserver;
30 };
31 
32 const struct TabReloadTestCase {
33   const char* description;
34   const char* start_url;
35   bool start_in_instant_process;
36   bool should_reload;
37   bool end_in_instant_process;
38 } kTabReloadTestCases[] = {
39     {"Local Embedded NTP", chrome::kChromeSearchLocalNtpUrl,
40      true, true, true},
41     {"Remote Embedded NTP", "https://www.google.com/instant?strk",
42      true, true, false},
43     {"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms",
44      true, true, false},
45     {"Other NTP", "https://bar.com/instant?strk",
46      false, false, false}
47 };
48 
49 class FakeWebContentsObserver : public content::WebContentsObserver {
50  public:
FakeWebContentsObserver(BrowserInstantControllerTest * base_test,content::WebContents * contents)51   FakeWebContentsObserver(BrowserInstantControllerTest* base_test,
52                           content::WebContents* contents)
53       : WebContentsObserver(contents),
54         contents_(contents),
55         base_test_(base_test),
56         url_(contents->GetURL()),
57         num_reloads_(0) {}
58 
DidStartNavigationToPendingEntry(const GURL & url,content::NavigationController::ReloadType reload_type)59   virtual void DidStartNavigationToPendingEntry(
60       const GURL& url,
61       content::NavigationController::ReloadType reload_type) OVERRIDE {
62     // The tab reload event doesn't work with BrowserWithTestWindowTest.
63     // So we capture the DidStartNavigationToPendingEntry, and use the
64     // BrowserWithTestWindowTest::NavigateAndCommit to simulate the complete
65     // reload. Note that this will again trigger
66     // DidStartNavigationToPendingEntry, so we remove this as observer.
67     content::NavigationController* controller =
68         &web_contents()->GetController();
69     Observe(NULL);
70 
71     if (url_ == url)
72       num_reloads_++;
73 
74     base_test_->NavigateAndCommit(controller, url);
75   }
76 
num_reloads() const77   int num_reloads() const {
78     return num_reloads_;
79   }
80 
contents()81   content::WebContents* contents() {
82     return contents_;
83   }
84 
85  protected:
86   friend class BrowserInstantControllerTest;
87   FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest,
88                            DefaultSearchProviderChanged);
89   FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest,
90                            GoogleBaseURLUpdated);
91 
92  private:
93   content::WebContents* contents_;
94   BrowserInstantControllerTest* base_test_;
95   const GURL& url_;
96   int num_reloads_;
97 };
98 
TEST_F(BrowserInstantControllerTest,DefaultSearchProviderChanged)99 TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) {
100   size_t num_tests = arraysize(kTabReloadTestCases);
101   ScopedVector<FakeWebContentsObserver> observers;
102   for (size_t i = 0; i < num_tests; ++i) {
103     const TabReloadTestCase& test = kTabReloadTestCases[i];
104     AddTab(browser(), GURL(test.start_url));
105     content::WebContents* contents =
106       browser()->tab_strip_model()->GetActiveWebContents();
107 
108     // Validate initial instant state.
109     EXPECT_EQ(test.start_in_instant_process,
110         instant_service_->IsInstantProcess(
111           contents->GetRenderProcessHost()->GetID()))
112       << test.description;
113 
114     // Setup an observer to verify reload or absence thereof.
115     observers.push_back(new FakeWebContentsObserver(this, contents));
116   }
117 
118   SetDefaultSearchProvider("https://bar.com/");
119 
120   for (size_t i = 0; i < num_tests; ++i) {
121     FakeWebContentsObserver* observer = observers[i];
122     const TabReloadTestCase& test = kTabReloadTestCases[i];
123     content::WebContents* contents = observer->contents();
124 
125     // Validate final instant state.
126     EXPECT_EQ(test.end_in_instant_process,
127         instant_service_->IsInstantProcess(
128           contents->GetRenderProcessHost()->GetID()))
129       << test.description;
130 
131     // Ensure only the expected tabs(contents) reloaded.
132     EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
133       << test.description;
134   }
135 }
136 
TEST_F(BrowserInstantControllerTest,GoogleBaseURLUpdated)137 TEST_F(BrowserInstantControllerTest, GoogleBaseURLUpdated) {
138   const size_t num_tests = arraysize(kTabReloadTestCases);
139   ScopedVector<FakeWebContentsObserver> observers;
140   for (size_t i = 0; i < num_tests; ++i) {
141     const TabReloadTestCase& test = kTabReloadTestCases[i];
142     AddTab(browser(), GURL(test.start_url));
143     content::WebContents* contents =
144       browser()->tab_strip_model()->GetActiveWebContents();
145 
146     // Validate initial instant state.
147     EXPECT_EQ(test.start_in_instant_process,
148         instant_service_->IsInstantProcess(
149           contents->GetRenderProcessHost()->GetID()))
150       << test.description;
151 
152     // Setup an observer to verify reload or absence thereof.
153     observers.push_back(new FakeWebContentsObserver(this, contents));
154   }
155 
156   NotifyGoogleBaseURLUpdate("https://www.google.es/");
157 
158   for (size_t i = 0; i < num_tests; ++i) {
159     const TabReloadTestCase& test = kTabReloadTestCases[i];
160     FakeWebContentsObserver* observer = observers[i];
161     content::WebContents* contents = observer->contents();
162 
163     // Validate final instant state.
164     EXPECT_EQ(test.end_in_instant_process,
165         instant_service_->IsInstantProcess(
166           contents->GetRenderProcessHost()->GetID()))
167       << test.description;
168 
169     // Ensure only the expected tabs(contents) reloaded.
170     EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
171       << test.description;
172   }
173 }
174 
TEST_F(BrowserInstantControllerTest,BrowserWindowLifecycle)175 TEST_F(BrowserInstantControllerTest, BrowserWindowLifecycle) {
176   scoped_ptr<BrowserWindow> window(CreateBrowserWindow());
177   Browser::CreateParams params(profile(), chrome::HOST_DESKTOP_TYPE_NATIVE);
178   params.window = window.get();
179   scoped_ptr<Browser> browser(new Browser(params));
180   InstantServiceObserver* bic;
181   bic = browser->instant_controller();
182   EXPECT_TRUE(IsInstantServiceObserver(bic))
183     << "New BrowserInstantController should register as InstantServiceObserver";
184 
185   browser.reset(NULL);
186   window.reset(NULL);
187   EXPECT_FALSE(IsInstantServiceObserver(bic))
188     << "New BrowserInstantController should register as InstantServiceObserver";
189 }
190 
191 }  // namespace
192 
193 }  // namespace chrome
194