OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/callback.h" |
7 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
8 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
9 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
10 #include "base/win/windows_version.h" | 12 #include "base/win/windows_version.h" |
11 #include "content/common/frame_messages.h" | 13 #include "content/common/frame_messages.h" |
12 #include "content/common/ssl_status_serialization.h" | 14 #include "content/common/ssl_status_serialization.h" |
13 #include "content/common/view_messages.h" | 15 #include "content/common/view_messages.h" |
| 16 #include "content/public/browser/browser_context.h" |
| 17 #include "content/public/browser/browser_thread.h" |
14 #include "content/public/browser/native_web_keyboard_event.h" | 18 #include "content/public/browser/native_web_keyboard_event.h" |
| 19 #include "content/public/browser/render_frame_host.h" |
| 20 #include "content/public/browser/render_process_host.h" |
| 21 #include "content/public/browser/web_contents.h" |
15 #include "content/public/browser/web_ui_controller_factory.h" | 22 #include "content/public/browser/web_ui_controller_factory.h" |
16 #include "content/public/common/bindings_policy.h" | 23 #include "content/public/common/bindings_policy.h" |
| 24 #include "content/public/common/content_switches.h" |
17 #include "content/public/common/page_zoom.h" | 25 #include "content/public/common/page_zoom.h" |
18 #include "content/public/common/url_constants.h" | 26 #include "content/public/common/url_constants.h" |
19 #include "content/public/common/url_utils.h" | 27 #include "content/public/common/url_utils.h" |
20 #include "content/public/renderer/document_state.h" | 28 #include "content/public/renderer/document_state.h" |
21 #include "content/public/renderer/history_item_serialization.h" | 29 #include "content/public/renderer/history_item_serialization.h" |
22 #include "content/public/renderer/navigation_state.h" | 30 #include "content/public/renderer/navigation_state.h" |
| 31 #include "content/public/test/browser_test_utils.h" |
23 #include "content/public/test/render_view_test.h" | 32 #include "content/public/test/render_view_test.h" |
| 33 #include "content/public/test/test_utils.h" |
24 #include "content/renderer/render_view_impl.h" | 34 #include "content/renderer/render_view_impl.h" |
| 35 #include "content/shell/browser/shell.h" |
| 36 #include "content/shell/browser/shell_browser_context.h" |
25 #include "content/shell/browser/shell_content_browser_client.h" | 37 #include "content/shell/browser/shell_content_browser_client.h" |
26 #include "content/shell/common/shell_content_client.h" | 38 #include "content/shell/common/shell_content_client.h" |
| 39 #include "content/shell/renderer/shell_content_renderer_client.h" |
| 40 #include "content/test/content_browser_test.h" |
| 41 #include "content/test/content_browser_test_utils.h" |
27 #include "content/test/mock_keyboard.h" | 42 #include "content/test/mock_keyboard.h" |
28 #include "net/base/net_errors.h" | 43 #include "net/base/net_errors.h" |
29 #include "net/cert/cert_status_flags.h" | 44 #include "net/cert/cert_status_flags.h" |
| 45 #include "net/disk_cache/disk_cache.h" |
| 46 #include "net/http/failing_http_transaction_factory.h" |
| 47 #include "net/http/http_cache.h" |
| 48 #include "net/url_request/url_request_context.h" |
| 49 #include "net/url_request/url_request_context_getter.h" |
30 #include "testing/gtest/include/gtest/gtest.h" | 50 #include "testing/gtest/include/gtest/gtest.h" |
31 #include "third_party/WebKit/public/platform/WebData.h" | 51 #include "third_party/WebKit/public/platform/WebData.h" |
32 #include "third_party/WebKit/public/platform/WebHTTPBody.h" | 52 #include "third_party/WebKit/public/platform/WebHTTPBody.h" |
33 #include "third_party/WebKit/public/platform/WebString.h" | 53 #include "third_party/WebKit/public/platform/WebString.h" |
34 #include "third_party/WebKit/public/platform/WebURLError.h" | 54 #include "third_party/WebKit/public/platform/WebURLError.h" |
35 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 55 #include "third_party/WebKit/public/platform/WebURLResponse.h" |
36 #include "third_party/WebKit/public/web/WebDataSource.h" | 56 #include "third_party/WebKit/public/web/WebDataSource.h" |
37 #include "third_party/WebKit/public/web/WebFrame.h" | 57 #include "third_party/WebKit/public/web/WebFrame.h" |
38 #include "third_party/WebKit/public/web/WebHistoryItem.h" | 58 #include "third_party/WebKit/public/web/WebHistoryItem.h" |
39 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" | 59 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 virtual bool UseWebUIForURL(BrowserContext* browser_context, | 131 virtual bool UseWebUIForURL(BrowserContext* browser_context, |
112 const GURL& url) const OVERRIDE { | 132 const GURL& url) const OVERRIDE { |
113 return HasWebUIScheme(url); | 133 return HasWebUIScheme(url); |
114 } | 134 } |
115 virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context, | 135 virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context, |
116 const GURL& url) const OVERRIDE { | 136 const GURL& url) const OVERRIDE { |
117 return HasWebUIScheme(url); | 137 return HasWebUIScheme(url); |
118 } | 138 } |
119 }; | 139 }; |
120 | 140 |
121 } // namespace | |
122 | |
123 class RenderViewImplTest : public RenderViewTest { | 141 class RenderViewImplTest : public RenderViewTest { |
124 public: | 142 public: |
125 RenderViewImplTest() { | 143 RenderViewImplTest() { |
126 // Attach a pseudo keyboard device to this object. | 144 // Attach a pseudo keyboard device to this object. |
127 mock_keyboard_.reset(new MockKeyboard()); | 145 mock_keyboard_.reset(new MockKeyboard()); |
128 } | 146 } |
129 | 147 |
130 virtual ~RenderViewImplTest() {} | 148 virtual ~RenderViewImplTest() {} |
131 | 149 |
132 virtual void SetUp() OVERRIDE { | 150 virtual void SetUp() OVERRIDE { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 #else | 316 #else |
299 NOTIMPLEMENTED(); | 317 NOTIMPLEMENTED(); |
300 return L'\0'; | 318 return L'\0'; |
301 #endif | 319 #endif |
302 } | 320 } |
303 | 321 |
304 private: | 322 private: |
305 scoped_ptr<MockKeyboard> mock_keyboard_; | 323 scoped_ptr<MockKeyboard> mock_keyboard_; |
306 }; | 324 }; |
307 | 325 |
| 326 class TestShellContentRendererClient : public ShellContentRendererClient { |
| 327 public: |
| 328 TestShellContentRendererClient() |
| 329 : latest_error_valid_(false), |
| 330 latest_error_reason_(0), |
| 331 latest_error_stale_copy_in_cache_(false) {} |
| 332 |
| 333 virtual void GetNavigationErrorStrings( |
| 334 content::RenderView* render_view, |
| 335 blink::WebFrame* frame, |
| 336 const blink::WebURLRequest& failed_request, |
| 337 const blink::WebURLError& error, |
| 338 std::string* error_html, |
| 339 base::string16* error_description) OVERRIDE { |
| 340 if (error_html) |
| 341 *error_html = "A suffusion of yellow."; |
| 342 latest_error_valid_ = true; |
| 343 latest_error_reason_ = error.reason; |
| 344 latest_error_stale_copy_in_cache_ = error.staleCopyInCache; |
| 345 } |
| 346 |
| 347 bool GetLatestError(int* error_code, bool* stale_cache_entry_present) { |
| 348 if (latest_error_valid_) { |
| 349 *error_code = latest_error_reason_; |
| 350 *stale_cache_entry_present = latest_error_stale_copy_in_cache_; |
| 351 } |
| 352 return latest_error_valid_; |
| 353 } |
| 354 |
| 355 private: |
| 356 bool latest_error_valid_; |
| 357 int latest_error_reason_; |
| 358 bool latest_error_stale_copy_in_cache_; |
| 359 }; |
| 360 |
| 361 // Must be called on IO thread. |
| 362 void InterceptNetworkTransactions(net::URLRequestContextGetter* getter, |
| 363 net::Error error) { |
| 364 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 365 net::HttpCache* cache( |
| 366 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| 367 DCHECK(cache); |
| 368 scoped_ptr<net::FailingHttpTransactionFactory> factory( |
| 369 new net::FailingHttpTransactionFactory(cache->GetSession(), error)); |
| 370 // Throw away old version; since this is a browser test, there is no |
| 371 // need to restore the old state. |
| 372 cache->SetHttpNetworkTransactionFactoryForTesting( |
| 373 factory.PassAs<net::HttpTransactionFactory>()); |
| 374 } |
| 375 |
| 376 void CallOnUIThreadValidatingReturn(const base::Closure& callback, |
| 377 int rv) { |
| 378 DCHECK_EQ(net::OK, rv); |
| 379 BrowserThread::PostTask( |
| 380 BrowserThread::UI, FROM_HERE, callback); |
| 381 } |
| 382 |
| 383 // Must be called on IO thread. The callback will be called on |
| 384 // completion of cache clearing on the UI thread. |
| 385 void BackendClearCache(scoped_ptr<disk_cache::Backend*> backend, |
| 386 const base::Closure& callback, |
| 387 int rv) { |
| 388 DCHECK(*backend); |
| 389 DCHECK_EQ(net::OK, rv); |
| 390 (*backend)->DoomAllEntries( |
| 391 base::Bind(&CallOnUIThreadValidatingReturn, callback)); |
| 392 } |
| 393 |
| 394 // Must be called on IO thread. The callback will be called on |
| 395 // completion of cache clearing on the UI thread. |
| 396 void ClearCache(net::URLRequestContextGetter* getter, |
| 397 const base::Closure& callback) { |
| 398 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 399 net::HttpCache* cache( |
| 400 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| 401 DCHECK(cache); |
| 402 scoped_ptr<disk_cache::Backend*> backend(new disk_cache::Backend*); |
| 403 *backend = NULL; |
| 404 disk_cache::Backend** backend_ptr = backend.get(); |
| 405 |
| 406 net::CompletionCallback backend_callback( |
| 407 base::Bind(&BackendClearCache, base::Passed(backend.Pass()), callback)); |
| 408 |
| 409 // backend_ptr is valid until all copies of backend_callback go out |
| 410 // of scope. |
| 411 if (net::OK == cache->GetBackend(backend_ptr, backend_callback)) { |
| 412 // The call completed synchronously, so GetBackend didn't run the callback. |
| 413 backend_callback.Run(net::OK); |
| 414 } |
| 415 } |
| 416 |
| 417 } // namespace |
| 418 |
308 // Test that we get form state change notifications when input fields change. | 419 // Test that we get form state change notifications when input fields change. |
309 TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) { | 420 TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) { |
310 // Don't want any delay for form state sync changes. This will still post a | 421 // Don't want any delay for form state sync changes. This will still post a |
311 // message so updates will get coalesced, but as soon as we spin the message | 422 // message so updates will get coalesced, but as soon as we spin the message |
312 // loop, it will generate an update. | 423 // loop, it will generate an update. |
313 view()->set_send_content_state_immediately(true); | 424 view()->set_send_content_state_immediately(true); |
314 | 425 |
315 LoadHTML("<input type=\"text\" id=\"elt_text\"></input>"); | 426 LoadHTML("<input type=\"text\" id=\"elt_text\"></input>"); |
316 | 427 |
317 // We should NOT have gotten a form state change notification yet. | 428 // We should NOT have gotten a form state change notification yet. |
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2234 | 2345 |
2235 view()->webview()->clearFocusedNode(); | 2346 view()->webview()->clearFocusedNode(); |
2236 const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching( | 2347 const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching( |
2237 ViewHostMsg_FocusedNodeChanged::ID); | 2348 ViewHostMsg_FocusedNodeChanged::ID); |
2238 EXPECT_TRUE(msg3); | 2349 EXPECT_TRUE(msg3); |
2239 ViewHostMsg_FocusedNodeChanged::Read(msg3, ¶ms); | 2350 ViewHostMsg_FocusedNodeChanged::Read(msg3, ¶ms); |
2240 EXPECT_FALSE(params.a); | 2351 EXPECT_FALSE(params.a); |
2241 render_thread_->sink().ClearMessages(); | 2352 render_thread_->sink().ClearMessages(); |
2242 } | 2353 } |
2243 | 2354 |
| 2355 // For actual, browser side tests targetting code in RenderView |
| 2356 // or RenderViewImpl. |
| 2357 class RenderViewBrowserTest : public ContentBrowserTest { |
| 2358 public: |
| 2359 RenderViewBrowserTest() : renderer_client_(NULL) {} |
| 2360 |
| 2361 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
| 2362 // This method is needed to allow interaction with in-process renderer |
| 2363 // and use of a test ContentRendererClient. |
| 2364 command_line->AppendSwitch(switches::kSingleProcess); |
| 2365 } |
| 2366 |
| 2367 virtual void SetUp() OVERRIDE { |
| 2368 // Override setting of renderer client. |
| 2369 renderer_client_ = new TestShellContentRendererClient(); |
| 2370 SetContentRendererClient( |
| 2371 scoped_ptr<ContentRendererClient>(renderer_client_).Pass()); |
| 2372 |
| 2373 ContentBrowserTest::SetUp(); |
| 2374 } |
| 2375 |
| 2376 // Navigates to the given URL and waits for |num_navigations| to occur, and |
| 2377 // the title to change to |expected_title|. |
| 2378 void NavigateToURLAndWaitForTitle(const GURL& url, |
| 2379 const std::string& expected_title, |
| 2380 int num_navigations) { |
| 2381 content::TitleWatcher title_watcher( |
| 2382 shell()->web_contents(), base::ASCIIToUTF16(expected_title)); |
| 2383 |
| 2384 content::NavigateToURLBlockUntilNavigationsComplete( |
| 2385 shell(), url, num_navigations); |
| 2386 |
| 2387 EXPECT_EQ(base::ASCIIToUTF16(expected_title), |
| 2388 title_watcher.WaitAndGetTitle()); |
| 2389 } |
| 2390 |
| 2391 // Returns true if there is a valid error stored; in this case |
| 2392 // |*error_code| and |*stale_cache_entry_present| will be updated |
| 2393 // appropriately. |
| 2394 // Must be called after the renderer thread is created. |
| 2395 bool GetLatestErrorFromRendererClient( |
| 2396 int* error_code, bool* stale_cache_entry_present) { |
| 2397 bool result = false; |
| 2398 |
| 2399 PostTaskToInProcessRendererAndWait( |
| 2400 base::Bind(&RenderViewBrowserTest::GetLatestErrorFromRendererClient0, |
| 2401 renderer_client_, &result, error_code, |
| 2402 stale_cache_entry_present)); |
| 2403 return result; |
| 2404 } |
| 2405 |
| 2406 private: |
| 2407 // Must be run on renderer thread. |
| 2408 static void GetLatestErrorFromRendererClient0( |
| 2409 TestShellContentRendererClient* renderer_client, |
| 2410 bool* result, int* error_code, bool* stale_cache_entry_present) { |
| 2411 *result = renderer_client->GetLatestError( |
| 2412 error_code, stale_cache_entry_present); |
| 2413 } |
| 2414 |
| 2415 // Actually owned by the superclass, so safe to keep a bare pointer. |
| 2416 TestShellContentRendererClient* renderer_client_; |
| 2417 }; |
| 2418 |
| 2419 IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) { |
| 2420 ASSERT_TRUE(test_server()->Start()); |
| 2421 |
| 2422 // Load URL with "nocache" set, to create stale cache. |
| 2423 GURL test_url(test_server()->GetURL("files/nocache.html")); |
| 2424 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); |
| 2425 |
| 2426 // Reload same URL after forcing an error from the the network layer; |
| 2427 // confirm that the error page is told the cached copy exists. |
| 2428 int renderer_id = |
| 2429 shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(); |
| 2430 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 2431 ShellContentBrowserClient::Get()->browser_context()-> |
| 2432 GetRequestContextForRenderProcess(renderer_id); |
| 2433 BrowserThread::PostTask( |
| 2434 BrowserThread::IO, FROM_HERE, |
| 2435 base::Bind(&InterceptNetworkTransactions, url_request_context_getter, |
| 2436 net::ERR_FAILED)); |
| 2437 |
| 2438 // An error results in one completed navigation. |
| 2439 content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); |
| 2440 int error_code = net::OK; |
| 2441 bool stale_cache_entry_present = false; |
| 2442 ASSERT_TRUE(GetLatestErrorFromRendererClient( |
| 2443 &error_code, &stale_cache_entry_present)); |
| 2444 EXPECT_EQ(net::ERR_FAILED, error_code); |
| 2445 EXPECT_TRUE(stale_cache_entry_present); |
| 2446 |
| 2447 // Clear the cache and repeat; confirm lack of entry in cache reported. |
| 2448 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; |
| 2449 BrowserThread::PostTask( |
| 2450 BrowserThread::IO, FROM_HERE, |
| 2451 base::Bind(&ClearCache, url_request_context_getter, |
| 2452 runner->QuitClosure())); |
| 2453 runner->Run(); |
| 2454 |
| 2455 content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); |
| 2456 |
| 2457 error_code = net::OK; |
| 2458 stale_cache_entry_present = true; |
| 2459 ASSERT_TRUE(GetLatestErrorFromRendererClient( |
| 2460 &error_code, &stale_cache_entry_present)); |
| 2461 EXPECT_EQ(net::ERR_FAILED, error_code); |
| 2462 EXPECT_FALSE(stale_cache_entry_present); |
| 2463 } |
| 2464 |
2244 } // namespace content | 2465 } // namespace content |
OLD | NEW |