OLD | NEW |
(Empty) | |
| 1 // Copyright 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 <memory> |
| 6 |
| 7 #include "base/ios/device_util.h" |
| 8 #include "base/mac/scoped_nsobject.h" |
| 9 #include "base/run_loop.h" |
| 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "components/prefs/pref_service.h" |
| 12 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" |
| 13 #include "ios/chrome/browser/pref_names.h" |
| 14 #import "ios/chrome/browser/ui/preload_controller.h" |
| 15 #include "ios/web/public/test/test_web_thread_bundle.h" |
| 16 #include "net/url_request/test_url_fetcher_factory.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/platform_test.h" |
| 19 |
| 20 @interface PreloadController (ExposedForTesting) |
| 21 - (BOOL)shouldPreloadURL:(const GURL&)url; |
| 22 - (BOOL)isPrerenderingEnabled; |
| 23 - (BOOL)isPrefetchingEnabled; |
| 24 - (const GURL)urlToPrefetchURL:(const GURL&)url; |
| 25 - (BOOL)hasPrefetchedURL:(const GURL&)url; |
| 26 @end |
| 27 |
| 28 namespace { |
| 29 |
| 30 // Override NetworkChangeNotifier to simulate connection type changes for tests. |
| 31 class TestNetworkChangeNotifier : public net::NetworkChangeNotifier { |
| 32 public: |
| 33 TestNetworkChangeNotifier() |
| 34 : net::NetworkChangeNotifier(), |
| 35 connection_type_to_return_( |
| 36 net::NetworkChangeNotifier::CONNECTION_UNKNOWN) {} |
| 37 |
| 38 // Simulates a change of the connection type to |type|. This will notify any |
| 39 // objects that are NetworkChangeNotifiers. |
| 40 void SimulateNetworkConnectionChange( |
| 41 net::NetworkChangeNotifier::ConnectionType type) { |
| 42 connection_type_to_return_ = type; |
| 43 net::NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange(); |
| 44 base::RunLoop().RunUntilIdle(); |
| 45 } |
| 46 |
| 47 private: |
| 48 ConnectionType GetCurrentConnectionType() const override { |
| 49 return connection_type_to_return_; |
| 50 } |
| 51 |
| 52 // The currently simulated network connection type. If this is set to |
| 53 // CONNECTION_NONE, then NetworkChangeNotifier::IsOffline will return true. |
| 54 net::NetworkChangeNotifier::ConnectionType connection_type_to_return_; |
| 55 |
| 56 DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier); |
| 57 }; |
| 58 |
| 59 class PreloadControllerTest : public PlatformTest { |
| 60 protected: |
| 61 void SetUp() override { |
| 62 TestChromeBrowserState::Builder test_cbs_builder; |
| 63 chrome_browser_state_ = test_cbs_builder.Build(); |
| 64 // Set up a NetworkChangeNotifier so that the test can simulate Wi-Fi vs. |
| 65 // cellular connection. |
| 66 network_change_notifier_.reset(new TestNetworkChangeNotifier); |
| 67 |
| 68 test_url_fetcher_factory_.reset(new net::TestURLFetcherFactory()); |
| 69 |
| 70 controller_.reset([[PreloadController alloc] |
| 71 initWithBrowserState:chrome_browser_state_.get()]); |
| 72 }; |
| 73 |
| 74 // Set the "Preload webpages" setting to "Always". |
| 75 void PreloadWebpagesAlways() { |
| 76 chrome_browser_state_->GetPrefs()->SetBoolean( |
| 77 prefs::kNetworkPredictionEnabled, YES); |
| 78 chrome_browser_state_->GetPrefs()->SetBoolean( |
| 79 prefs::kNetworkPredictionWifiOnly, NO); |
| 80 } |
| 81 |
| 82 // Set the "Preload webpages" setting to "Only on Wi-Fi". |
| 83 void PreloadWebpagesWiFiOnly() { |
| 84 chrome_browser_state_->GetPrefs()->SetBoolean( |
| 85 prefs::kNetworkPredictionEnabled, YES); |
| 86 chrome_browser_state_->GetPrefs()->SetBoolean( |
| 87 prefs::kNetworkPredictionWifiOnly, YES); |
| 88 } |
| 89 |
| 90 // Set the "Preload webpages" setting to "Never". |
| 91 void PreloadWebpagesNever() { |
| 92 chrome_browser_state_->GetPrefs()->SetBoolean( |
| 93 prefs::kNetworkPredictionEnabled, NO); |
| 94 } |
| 95 |
| 96 void SimulateWiFiConnection() { |
| 97 network_change_notifier_->SimulateNetworkConnectionChange( |
| 98 net::NetworkChangeNotifier::CONNECTION_WIFI); |
| 99 } |
| 100 |
| 101 void SimulateCellularConnection() { |
| 102 network_change_notifier_->SimulateNetworkConnectionChange( |
| 103 net::NetworkChangeNotifier::CONNECTION_3G); |
| 104 } |
| 105 |
| 106 web::TestWebThreadBundle thread_bundle_; |
| 107 std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; |
| 108 std::unique_ptr<TestNetworkChangeNotifier> network_change_notifier_; |
| 109 std::unique_ptr<net::TestURLFetcherFactory> test_url_fetcher_factory_; |
| 110 base::scoped_nsobject<PreloadController> controller_; |
| 111 }; |
| 112 |
| 113 // Tests that the preload controller does not try to preload non-web urls. |
| 114 TEST_F(PreloadControllerTest, ShouldPreloadURL) { |
| 115 EXPECT_TRUE([controller_ shouldPreloadURL:GURL("http://www.google.com/")]); |
| 116 EXPECT_TRUE([controller_ shouldPreloadURL:GURL("https://www.google.com/")]); |
| 117 |
| 118 EXPECT_FALSE([controller_ shouldPreloadURL:GURL()]); |
| 119 EXPECT_FALSE([controller_ shouldPreloadURL:GURL("chrome://newtab")]); |
| 120 EXPECT_FALSE([controller_ shouldPreloadURL:GURL("about:flags")]); |
| 121 } |
| 122 |
| 123 TEST_F(PreloadControllerTest, TestIsPrerenderingEnabled_preloadAlways) { |
| 124 // With the "Preload Webpages" setting set to "Always", prerendering is |
| 125 // enabled regardless of network type. |
| 126 PreloadWebpagesAlways(); |
| 127 |
| 128 SimulateWiFiConnection(); |
| 129 EXPECT_TRUE([controller_ isPrerenderingEnabled] || |
| 130 ios::device_util::IsSingleCoreDevice() || |
| 131 !ios::device_util::RamIsAtLeast512Mb()); |
| 132 |
| 133 SimulateCellularConnection(); |
| 134 EXPECT_TRUE([controller_ isPrerenderingEnabled] || |
| 135 ios::device_util::IsSingleCoreDevice() || |
| 136 !ios::device_util::RamIsAtLeast512Mb()); |
| 137 } |
| 138 |
| 139 TEST_F(PreloadControllerTest, TestIsPrerenderingEnabled_preloadWiFiOnly) { |
| 140 // With the Chrome "Preload Webpages" setting set to "Only on Wi-Fi", |
| 141 // prerendering is enabled only on WiFi. |
| 142 PreloadWebpagesWiFiOnly(); |
| 143 |
| 144 SimulateWiFiConnection(); |
| 145 EXPECT_TRUE([controller_ isPrerenderingEnabled] || |
| 146 ios::device_util::IsSingleCoreDevice() || |
| 147 !ios::device_util::RamIsAtLeast512Mb()); |
| 148 |
| 149 SimulateCellularConnection(); |
| 150 EXPECT_FALSE([controller_ isPrerenderingEnabled]); |
| 151 } |
| 152 |
| 153 TEST_F(PreloadControllerTest, TestIsPrerenderingEnabled_preloadNever) { |
| 154 // With the Chrome "Preload Webpages" setting set to "Never", prerendering |
| 155 // is never enabled, regardless of the network type. |
| 156 PreloadWebpagesNever(); |
| 157 |
| 158 SimulateWiFiConnection(); |
| 159 EXPECT_FALSE([controller_ isPrerenderingEnabled]); |
| 160 |
| 161 SimulateCellularConnection(); |
| 162 EXPECT_FALSE([controller_ isPrerenderingEnabled]); |
| 163 } |
| 164 |
| 165 TEST_F(PreloadControllerTest, TestIsPrefetchingEnabled_preloadAlways) { |
| 166 // With the "Preload Webpages" setting set to "Always", prefetching is |
| 167 // always enabled. |
| 168 PreloadWebpagesAlways(); |
| 169 |
| 170 SimulateWiFiConnection(); |
| 171 EXPECT_TRUE([controller_ isPrefetchingEnabled]); |
| 172 |
| 173 SimulateCellularConnection(); |
| 174 EXPECT_TRUE([controller_ isPrefetchingEnabled]); |
| 175 } |
| 176 |
| 177 TEST_F(PreloadControllerTest, TestIsPrefetchingEnabled_preloadWiFiOnly) { |
| 178 // With the Chrome "Preload Webpages" setting set to "Only on Wi-Fi", |
| 179 // prefetching is enabled only on WiFi. |
| 180 PreloadWebpagesWiFiOnly(); |
| 181 |
| 182 SimulateWiFiConnection(); |
| 183 EXPECT_TRUE([controller_ isPrefetchingEnabled]); |
| 184 |
| 185 SimulateCellularConnection(); |
| 186 EXPECT_FALSE([controller_ isPrefetchingEnabled]); |
| 187 } |
| 188 |
| 189 TEST_F(PreloadControllerTest, TestIsPrefetchingEnabled_preloadNever) { |
| 190 // With the Chrome "Preload Webpages" setting set to "Never", prefetching |
| 191 // is never enabled, regardless of WiFi state. |
| 192 PreloadWebpagesNever(); |
| 193 |
| 194 SimulateWiFiConnection(); |
| 195 EXPECT_FALSE([controller_ isPrefetchingEnabled]); |
| 196 |
| 197 SimulateCellularConnection(); |
| 198 EXPECT_FALSE([controller_ isPrefetchingEnabled]); |
| 199 } |
| 200 |
| 201 TEST_F(PreloadControllerTest, TestPrefetchURL_transformURL) { |
| 202 PreloadWebpagesAlways(); |
| 203 |
| 204 GURL original("http://www.google.com/search?q=foo"); |
| 205 GURL expected("http://www.google.com/search?q=foo&pf=i"); |
| 206 [controller_ prefetchURL:original |
| 207 transition:ui::PAGE_TRANSITION_FROM_ADDRESS_BAR]; |
| 208 |
| 209 net::TestURLFetcher* url_fetcher = nil; |
| 210 url_fetcher = |
| 211 test_url_fetcher_factory_->GetFetcherByID(kPreloadControllerURLFetcherID); |
| 212 |
| 213 EXPECT_TRUE(url_fetcher); |
| 214 GURL actual = url_fetcher->GetOriginalURL(); |
| 215 EXPECT_EQ(expected, actual); |
| 216 } |
| 217 |
| 218 TEST_F(PreloadControllerTest, TestUrlToPrefetchURL_noParams) { |
| 219 GURL original("http://www.google.com/search"); |
| 220 GURL expected("http://www.google.com/search?pf=i"); |
| 221 GURL actual = [controller_ urlToPrefetchURL:original]; |
| 222 EXPECT_EQ(expected, actual); |
| 223 } |
| 224 |
| 225 TEST_F(PreloadControllerTest, TestUrlToPrefetchURL_params) { |
| 226 std::string urlString = |
| 227 std::string("http://www.google.com/search") |
| 228 .append("?q=legoland&oq=legol&aqs=chrome.0.0j69i57j0j5") |
| 229 .append("&sourceid=chrome-mobile&ie=UTF-8&hl=en-US"); |
| 230 GURL original(urlString); |
| 231 GURL expected(urlString + "&pf=i"); |
| 232 GURL actual = [controller_ urlToPrefetchURL:original]; |
| 233 EXPECT_EQ(expected, actual); |
| 234 } |
| 235 |
| 236 TEST_F(PreloadControllerTest, TestHasPrefetchedURL) { |
| 237 PreloadWebpagesAlways(); |
| 238 |
| 239 GURL first("http://www.google.com/search?q=first"); |
| 240 GURL second("http://www.google.com/search?q=second"); |
| 241 GURL bogus("http://www.google.com/search?q=bogus"); |
| 242 |
| 243 EXPECT_FALSE([controller_ hasPrefetchedURL:first]); |
| 244 EXPECT_FALSE([controller_ hasPrefetchedURL:second]); |
| 245 EXPECT_FALSE([controller_ hasPrefetchedURL:bogus]); |
| 246 |
| 247 // Prefetch |first| and verify it's the only one that returns true. |
| 248 [controller_ prefetchURL:first |
| 249 transition:ui::PAGE_TRANSITION_FROM_ADDRESS_BAR]; |
| 250 EXPECT_TRUE([controller_ hasPrefetchedURL:first]); |
| 251 EXPECT_FALSE([controller_ hasPrefetchedURL:second]); |
| 252 EXPECT_FALSE([controller_ hasPrefetchedURL:bogus]); |
| 253 |
| 254 // Prefetch |second| and verify it's the only one that returns true. |
| 255 [controller_ prefetchURL:second |
| 256 transition:ui::PAGE_TRANSITION_FROM_ADDRESS_BAR]; |
| 257 EXPECT_FALSE([controller_ hasPrefetchedURL:first]); |
| 258 EXPECT_TRUE([controller_ hasPrefetchedURL:second]); |
| 259 EXPECT_FALSE([controller_ hasPrefetchedURL:bogus]); |
| 260 } |
| 261 |
| 262 } // anonymous namespace |
OLD | NEW |