Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / renderer_context_menu / render_view_context_menu_unittest.cc
blob2f82aa31e49f1893cc405b43f46d62c760064624
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
3 // found in the LICENSE file.
5 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
7 #include "base/prefs/pref_registry_simple.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
14 #include "chrome/browser/extensions/menu_manager.h"
15 #include "chrome/browser/extensions/menu_manager_factory.h"
16 #include "chrome/browser/extensions/test_extension_environment.h"
17 #include "chrome/browser/extensions/test_extension_prefs.h"
18 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
19 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
20 #include "chrome/browser/prefs/incognito_mode_prefs.h"
21 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
26 #include "components/data_reduction_proxy/core/browser/data_store.h"
27 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
28 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
29 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/test/web_contents_tester.h"
33 #include "extensions/browser/extension_prefs.h"
34 #include "extensions/common/url_pattern.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36 #include "third_party/WebKit/public/web/WebContextMenuData.h"
37 #include "url/gurl.h"
39 using extensions::Extension;
40 using extensions::MenuItem;
41 using extensions::MenuManager;
42 using extensions::MenuManagerFactory;
43 using extensions::URLPatternSet;
45 namespace {
47 // Generates a ContextMenuParams that matches the specified contexts.
48 static content::ContextMenuParams CreateParams(int contexts) {
49 content::ContextMenuParams rv;
50 rv.is_editable = false;
51 rv.media_type = blink::WebContextMenuData::MediaTypeNone;
52 rv.page_url = GURL("http://test.page/");
54 static const base::char16 selected_text[] = { 's', 'e', 'l', 0 };
55 if (contexts & MenuItem::SELECTION)
56 rv.selection_text = selected_text;
58 if (contexts & MenuItem::LINK)
59 rv.link_url = GURL("http://test.link/");
61 if (contexts & MenuItem::EDITABLE)
62 rv.is_editable = true;
64 if (contexts & MenuItem::IMAGE) {
65 rv.src_url = GURL("http://test.image/");
66 rv.media_type = blink::WebContextMenuData::MediaTypeImage;
69 if (contexts & MenuItem::VIDEO) {
70 rv.src_url = GURL("http://test.video/");
71 rv.media_type = blink::WebContextMenuData::MediaTypeVideo;
74 if (contexts & MenuItem::AUDIO) {
75 rv.src_url = GURL("http://test.audio/");
76 rv.media_type = blink::WebContextMenuData::MediaTypeAudio;
79 if (contexts & MenuItem::FRAME)
80 rv.frame_url = GURL("http://test.frame/");
82 return rv;
85 } // namespace
87 class RenderViewContextMenuTest : public testing::Test {
88 protected:
89 // Proxy defined here to minimize friend classes in RenderViewContextMenu
90 static bool ExtensionContextAndPatternMatch(
91 const content::ContextMenuParams& params,
92 MenuItem::ContextList contexts,
93 const URLPatternSet& patterns) {
94 return RenderViewContextMenu::ExtensionContextAndPatternMatch(
95 params, contexts, patterns);
98 // Returns a test item.
99 MenuItem* CreateTestItem(const Extension* extension, int uid) {
100 MenuItem::Type type = MenuItem::NORMAL;
101 MenuItem::ContextList contexts(MenuItem::ALL);
102 const MenuItem::ExtensionKey key(extension->id());
103 bool incognito = false;
104 MenuItem::Id id(incognito, key);
105 id.uid = uid;
106 return new MenuItem(id, "Added by an extension", false, true, type,
107 contexts);
110 // Returns a test context menu.
111 TestRenderViewContextMenu* CreateContextMenu(
112 TestingProfile* profile,
113 content::WebContents* web_contents) {
114 content::ContextMenuParams params = CreateParams(MenuItem::LINK);
115 params.unfiltered_link_url = params.link_url;
116 TestRenderViewContextMenu* menu =
117 new TestRenderViewContextMenu(web_contents->GetMainFrame(), params);
118 // TestingProfile (returned by profile()) does not provide a protocol
119 // registry.
120 scoped_ptr<ProtocolHandlerRegistry> registry_(
121 new ProtocolHandlerRegistry(profile, NULL));
122 menu->protocol_handler_registry_ = registry_.get();
123 menu->Init();
124 return menu;
128 // Generates a URLPatternSet with a single pattern
129 static URLPatternSet CreatePatternSet(const std::string& pattern) {
130 URLPattern target(URLPattern::SCHEME_HTTP);
131 target.Parse(pattern);
133 URLPatternSet rv;
134 rv.AddPattern(target);
136 return rv;
139 TEST_F(RenderViewContextMenuTest, TargetIgnoredForPage) {
140 content::ContextMenuParams params = CreateParams(0);
142 MenuItem::ContextList contexts;
143 contexts.Add(MenuItem::PAGE);
145 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
147 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
150 TEST_F(RenderViewContextMenuTest, TargetCheckedForLink) {
151 content::ContextMenuParams params = CreateParams(MenuItem::LINK);
153 MenuItem::ContextList contexts;
154 contexts.Add(MenuItem::PAGE);
155 contexts.Add(MenuItem::LINK);
157 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
159 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns));
162 TEST_F(RenderViewContextMenuTest, TargetCheckedForImage) {
163 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
165 MenuItem::ContextList contexts;
166 contexts.Add(MenuItem::PAGE);
167 contexts.Add(MenuItem::IMAGE);
169 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
171 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns));
174 TEST_F(RenderViewContextMenuTest, TargetCheckedForVideo) {
175 content::ContextMenuParams params = CreateParams(MenuItem::VIDEO);
177 MenuItem::ContextList contexts;
178 contexts.Add(MenuItem::PAGE);
179 contexts.Add(MenuItem::VIDEO);
181 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
183 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns));
186 TEST_F(RenderViewContextMenuTest, TargetCheckedForAudio) {
187 content::ContextMenuParams params = CreateParams(MenuItem::AUDIO);
189 MenuItem::ContextList contexts;
190 contexts.Add(MenuItem::PAGE);
191 contexts.Add(MenuItem::AUDIO);
193 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
195 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns));
198 TEST_F(RenderViewContextMenuTest, MatchWhenLinkedImageMatchesTarget) {
199 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE |
200 MenuItem::LINK);
202 MenuItem::ContextList contexts;
203 contexts.Add(MenuItem::LINK);
204 contexts.Add(MenuItem::IMAGE);
206 URLPatternSet patterns = CreatePatternSet("*://test.link/*");
208 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
211 TEST_F(RenderViewContextMenuTest, MatchWhenLinkedImageMatchesSource) {
212 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE |
213 MenuItem::LINK);
215 MenuItem::ContextList contexts;
216 contexts.Add(MenuItem::LINK);
217 contexts.Add(MenuItem::IMAGE);
219 URLPatternSet patterns = CreatePatternSet("*://test.image/*");
221 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
224 TEST_F(RenderViewContextMenuTest, NoMatchWhenLinkedImageMatchesNeither) {
225 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE |
226 MenuItem::LINK);
228 MenuItem::ContextList contexts;
229 contexts.Add(MenuItem::LINK);
230 contexts.Add(MenuItem::IMAGE);
232 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
234 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns));
237 TEST_F(RenderViewContextMenuTest, TargetIgnoredForFrame) {
238 content::ContextMenuParams params = CreateParams(MenuItem::FRAME);
240 MenuItem::ContextList contexts;
241 contexts.Add(MenuItem::FRAME);
243 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
245 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
248 TEST_F(RenderViewContextMenuTest, TargetIgnoredForEditable) {
249 content::ContextMenuParams params = CreateParams(MenuItem::EDITABLE);
251 MenuItem::ContextList contexts;
252 contexts.Add(MenuItem::EDITABLE);
254 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
256 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
259 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelection) {
260 content::ContextMenuParams params =
261 CreateParams(MenuItem::SELECTION);
263 MenuItem::ContextList contexts;
264 contexts.Add(MenuItem::SELECTION);
266 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
268 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
271 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelectionOnLink) {
272 content::ContextMenuParams params = CreateParams(
273 MenuItem::SELECTION | MenuItem::LINK);
275 MenuItem::ContextList contexts;
276 contexts.Add(MenuItem::SELECTION);
277 contexts.Add(MenuItem::LINK);
279 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
281 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
284 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelectionOnImage) {
285 content::ContextMenuParams params = CreateParams(
286 MenuItem::SELECTION | MenuItem::IMAGE);
288 MenuItem::ContextList contexts;
289 contexts.Add(MenuItem::SELECTION);
290 contexts.Add(MenuItem::IMAGE);
292 URLPatternSet patterns = CreatePatternSet("*://test.none/*");
294 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns));
297 TEST_F(RenderViewContextMenuTest, ItemWithSameTitleFromTwoExtensions) {
298 extensions::TestExtensionEnvironment env;
300 MenuManager* menu_manager = // Owned by env.profile().
301 static_cast<MenuManager*>(
302 (MenuManagerFactory::GetInstance()->SetTestingFactoryAndUse(
303 env.profile(),
304 &MenuManagerFactory::BuildServiceInstanceForTesting)));
306 const Extension* extension1 =
307 env.MakeExtension(base::DictionaryValue(),
308 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
309 const Extension* extension2 =
310 env.MakeExtension(base::DictionaryValue(),
311 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
313 // Create two items in two extensions with same title.
314 MenuItem* item1 = CreateTestItem(extension1, 1);
315 ASSERT_TRUE(menu_manager->AddContextItem(extension1, item1));
316 MenuItem* item2 = CreateTestItem(extension2, 2);
317 ASSERT_TRUE(menu_manager->AddContextItem(extension2, item2));
319 scoped_ptr<content::WebContents> web_contents = env.MakeTab();
320 scoped_ptr<TestRenderViewContextMenu> menu(
321 CreateContextMenu(env.profile(), web_contents.get()));
323 const ui::MenuModel& model = menu->menu_model();
324 base::string16 expected_title = base::ASCIIToUTF16("Added by an extension");
325 int num_items_found = 0;
326 for (int i = 0; i < model.GetItemCount(); ++i) {
327 if (expected_title == model.GetLabelAt(i))
328 ++num_items_found;
331 // Expect both items to be found.
332 ASSERT_EQ(2, num_items_found);
335 class RenderViewContextMenuPrefsTest : public ChromeRenderViewHostTestHarness {
336 public:
337 void SetUp() override {
338 ChromeRenderViewHostTestHarness::SetUp();
339 registry_.reset(new ProtocolHandlerRegistry(profile(), NULL));
342 void TearDown() override {
343 registry_.reset();
344 ChromeRenderViewHostTestHarness::TearDown();
347 TestRenderViewContextMenu* CreateContextMenu() {
348 content::ContextMenuParams params = CreateParams(MenuItem::LINK);
349 params.unfiltered_link_url = params.link_url;
350 content::WebContents* wc = web_contents();
351 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu(
352 wc->GetMainFrame(), params);
353 // TestingProfile (returned by profile()) does not provide a protocol
354 // registry.
355 menu->protocol_handler_registry_ = registry_.get();
356 menu->Init();
357 return menu;
360 void AppendImageItems(TestRenderViewContextMenu* menu) {
361 menu->AppendImageItems();
364 void SetupDataReductionProxy(bool enable_data_reduction_proxy) {
365 drp_test_context_ =
366 data_reduction_proxy::DataReductionProxyTestContext::Builder()
367 .WithParamsFlags(
368 data_reduction_proxy::DataReductionProxyParams::kAllowed |
369 data_reduction_proxy::DataReductionProxyParams::
370 kFallbackAllowed |
371 data_reduction_proxy::DataReductionProxyParams::kPromoAllowed)
372 .WithMockConfig()
373 .SkipSettingsInitialization()
374 .Build();
376 DataReductionProxyChromeSettings* settings =
377 DataReductionProxyChromeSettingsFactory::GetForBrowserContext(
378 profile());
380 // TODO(bengr): Remove prefs::kProxy registration after M46. See
381 // http://crbug.com/445599.
382 PrefRegistrySimple* registry =
383 drp_test_context_->pref_service()->registry();
384 registry->RegisterDictionaryPref(prefs::kProxy);
386 drp_test_context_->pref_service()->SetBoolean(
387 data_reduction_proxy::prefs::kDataReductionProxyEnabled,
388 enable_data_reduction_proxy);
389 drp_test_context_->InitSettings();
391 settings->InitDataReductionProxySettings(
392 drp_test_context_->io_data(), drp_test_context_->pref_service(),
393 drp_test_context_->request_context_getter(),
394 make_scoped_ptr(new data_reduction_proxy::DataStore()),
395 base::ThreadTaskRunnerHandle::Get(),
396 base::ThreadTaskRunnerHandle::Get());
399 // Force destruction of |DataReductionProxySettings| so that objects on DB
400 // task runner can be destroyed before test threads are destroyed. This method
401 // must be called by tests that call |SetupDataReductionProxy|. We cannot
402 // destroy |drp_test_context_| until browser context keyed services are
403 // destroyed since |DataReductionProxyChromeSettings| holds a pointer to the
404 // |PrefService|, which is owned by |drp_test_context_|.
405 void DestroyDataReductionProxySettings() {
406 drp_test_context_->DestroySettings();
409 protected:
410 scoped_ptr<data_reduction_proxy::DataReductionProxyTestContext>
411 drp_test_context_;
413 private:
414 scoped_ptr<ProtocolHandlerRegistry> registry_;
417 // Verifies when Incognito Mode is not available (disabled by policy),
418 // Open Link in Incognito Window link in the context menu is disabled.
419 TEST_F(RenderViewContextMenuPrefsTest,
420 DisableOpenInIncognitoWindowWhenIncognitoIsDisabled) {
421 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu());
423 // Initially the Incognito mode is be enabled. So is the Open Link in
424 // Incognito Window link.
425 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD));
426 EXPECT_TRUE(
427 menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD));
429 // Disable Incognito mode.
430 IncognitoModePrefs::SetAvailability(profile()->GetPrefs(),
431 IncognitoModePrefs::DISABLED);
432 menu.reset(CreateContextMenu());
433 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD));
434 EXPECT_FALSE(
435 menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD));
438 // Make sure the checking custom command id that is not enabled will not
439 // cause DCHECK failure.
440 TEST_F(RenderViewContextMenuPrefsTest,
441 IsCustomCommandIdEnabled) {
442 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu());
444 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_CUSTOM_FIRST));
447 // Verify that request headers specify that data reduction proxy should return
448 // the original non compressed resource when "Save Image As..." is used with
449 // Data Saver enabled.
450 TEST_F(RenderViewContextMenuPrefsTest, DataSaverEnabledSaveImageAs) {
451 SetupDataReductionProxy(true);
453 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
454 params.unfiltered_link_url = params.link_url;
455 content::WebContents* wc = web_contents();
456 scoped_ptr<TestRenderViewContextMenu> menu(
457 new TestRenderViewContextMenu(wc->GetMainFrame(), params));
459 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
461 const std::string& headers =
462 content::WebContentsTester::For(web_contents())->GetSaveFrameHeaders();
463 EXPECT_TRUE(headers.find("Chrome-Proxy: pass-through") != std::string::npos);
464 EXPECT_TRUE(headers.find("Cache-Control: no-cache") != std::string::npos);
466 DestroyDataReductionProxySettings();
469 // Verify that request headers do not specify pass through when "Save Image
470 // As..." is used with Data Saver disabled.
471 TEST_F(RenderViewContextMenuPrefsTest, DataSaverDisabledSaveImageAs) {
472 SetupDataReductionProxy(false);
474 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
475 params.unfiltered_link_url = params.link_url;
476 content::WebContents* wc = web_contents();
477 scoped_ptr<TestRenderViewContextMenu> menu(
478 new TestRenderViewContextMenu(wc->GetMainFrame(), params));
480 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
482 const std::string& headers =
483 content::WebContentsTester::For(web_contents())->GetSaveFrameHeaders();
484 EXPECT_TRUE(headers.find("Chrome-Proxy: pass-through") == std::string::npos);
485 EXPECT_TRUE(headers.find("Cache-Control: no-cache") == std::string::npos);
487 DestroyDataReductionProxySettings();
490 // Verify that the Chrome-Proxy Lo-Fi directive causes the context menu to
491 // display the "Load Image" menu item.
492 TEST_F(RenderViewContextMenuPrefsTest, DataSaverLoadImage) {
493 SetupDataReductionProxy(true);
494 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE);
495 params.properties[data_reduction_proxy::chrome_proxy_header()] =
496 data_reduction_proxy::chrome_proxy_lo_fi_directive();
497 params.unfiltered_link_url = params.link_url;
498 content::WebContents* wc = web_contents();
499 scoped_ptr<TestRenderViewContextMenu> menu(
500 new TestRenderViewContextMenu(wc->GetMainFrame(), params));
501 AppendImageItems(menu.get());
503 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_LOAD_ORIGINAL_IMAGE));
505 DestroyDataReductionProxySettings();