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() {} |
47 | 52 |
48 TestRenderViewContextMenu* CreateContextMenu( | 53 content::ContextMenuParams CreateContextMenuParams( |
49 const GURL& unfiltered_url, | 54 const GURL& unfiltered_url, |
50 const GURL& url, | 55 const GURL& url, |
51 blink::WebContextMenuData::MediaType media_type) { | 56 blink::WebContextMenuData::MediaType media_type) { |
52 content::ContextMenuParams params; | 57 content::ContextMenuParams params; |
53 params.media_type = media_type; | 58 params.media_type = media_type; |
54 params.unfiltered_link_url = unfiltered_url; | 59 params.unfiltered_link_url = unfiltered_url; |
55 params.link_url = url; | 60 params.link_url = url; |
56 params.src_url = url; | 61 params.src_url = url; |
57 WebContents* web_contents = | 62 WebContents* web_contents = |
58 browser()->tab_strip_model()->GetActiveWebContents(); | 63 browser()->tab_strip_model()->GetActiveWebContents(); |
59 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); | 64 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); |
60 #if defined(OS_MACOSX) | 65 #if defined(OS_MACOSX) |
61 params.writing_direction_default = 0; | 66 params.writing_direction_default = 0; |
62 params.writing_direction_left_to_right = 0; | 67 params.writing_direction_left_to_right = 0; |
63 params.writing_direction_right_to_left = 0; | 68 params.writing_direction_right_to_left = 0; |
64 #endif // OS_MACOSX | 69 #endif // OS_MACOSX |
70 return params; | |
71 } | |
72 | |
73 TestRenderViewContextMenu* CreateContextMenu( | |
74 content::ContextMenuParams params) { | |
65 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( | 75 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( |
66 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), | 76 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), |
67 params); | 77 params); |
68 menu->Init(); | 78 menu->Init(); |
69 return menu; | 79 return menu; |
70 } | 80 } |
71 | 81 |
72 TestRenderViewContextMenu* CreateContextMenuMediaTypeNone( | 82 TestRenderViewContextMenu* CreateContextMenuMediaTypeNone( |
73 const GURL& unfiltered_url, | 83 const GURL& unfiltered_url, |
74 const GURL& url) { | 84 const GURL& url) { |
75 return CreateContextMenu(unfiltered_url, url, | 85 return CreateContextMenu(CreateContextMenuParams( |
76 blink::WebContextMenuData::MediaTypeNone); | 86 unfiltered_url, url, blink::WebContextMenuData::MediaTypeNone)); |
77 } | 87 } |
78 }; | 88 }; |
79 | 89 |
80 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, | 90 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, |
81 OpenEntryPresentForNormalURLs) { | 91 OpenEntryPresentForNormalURLs) { |
82 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenuMediaTypeNone( | 92 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenuMediaTypeNone( |
83 GURL("http://www.google.com/"), GURL("http://www.google.com/"))); | 93 GURL("http://www.google.com/"), GURL("http://www.google.com/"))); |
84 | 94 |
85 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); | 95 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); |
86 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); | 96 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 TestRenderViewContextMenu menu(tab->GetMainFrame(), context_menu_params); | 311 TestRenderViewContextMenu menu(tab->GetMainFrame(), context_menu_params); |
302 menu.Init(); | 312 menu.Init(); |
303 | 313 |
304 // The item shouldn't be enabled in the menu. | 314 // The item shouldn't be enabled in the menu. |
305 EXPECT_FALSE(menu.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO)); | 315 EXPECT_FALSE(menu.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO)); |
306 | 316 |
307 // Ensure that viewing page info doesn't crash even if you can get to it. | 317 // Ensure that viewing page info doesn't crash even if you can get to it. |
308 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO, 0); | 318 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO, 0); |
309 } | 319 } |
310 | 320 |
321 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, DataSaverLoadImage) { | |
Lei Zhang
2015/05/11 20:16:53
Can this be a unit test instead?
megjablon
2015/05/11 22:58:40
I looked into writing it as a unit test, but the I
Lei Zhang
2015/05/12 21:16:39
It's probably possible, just a pain to set up all
megjablon
2015/05/13 23:36:38
Just found out someone is already doing this work
Lei Zhang
2015/05/13 23:50:19
Yay! Can you add a TODO to convert ContextMenuBrow
megjablon
2015/05/14 19:26:24
Done.
| |
322 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
323 command_line->AppendSwitch( | |
324 data_reduction_proxy::switches::kEnableDataReductionProxyLoFi); | |
325 | |
326 content::ContextMenuParams params = CreateContextMenuParams( | |
327 GURL(), GURL("http://url.com/image.png"), | |
328 blink::WebContextMenuData::MediaTypeImage); | |
329 params.image_was_fetched_lo_fi = true; | |
330 | |
331 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu(params)); | |
332 | |
333 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_RELOAD_ORIGINAL_IMAGE)); | |
334 } | |
335 | |
311 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, DataSaverOpenOrigImageInNewTab) { | 336 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, DataSaverOpenOrigImageInNewTab) { |
312 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 337 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
313 command_line->AppendSwitch( | 338 command_line->AppendSwitch( |
314 data_reduction_proxy::switches::kEnableDataReductionProxy); | 339 data_reduction_proxy::switches::kEnableDataReductionProxy); |
315 | 340 |
316 scoped_ptr<TestRenderViewContextMenu> menu( | 341 scoped_ptr<TestRenderViewContextMenu> menu( |
317 CreateContextMenu(GURL(), GURL("http://url.com/image.png"), | 342 CreateContextMenu(CreateContextMenuParams( |
318 blink::WebContextMenuData::MediaTypeImage)); | 343 GURL(), GURL("http://url.com/image.png"), |
344 blink::WebContextMenuData::MediaTypeImage))); | |
319 | 345 |
320 ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); | 346 ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); |
321 ASSERT_TRUE(menu->IsItemPresent( | 347 ASSERT_TRUE(menu->IsItemPresent( |
322 IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); | 348 IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); |
323 } | 349 } |
324 | 350 |
325 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, | 351 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, |
326 DataSaverHttpsOpenImageInNewTab) { | 352 DataSaverHttpsOpenImageInNewTab) { |
327 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 353 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
328 command_line->AppendSwitch( | 354 command_line->AppendSwitch( |
329 data_reduction_proxy::switches::kEnableDataReductionProxy); | 355 data_reduction_proxy::switches::kEnableDataReductionProxy); |
330 | 356 |
331 scoped_ptr<TestRenderViewContextMenu> menu( | 357 scoped_ptr<TestRenderViewContextMenu> menu( |
332 CreateContextMenu(GURL(), GURL("https://url.com/image.png"), | 358 CreateContextMenu(CreateContextMenuParams( |
333 blink::WebContextMenuData::MediaTypeImage)); | 359 GURL(), GURL("https://url.com/image.png"), |
360 blink::WebContextMenuData::MediaTypeImage))); | |
334 | 361 |
335 ASSERT_FALSE( | 362 ASSERT_FALSE( |
336 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); | 363 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); |
337 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); | 364 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); |
338 } | 365 } |
339 | 366 |
340 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenImageInNewTab) { | 367 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenImageInNewTab) { |
341 scoped_ptr<TestRenderViewContextMenu> menu( | 368 scoped_ptr<TestRenderViewContextMenu> menu( |
342 CreateContextMenu(GURL(), GURL("http://url.com/image.png"), | 369 CreateContextMenu(CreateContextMenuParams( |
343 blink::WebContextMenuData::MediaTypeImage)); | 370 GURL(), GURL("http://url.com/image.png"), |
371 blink::WebContextMenuData::MediaTypeImage))); | |
344 ASSERT_FALSE( | 372 ASSERT_FALSE( |
345 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); | 373 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); |
346 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); | 374 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); |
347 } | 375 } |
348 | 376 |
349 class ThumbnailResponseWatcher : public content::NotificationObserver { | 377 class ThumbnailResponseWatcher : public content::NotificationObserver { |
350 public: | 378 public: |
351 enum QuitReason { | 379 enum QuitReason { |
352 STILL_RUNNING = 0, | 380 STILL_RUNNING = 0, |
353 THUMBNAIL_RECEIVED, | 381 THUMBNAIL_RECEIVED, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 content::WebContents* tab = | 546 content::WebContents* tab = |
519 browser()->tab_strip_model()->GetActiveWebContents(); | 547 browser()->tab_strip_model()->GetActiveWebContents(); |
520 ThumbnailResponseWatcher watcher(tab->GetRenderProcessHost()); | 548 ThumbnailResponseWatcher watcher(tab->GetRenderProcessHost()); |
521 AttemptImageSearch(); | 549 AttemptImageSearch(); |
522 | 550 |
523 // The browser should receive a response from the renderer, because the | 551 // The browser should receive a response from the renderer, because the |
524 // renderer should not crash. | 552 // renderer should not crash. |
525 EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait()); | 553 EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait()); |
526 } | 554 } |
527 | 555 |
556 class LoadImageRequestInterceptor : public net::URLRequestInterceptor { | |
557 public: | |
558 LoadImageRequestInterceptor() : num_requests_(0), | |
559 requests_to_wait_for_(-1), | |
560 weak_factory_(this) { | |
561 } | |
562 | |
563 ~LoadImageRequestInterceptor() override {} | |
564 | |
565 // net::URLRequestInterceptor implementation | |
566 net::URLRequestJob* MaybeInterceptRequest( | |
567 net::URLRequest* request, | |
568 net::NetworkDelegate* network_delegate) const override { | |
569 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
Lei Zhang
2015/05/11 20:16:53
Use DCHECK_CURRENTLY_ON()
megjablon
2015/05/11 22:58:40
Done.
| |
570 EXPECT_TRUE(request->load_flags() & net::LOAD_BYPASS_CACHE); | |
571 content::BrowserThread::PostTask( | |
572 content::BrowserThread::UI, FROM_HERE, | |
573 base::Bind(&LoadImageRequestInterceptor::RequestCreated, | |
574 weak_factory_.GetWeakPtr())); | |
575 return nullptr; | |
576 } | |
577 | |
578 void WaitForRequests(int requests_to_wait_for) { | |
579 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
580 DCHECK_EQ(-1, requests_to_wait_for_); | |
581 DCHECK(!run_loop_); | |
582 | |
583 if (num_requests_ >= requests_to_wait_for) | |
584 return; | |
585 | |
586 requests_to_wait_for_ = requests_to_wait_for; | |
587 run_loop_.reset(new base::RunLoop()); | |
588 run_loop_->Run(); | |
589 run_loop_.reset(); | |
590 requests_to_wait_for_ = -1; | |
591 EXPECT_EQ(num_requests_, requests_to_wait_for); | |
592 } | |
593 | |
594 // It is up to the caller to wait until all relevant requests has been | |
595 // created, either through calling WaitForRequests or some other manner, | |
596 // before calling this method. | |
597 int num_requests() const { | |
598 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
599 return num_requests_; | |
600 } | |
601 | |
602 private: | |
603 void RequestCreated() { | |
604 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
605 | |
606 num_requests_++; | |
607 if (num_requests_ == requests_to_wait_for_) | |
608 run_loop_->Quit(); | |
609 } | |
610 | |
611 // These are only used on the UI thread. | |
612 int num_requests_; | |
613 int requests_to_wait_for_; | |
614 scoped_ptr<base::RunLoop> run_loop_; | |
615 | |
616 // This prevents any risk of flake if any test doesn't wait for a request | |
617 // it sent. Mutable so it can be accessed from a const function. | |
618 mutable base::WeakPtrFactory<LoadImageRequestInterceptor> weak_factory_; | |
619 | |
620 DISALLOW_COPY_AND_ASSIGN(LoadImageRequestInterceptor); | |
621 }; | |
622 | |
623 class LoadImageBrowserTest : public InProcessBrowserTest { | |
624 protected: | |
625 void SetupAndLoadImagePage(const std::string& image_path) { | |
626 // Go to a page with an image in it. The test server doesn't serve the image | |
627 // with the right MIME type, so use a data URL to make a page containing it. | |
628 GURL image_url(test_server()->GetURL(image_path)); | |
629 GURL page("data:text/html,<img src='" + image_url.spec() + "'>"); | |
630 ui_test_utils::NavigateToURL(browser(), page); | |
631 } | |
632 | |
633 void AddLoadImageInterceptor(const std::string& image_path) { | |
634 interceptor_ = new LoadImageRequestInterceptor(); | |
635 scoped_ptr<net::URLRequestInterceptor> owned_interceptor(interceptor_); | |
636 // Ownership of the |interceptor_| is passed to an object the IO thread, but | |
637 // a pointer is kept in the test fixture. As soon as anything calls | |
638 // URLRequestFilter::ClearHandlers(), |interceptor_| can become invalid. | |
Lei Zhang
2015/05/11 20:16:53
I realized this is copied over from another test,
megjablon
2015/05/11 22:58:40
Looks like ClearHandlers is only called by tests a
| |
639 content::BrowserThread::PostTask( | |
640 content::BrowserThread::IO, FROM_HERE, | |
641 base::Bind(&LoadImageBrowserTest::AddInterceptorForURL, | |
642 base::Unretained(this), | |
643 GURL(test_server()->GetURL(image_path).spec()), | |
644 base::Passed(&owned_interceptor))); | |
645 } | |
646 | |
647 void AttemptImageLoad() { | |
648 // Right-click where the image should be. | |
649 // |menu_observer_| will cause the load-image menu item to be clicked. | |
650 menu_observer_.reset(new ContextMenuNotificationObserver( | |
651 IDC_CONTENT_CONTEXT_RELOAD_ORIGINAL_IMAGE)); | |
652 content::WebContents* tab = | |
653 browser()->tab_strip_model()->GetActiveWebContents(); | |
654 content::SimulateMouseClickAt(tab, 0, blink::WebMouseEvent::ButtonRight, | |
655 gfx::Point(15, 15)); | |
656 } | |
657 | |
658 void AddInterceptorForURL( | |
659 const GURL& url, scoped_ptr<net::URLRequestInterceptor> handler) { | |
660 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
661 net::URLRequestFilter::GetInstance()->AddUrlInterceptor( | |
662 url, handler.Pass()); | |
663 } | |
664 | |
665 LoadImageRequestInterceptor* interceptor_; | |
666 | |
667 private: | |
668 scoped_ptr<ContextMenuNotificationObserver> menu_observer_; | |
669 }; | |
670 | |
671 IN_PROC_BROWSER_TEST_F(LoadImageBrowserTest, LoadImage) { | |
672 static const char kValidImage[] = "files/load_image/image.png"; | |
673 SetupAndLoadImagePage(kValidImage); | |
674 AddLoadImageInterceptor(kValidImage); | |
675 AttemptImageLoad(); | |
676 interceptor_->WaitForRequests(1); | |
677 EXPECT_EQ(1, interceptor_->num_requests()); | |
678 } | |
679 | |
528 } // namespace | 680 } // namespace |
OLD | NEW |