Index: chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc |
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc |
index 0498a2cf6532f74bf6afa7604b71cbb52c2f10ac..823dbafd91146a952989ae94ee5928c5f2e6039d 100644 |
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc |
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc |
@@ -4,6 +4,7 @@ |
#include <string> |
+#include "base/bind.h" |
#include "base/command_line.h" |
#include "base/macros.h" |
#include "base/memory/ref_counted.h" |
@@ -34,6 +35,10 @@ |
#include "content/public/browser/web_contents.h" |
#include "content/public/test/browser_test_utils.h" |
#include "content/public/test/test_utils.h" |
+#include "net/base/load_flags.h" |
+#include "net/url_request/url_request.h" |
+#include "net/url_request/url_request_filter.h" |
+#include "net/url_request/url_request_interceptor.h" |
#include "third_party/WebKit/public/web/WebContextMenuData.h" |
#include "third_party/WebKit/public/web/WebInputEvent.h" |
@@ -525,4 +530,125 @@ IN_PROC_BROWSER_TEST_F(SearchByImageBrowserTest, ImageSearchWithCorruptImage) { |
EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait()); |
} |
+class ShowImageRequestInterceptor : public net::URLRequestInterceptor { |
+ public: |
+ ShowImageRequestInterceptor() : num_requests_(0), |
+ requests_to_wait_for_(-1), |
+ weak_factory_(this) { |
+ } |
+ |
+ ~ShowImageRequestInterceptor() override {} |
+ |
+ // net::URLRequestInterceptor implementation |
+ net::URLRequestJob* MaybeInterceptRequest( |
+ net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) const override { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
+ EXPECT_TRUE(request->load_flags() & net::LOAD_BYPASS_CACHE); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&ShowImageRequestInterceptor::RequestCreated, |
+ weak_factory_.GetWeakPtr())); |
+ return nullptr; |
+ } |
+ |
+ void WaitForRequests(int requests_to_wait_for) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ DCHECK_EQ(-1, requests_to_wait_for_); |
+ DCHECK(!run_loop_); |
+ |
+ if (num_requests_ >= requests_to_wait_for) |
+ return; |
+ |
+ requests_to_wait_for_ = requests_to_wait_for; |
+ run_loop_.reset(new base::RunLoop()); |
+ run_loop_->Run(); |
+ run_loop_.reset(); |
+ requests_to_wait_for_ = -1; |
+ EXPECT_EQ(num_requests_, requests_to_wait_for); |
+ } |
+ |
+ // It is up to the caller to wait until all relevant requests has been |
+ // created, either through calling WaitForRequests or some other manner, |
+ // before calling this method. |
+ int num_requests() const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ return num_requests_; |
+ } |
+ |
+ private: |
+ void RequestCreated() { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ num_requests_++; |
+ if (num_requests_ == requests_to_wait_for_) |
+ run_loop_->Quit(); |
+ } |
+ |
+ // These are only used on the UI thread. |
+ int num_requests_; |
+ int requests_to_wait_for_; |
+ scoped_ptr<base::RunLoop> run_loop_; |
+ |
+ // This prevents any risk of flake if any test doesn't wait for a request |
+ // it sent. Mutable so it can be accessed from a const function. |
+ mutable base::WeakPtrFactory<ShowImageRequestInterceptor> weak_factory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ShowImageRequestInterceptor); |
+}; |
+ |
+class ShowImageBrowserTest : public InProcessBrowserTest { |
+ protected: |
+ void SetupAndLoadImagePage(const std::string& image_path) { |
+ // Go to a page with an image in it. The test server doesn't serve the image |
+ // with the right MIME type, so use a data URL to make a page containing it. |
+ GURL image_url(test_server()->GetURL(image_path)); |
+ GURL page("data:text/html,<img src='" + image_url.spec() + "'>"); |
+ ui_test_utils::NavigateToURL(browser(), page); |
+ } |
+ |
+ void AddShowImageInterceptor(const std::string& image_path) { |
+ interceptor_ = new ShowImageRequestInterceptor(); |
+ scoped_ptr<net::URLRequestInterceptor> owned_interceptor(interceptor_); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, FROM_HERE, |
+ base::Bind(&ShowImageBrowserTest::AddInterceptorForURL, |
+ base::Unretained(this), |
+ GURL(test_server()->GetURL(image_path).spec()), |
+ base::Passed(&owned_interceptor))); |
+ } |
+ |
+ void AttemptShowImage() { |
+ // Right-click where the image should be. |
+ // |menu_observer_| will cause the show-image menu item to be clicked. |
+ menu_observer_.reset(new ContextMenuNotificationObserver( |
+ IDC_CONTENT_CONTEXT_SHOW_ORIGINAL_IMAGE)); |
+ content::WebContents* tab = |
+ browser()->tab_strip_model()->GetActiveWebContents(); |
+ content::SimulateMouseClickAt(tab, 0, blink::WebMouseEvent::ButtonRight, |
+ gfx::Point(15, 15)); |
+ } |
+ |
+ void AddInterceptorForURL( |
+ const GURL& url, scoped_ptr<net::URLRequestInterceptor> handler) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
+ net::URLRequestFilter::GetInstance()->AddUrlInterceptor( |
+ url, handler.Pass()); |
+ } |
+ |
+ ShowImageRequestInterceptor* interceptor_; |
+ |
+ private: |
+ scoped_ptr<ContextMenuNotificationObserver> menu_observer_; |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(ShowImageBrowserTest, ShowImage) { |
+ static const char kValidImage[] = "files/show_image/image.png"; |
+ SetupAndLoadImagePage(kValidImage); |
+ AddShowImageInterceptor(kValidImage); |
+ AttemptShowImage(); |
+ interceptor_->WaitForRequests(1); |
+ EXPECT_EQ(1, interceptor_->num_requests()); |
+} |
+ |
} // namespace |