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 21using extensions::MenuItem; 22using extensions::URLPatternSet; 23 24class 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. 37static 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 75static 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 85TEST_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 96TEST_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 108TEST_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 120TEST_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 132TEST_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 144TEST_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 157TEST_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 170TEST_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 183TEST_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 194TEST_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 205TEST_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 217TEST_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 230TEST_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 243class 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. 274TEST_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