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