OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <string> | 5 #include <string> |
6 | 6 |
| 7 #include "base/bind.h" |
7 #include "base/command_line.h" | 8 #include "base/command_line.h" |
8 #include "base/macros.h" | 9 #include "base/macros.h" |
9 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/app/chrome_command_ids.h" | 14 #include "chrome/app/chrome_command_ids.h" |
14 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
15 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h" | 16 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h" |
16 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert
est_util.h" | 17 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsert
est_util.h" |
(...skipping 10 matching lines...) Expand all Loading... |
27 #include "content/public/browser/browser_message_filter.h" | 28 #include "content/public/browser/browser_message_filter.h" |
28 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/navigation_controller.h" | 30 #include "content/public/browser/navigation_controller.h" |
30 #include "content/public/browser/navigation_entry.h" | 31 #include "content/public/browser/navigation_entry.h" |
31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
32 #include "content/public/browser/render_process_host.h" | 33 #include "content/public/browser/render_process_host.h" |
33 #include "content/public/browser/render_view_host.h" | 34 #include "content/public/browser/render_view_host.h" |
34 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
35 #include "content/public/test/browser_test_utils.h" | 36 #include "content/public/test/browser_test_utils.h" |
36 #include "content/public/test/test_utils.h" | 37 #include "content/public/test/test_utils.h" |
| 38 #include "net/base/load_flags.h" |
| 39 #include "net/url_request/url_request.h" |
| 40 #include "net/url_request/url_request_filter.h" |
| 41 #include "net/url_request/url_request_interceptor.h" |
37 #include "third_party/WebKit/public/web/WebContextMenuData.h" | 42 #include "third_party/WebKit/public/web/WebContextMenuData.h" |
38 #include "third_party/WebKit/public/web/WebInputEvent.h" | 43 #include "third_party/WebKit/public/web/WebInputEvent.h" |
39 | 44 |
40 using content::WebContents; | 45 using content::WebContents; |
41 | 46 |
42 namespace { | 47 namespace { |
43 | 48 |
44 class ContextMenuBrowserTest : public InProcessBrowserTest { | 49 class ContextMenuBrowserTest : public InProcessBrowserTest { |
45 public: | 50 public: |
46 ContextMenuBrowserTest() {} | 51 ContextMenuBrowserTest() {} |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 content::WebContents* tab = | 523 content::WebContents* tab = |
519 browser()->tab_strip_model()->GetActiveWebContents(); | 524 browser()->tab_strip_model()->GetActiveWebContents(); |
520 ThumbnailResponseWatcher watcher(tab->GetRenderProcessHost()); | 525 ThumbnailResponseWatcher watcher(tab->GetRenderProcessHost()); |
521 AttemptImageSearch(); | 526 AttemptImageSearch(); |
522 | 527 |
523 // The browser should receive a response from the renderer, because the | 528 // The browser should receive a response from the renderer, because the |
524 // renderer should not crash. | 529 // renderer should not crash. |
525 EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait()); | 530 EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait()); |
526 } | 531 } |
527 | 532 |
| 533 class LoadImageRequestInterceptor : public net::URLRequestInterceptor { |
| 534 public: |
| 535 LoadImageRequestInterceptor() : num_requests_(0), |
| 536 requests_to_wait_for_(-1), |
| 537 weak_factory_(this) { |
| 538 } |
| 539 |
| 540 ~LoadImageRequestInterceptor() override {} |
| 541 |
| 542 // net::URLRequestInterceptor implementation |
| 543 net::URLRequestJob* MaybeInterceptRequest( |
| 544 net::URLRequest* request, |
| 545 net::NetworkDelegate* network_delegate) const override { |
| 546 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 547 EXPECT_TRUE(request->load_flags() & net::LOAD_BYPASS_CACHE); |
| 548 content::BrowserThread::PostTask( |
| 549 content::BrowserThread::UI, FROM_HERE, |
| 550 base::Bind(&LoadImageRequestInterceptor::RequestCreated, |
| 551 weak_factory_.GetWeakPtr())); |
| 552 return nullptr; |
| 553 } |
| 554 |
| 555 void WaitForRequests(int requests_to_wait_for) { |
| 556 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 557 DCHECK_EQ(-1, requests_to_wait_for_); |
| 558 DCHECK(!run_loop_); |
| 559 |
| 560 if (num_requests_ >= requests_to_wait_for) |
| 561 return; |
| 562 |
| 563 requests_to_wait_for_ = requests_to_wait_for; |
| 564 run_loop_.reset(new base::RunLoop()); |
| 565 run_loop_->Run(); |
| 566 run_loop_.reset(); |
| 567 requests_to_wait_for_ = -1; |
| 568 EXPECT_EQ(num_requests_, requests_to_wait_for); |
| 569 } |
| 570 |
| 571 // It is up to the caller to wait until all relevant requests has been |
| 572 // created, either through calling WaitForRequests or some other manner, |
| 573 // before calling this method. |
| 574 int num_requests() const { |
| 575 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 576 return num_requests_; |
| 577 } |
| 578 |
| 579 private: |
| 580 void RequestCreated() { |
| 581 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 582 |
| 583 num_requests_++; |
| 584 if (num_requests_ == requests_to_wait_for_) |
| 585 run_loop_->Quit(); |
| 586 } |
| 587 |
| 588 // These are only used on the UI thread. |
| 589 int num_requests_; |
| 590 int requests_to_wait_for_; |
| 591 scoped_ptr<base::RunLoop> run_loop_; |
| 592 |
| 593 // This prevents any risk of flake if any test doesn't wait for a request |
| 594 // it sent. Mutable so it can be accessed from a const function. |
| 595 mutable base::WeakPtrFactory<LoadImageRequestInterceptor> weak_factory_; |
| 596 |
| 597 DISALLOW_COPY_AND_ASSIGN(LoadImageRequestInterceptor); |
| 598 }; |
| 599 |
| 600 class LoadImageBrowserTest : public InProcessBrowserTest { |
| 601 protected: |
| 602 void SetupAndLoadImagePage(const std::string& image_path) { |
| 603 // Go to a page with an image in it. The test server doesn't serve the image |
| 604 // with the right MIME type, so use a data URL to make a page containing it. |
| 605 GURL image_url(test_server()->GetURL(image_path)); |
| 606 GURL page("data:text/html,<img src='" + image_url.spec() + "'>"); |
| 607 ui_test_utils::NavigateToURL(browser(), page); |
| 608 } |
| 609 |
| 610 void AddLoadImageInterceptor(const std::string& image_path) { |
| 611 interceptor_ = new LoadImageRequestInterceptor(); |
| 612 scoped_ptr<net::URLRequestInterceptor> owned_interceptor(interceptor_); |
| 613 content::BrowserThread::PostTask( |
| 614 content::BrowserThread::IO, FROM_HERE, |
| 615 base::Bind(&LoadImageBrowserTest::AddInterceptorForURL, |
| 616 base::Unretained(this), |
| 617 GURL(test_server()->GetURL(image_path).spec()), |
| 618 base::Passed(&owned_interceptor))); |
| 619 } |
| 620 |
| 621 void AttemptImageLoad() { |
| 622 // Right-click where the image should be. |
| 623 // |menu_observer_| will cause the load-image menu item to be clicked. |
| 624 menu_observer_.reset(new ContextMenuNotificationObserver( |
| 625 IDC_CONTENT_CONTEXT_RELOAD_ORIGINAL_IMAGE)); |
| 626 content::WebContents* tab = |
| 627 browser()->tab_strip_model()->GetActiveWebContents(); |
| 628 content::SimulateMouseClickAt(tab, 0, blink::WebMouseEvent::ButtonRight, |
| 629 gfx::Point(15, 15)); |
| 630 } |
| 631 |
| 632 void AddInterceptorForURL( |
| 633 const GURL& url, scoped_ptr<net::URLRequestInterceptor> handler) { |
| 634 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 635 net::URLRequestFilter::GetInstance()->AddUrlInterceptor( |
| 636 url, handler.Pass()); |
| 637 } |
| 638 |
| 639 LoadImageRequestInterceptor* interceptor_; |
| 640 |
| 641 private: |
| 642 scoped_ptr<ContextMenuNotificationObserver> menu_observer_; |
| 643 }; |
| 644 |
| 645 IN_PROC_BROWSER_TEST_F(LoadImageBrowserTest, LoadImage) { |
| 646 static const char kValidImage[] = "files/load_image/image.png"; |
| 647 SetupAndLoadImagePage(kValidImage); |
| 648 AddLoadImageInterceptor(kValidImage); |
| 649 AttemptImageLoad(); |
| 650 interceptor_->WaitForRequests(1); |
| 651 EXPECT_EQ(1, interceptor_->num_requests()); |
| 652 } |
| 653 |
528 } // namespace | 654 } // namespace |
OLD | NEW |