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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/tab_contents/render_view_context_menu.h" 6 7 #include "base/prefs/pref_service.h" 8 #include "chrome/app/chrome_command_ids.h" 9 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" 10 #include "chrome/browser/extensions/extension_prefs.h" 11 #include "chrome/browser/prefs/incognito_mode_prefs.h" 12 #include "chrome/browser/tab_contents/render_view_context_menu_test_util.h" 13 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 14 #include "chrome/test/base/testing_profile.h" 15 #include "content/public/browser/web_contents.h" 16 #include "extensions/common/url_pattern.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "third_party/WebKit/public/web/WebContextMenuData.h" 19 #include "url/gurl.h" 20 21 using extensions::MenuItem; 22 using extensions::URLPatternSet; 23 24 class RenderViewContextMenuTest : public testing::Test { 25 protected: 26 // Proxy defined here to minimize friend classes in RenderViewContextMenu 27 static bool ExtensionContextAndPatternMatch( 28 const content::ContextMenuParams& params, 29 MenuItem::ContextList contexts, 30 const URLPatternSet& patterns) { 31 return RenderViewContextMenu::ExtensionContextAndPatternMatch(params, 32 contexts, patterns); 33 } 34 }; 35 36 // Generates a ContextMenuParams that matches the specified contexts. 37 static content::ContextMenuParams CreateParams(int contexts) { 38 content::ContextMenuParams rv; 39 rv.is_editable = false; 40 rv.media_type = WebKit::WebContextMenuData::MediaTypeNone; 41 rv.page_url = GURL("http://test.page/"); 42 43 static const char16 selected_text[] = { 's', 'e', 'l', 0 }; 44 if (contexts & MenuItem::SELECTION) 45 rv.selection_text = selected_text; 46 47 if (contexts & MenuItem::LINK) 48 rv.link_url = GURL("http://test.link/"); 49 50 if (contexts & MenuItem::EDITABLE) 51 rv.is_editable = true; 52 53 if (contexts & MenuItem::IMAGE) { 54 rv.src_url = GURL("http://test.image/"); 55 rv.media_type = WebKit::WebContextMenuData::MediaTypeImage; 56 } 57 58 if (contexts & MenuItem::VIDEO) { 59 rv.src_url = GURL("http://test.video/"); 60 rv.media_type = WebKit::WebContextMenuData::MediaTypeVideo; 61 } 62 63 if (contexts & MenuItem::AUDIO) { 64 rv.src_url = GURL("http://test.audio/"); 65 rv.media_type = WebKit::WebContextMenuData::MediaTypeAudio; 66 } 67 68 if (contexts & MenuItem::FRAME) 69 rv.frame_url = GURL("http://test.frame/"); 70 71 return rv; 72 } 73 74 // Generates a URLPatternSet with a single pattern 75 static URLPatternSet CreatePatternSet(const std::string& pattern) { 76 URLPattern target(URLPattern::SCHEME_HTTP); 77 target.Parse(pattern); 78 79 URLPatternSet rv; 80 rv.AddPattern(target); 81 82 return rv; 83 } 84 85 TEST_F(RenderViewContextMenuTest, TargetIgnoredForPage) { 86 content::ContextMenuParams params = CreateParams(0); 87 88 MenuItem::ContextList contexts; 89 contexts.Add(MenuItem::PAGE); 90 91 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 92 93 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 94 } 95 96 TEST_F(RenderViewContextMenuTest, TargetCheckedForLink) { 97 content::ContextMenuParams params = CreateParams(MenuItem::LINK); 98 99 MenuItem::ContextList contexts; 100 contexts.Add(MenuItem::PAGE); 101 contexts.Add(MenuItem::LINK); 102 103 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 104 105 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 106 } 107 108 TEST_F(RenderViewContextMenuTest, TargetCheckedForImage) { 109 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE); 110 111 MenuItem::ContextList contexts; 112 contexts.Add(MenuItem::PAGE); 113 contexts.Add(MenuItem::IMAGE); 114 115 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 116 117 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 118 } 119 120 TEST_F(RenderViewContextMenuTest, TargetCheckedForVideo) { 121 content::ContextMenuParams params = CreateParams(MenuItem::VIDEO); 122 123 MenuItem::ContextList contexts; 124 contexts.Add(MenuItem::PAGE); 125 contexts.Add(MenuItem::VIDEO); 126 127 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 128 129 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 130 } 131 132 TEST_F(RenderViewContextMenuTest, TargetCheckedForAudio) { 133 content::ContextMenuParams params = CreateParams(MenuItem::AUDIO); 134 135 MenuItem::ContextList contexts; 136 contexts.Add(MenuItem::PAGE); 137 contexts.Add(MenuItem::AUDIO); 138 139 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 140 141 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 142 } 143 144 TEST_F(RenderViewContextMenuTest, MatchWhenLinkedImageMatchesTarget) { 145 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE | 146 MenuItem::LINK); 147 148 MenuItem::ContextList contexts; 149 contexts.Add(MenuItem::LINK); 150 contexts.Add(MenuItem::IMAGE); 151 152 URLPatternSet patterns = CreatePatternSet("*://test.link/*"); 153 154 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 155 } 156 157 TEST_F(RenderViewContextMenuTest, MatchWhenLinkedImageMatchesSource) { 158 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE | 159 MenuItem::LINK); 160 161 MenuItem::ContextList contexts; 162 contexts.Add(MenuItem::LINK); 163 contexts.Add(MenuItem::IMAGE); 164 165 URLPatternSet patterns = CreatePatternSet("*://test.image/*"); 166 167 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 168 } 169 170 TEST_F(RenderViewContextMenuTest, NoMatchWhenLinkedImageMatchesNeither) { 171 content::ContextMenuParams params = CreateParams(MenuItem::IMAGE | 172 MenuItem::LINK); 173 174 MenuItem::ContextList contexts; 175 contexts.Add(MenuItem::LINK); 176 contexts.Add(MenuItem::IMAGE); 177 178 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 179 180 EXPECT_FALSE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 181 } 182 183 TEST_F(RenderViewContextMenuTest, TargetIgnoredForFrame) { 184 content::ContextMenuParams params = CreateParams(MenuItem::FRAME); 185 186 MenuItem::ContextList contexts; 187 contexts.Add(MenuItem::FRAME); 188 189 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 190 191 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 192 } 193 194 TEST_F(RenderViewContextMenuTest, TargetIgnoredForEditable) { 195 content::ContextMenuParams params = CreateParams(MenuItem::EDITABLE); 196 197 MenuItem::ContextList contexts; 198 contexts.Add(MenuItem::EDITABLE); 199 200 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 201 202 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 203 } 204 205 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelection) { 206 content::ContextMenuParams params = 207 CreateParams(MenuItem::SELECTION); 208 209 MenuItem::ContextList contexts; 210 contexts.Add(MenuItem::SELECTION); 211 212 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 213 214 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 215 } 216 217 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelectionOnLink) { 218 content::ContextMenuParams params = CreateParams( 219 MenuItem::SELECTION | MenuItem::LINK); 220 221 MenuItem::ContextList contexts; 222 contexts.Add(MenuItem::SELECTION); 223 contexts.Add(MenuItem::LINK); 224 225 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 226 227 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 228 } 229 230 TEST_F(RenderViewContextMenuTest, TargetIgnoredForSelectionOnImage) { 231 content::ContextMenuParams params = CreateParams( 232 MenuItem::SELECTION | MenuItem::IMAGE); 233 234 MenuItem::ContextList contexts; 235 contexts.Add(MenuItem::SELECTION); 236 contexts.Add(MenuItem::IMAGE); 237 238 URLPatternSet patterns = CreatePatternSet("*://test.none/*"); 239 240 EXPECT_TRUE(ExtensionContextAndPatternMatch(params, contexts, patterns)); 241 } 242 243 class RenderViewContextMenuPrefsTest : public ChromeRenderViewHostTestHarness { 244 public: 245 virtual void SetUp() OVERRIDE { 246 ChromeRenderViewHostTestHarness::SetUp(); 247 registry_.reset(new ProtocolHandlerRegistry(profile(), NULL)); 248 } 249 250 virtual void TearDown() OVERRIDE { 251 registry_.reset(); 252 ChromeRenderViewHostTestHarness::TearDown(); 253 } 254 255 TestRenderViewContextMenu* CreateContextMenu() { 256 content::ContextMenuParams params = CreateParams(MenuItem::LINK); 257 params.unfiltered_link_url = params.link_url; 258 content::WebContents* wc = web_contents(); 259 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( 260 wc, params); 261 // TestingProfile (returned by profile()) does not provide a protocol 262 // registry. 263 menu->protocol_handler_registry_ = registry_.get(); 264 menu->Init(); 265 return menu; 266 } 267 268 private: 269 scoped_ptr<ProtocolHandlerRegistry> registry_; 270 }; 271 272 // Verifies when Incognito Mode is not available (disabled by policy), 273 // Open Link in Incognito Window link in the context menu is disabled. 274 TEST_F(RenderViewContextMenuPrefsTest, 275 DisableOpenInIncognitoWindowWhenIncognitoIsDisabled) { 276 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenu()); 277 278 // Initially the Incognito mode is be enabled. So is the Open Link in 279 // Incognito Window link. 280 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); 281 EXPECT_TRUE( 282 menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); 283 284 // Disable Incognito mode. 285 IncognitoModePrefs::SetAvailability(profile()->GetPrefs(), 286 IncognitoModePrefs::DISABLED); 287 menu.reset(CreateContextMenu()); 288 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); 289 EXPECT_FALSE( 290 menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); 291 } 292