Home | History | Annotate | Download | only in tab_contents
      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