| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/extensions/extension_context_menu_model.h" | 5 #include "chrome/browser/extensions/extension_context_menu_model.h" |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 7 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| 8 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
| 9 #include "chrome/browser/extensions/extension_service_test_base.h" | 9 #include "chrome/browser/extensions/extension_service_test_base.h" |
| 10 #include "chrome/browser/extensions/menu_manager.h" | 10 #include "chrome/browser/extensions/menu_manager.h" |
| 11 #include "chrome/browser/extensions/menu_manager_factory.h" | 11 #include "chrome/browser/extensions/menu_manager_factory.h" |
| 12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/host_desktop.h" | 13 #include "chrome/browser/ui/host_desktop.h" |
| 14 #include "chrome/common/extensions/api/context_menus.h" | 14 #include "chrome/common/extensions/api/context_menus.h" |
| 15 #include "chrome/grit/chromium_strings.h" | 15 #include "chrome/grit/chromium_strings.h" |
| 16 #include "chrome/grit/generated_resources.h" | 16 #include "chrome/grit/generated_resources.h" |
| 17 #include "chrome/test/base/test_browser_window.h" | 17 #include "chrome/test/base/test_browser_window.h" |
| 18 #include "chrome/test/base/testing_profile.h" | 18 #include "chrome/test/base/testing_profile.h" |
| 19 #include "components/crx_file/id_util.h" | 19 #include "components/crx_file/id_util.h" |
| 20 #include "extensions/browser/extension_system.h" | 20 #include "extensions/browser/extension_system.h" |
| 21 #include "extensions/browser/test_management_policy.h" | 21 #include "extensions/browser/test_management_policy.h" |
| 22 #include "extensions/common/extension_builder.h" | 22 #include "extensions/common/extension_builder.h" |
| 23 #include "extensions/common/feature_switch.h" | 23 #include "extensions/common/feature_switch.h" |
| 24 #include "extensions/common/manifest.h" | 24 #include "extensions/common/manifest.h" |
| 25 #include "extensions/common/manifest_constants.h" | 25 #include "extensions/common/manifest_constants.h" |
| 26 #include "extensions/common/manifest_handlers/options_page_info.h" |
| 26 #include "extensions/common/value_builder.h" | 27 #include "extensions/common/value_builder.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
| 30 #include "ui/gfx/image/image.h" |
| 29 | 31 |
| 30 namespace extensions { | 32 namespace extensions { |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 // Build an extension to pass to the menu constructor, with the an action | 36 // Build an extension to pass to the menu constructor, with the an action |
| 35 // specified by |action_key|. | 37 // specified by |action_key|. |
| 36 scoped_refptr<const Extension> BuildExtension(const std::string& name, | 38 scoped_refptr<const Extension> BuildExtension(const std::string& name, |
| 37 const char* action_key, | 39 const char* action_key, |
| 38 Manifest::Location location) { | 40 Manifest::Location location) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 // Returns the number of extension menu items that show up in |model|. | 88 // Returns the number of extension menu items that show up in |model|. |
| 87 int CountExtensionItems(ExtensionContextMenuModel* model); | 89 int CountExtensionItems(ExtensionContextMenuModel* model); |
| 88 | 90 |
| 89 private: | 91 private: |
| 90 int cur_id_; | 92 int cur_id_; |
| 91 }; | 93 }; |
| 92 | 94 |
| 93 ExtensionContextMenuModelTest::ExtensionContextMenuModelTest() : cur_id_(0) { | 95 ExtensionContextMenuModelTest::ExtensionContextMenuModelTest() : cur_id_(0) { |
| 94 } | 96 } |
| 95 | 97 |
| 96 | |
| 97 void ExtensionContextMenuModelTest::AddContextItemAndRefreshModel( | 98 void ExtensionContextMenuModelTest::AddContextItemAndRefreshModel( |
| 98 MenuManager* manager, | 99 MenuManager* manager, |
| 99 const Extension* extension, | 100 const Extension* extension, |
| 100 MenuItem::Context context, | 101 MenuItem::Context context, |
| 101 ExtensionContextMenuModel* model) { | 102 ExtensionContextMenuModel* model) { |
| 102 MenuItem::Type type = MenuItem::NORMAL; | 103 MenuItem::Type type = MenuItem::NORMAL; |
| 103 MenuItem::ContextList contexts(context); | 104 MenuItem::ContextList contexts(context); |
| 104 const MenuItem::ExtensionKey key(extension->id()); | 105 const MenuItem::ExtensionKey key(extension->id()); |
| 105 MenuItem::Id id(false, key); | 106 MenuItem::Id id(false, key); |
| 106 id.uid = ++cur_id_; | 107 id.uid = ++cur_id_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 122 int ExtensionContextMenuModelTest::CountExtensionItems( | 123 int ExtensionContextMenuModelTest::CountExtensionItems( |
| 123 ExtensionContextMenuModel* model) { | 124 ExtensionContextMenuModel* model) { |
| 124 return model->extension_items_count_; | 125 return model->extension_items_count_; |
| 125 } | 126 } |
| 126 | 127 |
| 127 // Tests that applicable menu items are disabled when a ManagementPolicy | 128 // Tests that applicable menu items are disabled when a ManagementPolicy |
| 128 // prohibits them. | 129 // prohibits them. |
| 129 TEST_F(ExtensionContextMenuModelTest, RequiredInstallationsDisablesItems) { | 130 TEST_F(ExtensionContextMenuModelTest, RequiredInstallationsDisablesItems) { |
| 130 InitializeEmptyExtensionService(); | 131 InitializeEmptyExtensionService(); |
| 131 | 132 |
| 132 // First, test that a component extension cannot be uninstalled by the | 133 // Test that management policy can determine whether or not policy-installed |
| 133 // standard management policy. | 134 // extensions can be installed/uninstalled. |
| 134 scoped_refptr<const Extension> extension = | 135 scoped_refptr<const Extension> extension = |
| 135 BuildExtension("component", | 136 BuildExtension("extension", |
| 136 manifest_keys::kBrowserAction, | 137 manifest_keys::kPageAction, |
| 137 Manifest::COMPONENT); | 138 Manifest::EXTERNAL_POLICY); |
| 138 ASSERT_TRUE(extension.get()); | 139 ASSERT_TRUE(extension.get()); |
| 139 service()->AddExtension(extension.get()); | 140 service()->AddExtension(extension.get()); |
| 140 | 141 |
| 141 scoped_ptr<Browser> browser = CreateBrowser(profile()); | 142 scoped_ptr<Browser> browser = CreateBrowser(profile()); |
| 143 scoped_refptr<ExtensionContextMenuModel> menu( |
| 144 new ExtensionContextMenuModel(extension.get(), browser.get())); |
| 145 |
| 146 ExtensionSystem* system = ExtensionSystem::Get(profile()); |
| 147 system->management_policy()->UnregisterAllProviders(); |
| 148 |
| 149 // Uninstallation should be, by default, enabled. |
| 150 ASSERT_TRUE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL)); |
| 151 |
| 152 TestManagementPolicyProvider policy_provider( |
| 153 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); |
| 154 system->management_policy()->RegisterProvider(&policy_provider); |
| 155 |
| 156 // If there's a policy provider that requires the extension stay enabled, then |
| 157 // uninstallation should be disabled. |
| 158 ASSERT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL)); |
| 159 |
| 160 // Don't leave |policy_provider| dangling. |
| 161 system->management_policy()->UnregisterProvider(&policy_provider); |
| 162 } |
| 163 |
| 164 // Tests the context menu for a component extension. |
| 165 TEST_F(ExtensionContextMenuModelTest, ComponentExtensionContextMenu) { |
| 166 InitializeEmptyExtensionService(); |
| 167 |
| 168 std::string name("component"); |
| 169 scoped_ptr<base::DictionaryValue> manifest = |
| 170 DictionaryBuilder().Set("name", name) |
| 171 .Set("version", "1") |
| 172 .Set("manifest_version", 2) |
| 173 .Set("browser_action", DictionaryBuilder().Pass()) |
| 174 .Build(); |
| 175 |
| 176 scoped_refptr<const Extension> extension = |
| 177 ExtensionBuilder().SetManifest(make_scoped_ptr(manifest->DeepCopy())) |
| 178 .SetID(crx_file::id_util::GenerateId("component")) |
| 179 .SetLocation(Manifest::COMPONENT) |
| 180 .Build(); |
| 181 service()->AddExtension(extension.get()); |
| 182 |
| 183 scoped_ptr<Browser> browser = CreateBrowser(profile()); |
| 142 | 184 |
| 143 scoped_refptr<ExtensionContextMenuModel> menu( | 185 scoped_refptr<ExtensionContextMenuModel> menu( |
| 144 new ExtensionContextMenuModel(extension.get(), browser.get())); | 186 new ExtensionContextMenuModel(extension.get(), browser.get())); |
| 145 | 187 |
| 146 // Uninstallation should be disabled. | 188 // A component extension's context menu should not include options for |
| 147 EXPECT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL)); | 189 // managing extensions or removing it, and should only include an option for |
| 190 // the options page if the extension has one (which this one doesn't). |
| 191 EXPECT_EQ(-1, |
| 192 menu->GetIndexOfCommandId(ExtensionContextMenuModel::CONFIGURE)); |
| 193 EXPECT_EQ(-1, |
| 194 menu->GetIndexOfCommandId(ExtensionContextMenuModel::UNINSTALL)); |
| 195 EXPECT_EQ(-1, menu->GetIndexOfCommandId(ExtensionContextMenuModel::MANAGE)); |
| 196 // The "name" option should be present, but not enabled for component |
| 197 // extensions. |
| 198 EXPECT_NE(-1, menu->GetIndexOfCommandId(ExtensionContextMenuModel::NAME)); |
| 199 EXPECT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::NAME)); |
| 148 | 200 |
| 149 // Also test that management policy can determine whether or not | 201 // Check that a component extension with an options page does have the options |
| 150 // policy-installed extensions can be installed/uninstalled. | 202 // menu item, and it is enabled. |
| 151 extension = BuildExtension("extension", | 203 manifest->SetString("options_page", "options_page.html"); |
| 152 manifest_keys::kPageAction, | 204 extension = |
| 153 Manifest::INTERNAL); | 205 ExtensionBuilder().SetManifest(manifest.Pass()) |
| 154 ASSERT_TRUE(extension.get()); | 206 .SetID(crx_file::id_util::GenerateId("component_opts")) |
| 207 .SetLocation(Manifest::COMPONENT) |
| 208 .Build(); |
| 209 menu = new ExtensionContextMenuModel(extension.get(), browser.get()); |
| 155 service()->AddExtension(extension.get()); | 210 service()->AddExtension(extension.get()); |
| 156 | 211 EXPECT_TRUE(extensions::OptionsPageInfo::HasOptionsPage(extension.get())); |
| 157 menu = new ExtensionContextMenuModel(extension.get(), browser.get()); | 212 EXPECT_NE(-1, |
| 158 | 213 menu->GetIndexOfCommandId(ExtensionContextMenuModel::CONFIGURE)); |
| 159 ExtensionSystem* system = ExtensionSystem::Get(profile()); | 214 EXPECT_TRUE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::CONFIGURE)); |
| 160 system->management_policy()->UnregisterAllProviders(); | |
| 161 | |
| 162 // Actions should be enabled. | |
| 163 ASSERT_TRUE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL)); | |
| 164 | |
| 165 TestManagementPolicyProvider policy_provider( | |
| 166 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); | |
| 167 system->management_policy()->RegisterProvider(&policy_provider); | |
| 168 | |
| 169 // Now the actions are disabled. | |
| 170 ASSERT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL)); | |
| 171 | |
| 172 // Don't leave |policy_provider| dangling. | |
| 173 system->management_policy()->UnregisterProvider(&policy_provider); | |
| 174 } | 215 } |
| 175 | 216 |
| 176 TEST_F(ExtensionContextMenuModelTest, ExtensionItemTest) { | 217 TEST_F(ExtensionContextMenuModelTest, ExtensionItemTest) { |
| 177 InitializeEmptyExtensionService(); | 218 InitializeEmptyExtensionService(); |
| 178 scoped_refptr<const Extension> extension = | 219 scoped_refptr<const Extension> extension = |
| 179 BuildExtension("extension", | 220 BuildExtension("extension", |
| 180 manifest_keys::kPageAction, | 221 manifest_keys::kPageAction, |
| 181 Manifest::INTERNAL); | 222 Manifest::INTERNAL); |
| 182 ASSERT_TRUE(extension.get()); | 223 ASSERT_TRUE(extension.get()); |
| 183 service()->AddExtension(extension.get()); | 224 service()->AddExtension(extension.get()); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 browser_action.get(), | 354 browser_action.get(), |
| 314 browser.get(), | 355 browser.get(), |
| 315 ExtensionContextMenuModel::TRANSITIVELY_VISIBLE, | 356 ExtensionContextMenuModel::TRANSITIVELY_VISIBLE, |
| 316 nullptr); | 357 nullptr); |
| 317 index = GetCommandIndex(menu, visibility_command); | 358 index = GetCommandIndex(menu, visibility_command); |
| 318 EXPECT_NE(-1, index); | 359 EXPECT_NE(-1, index); |
| 319 EXPECT_EQ(redesign_keep_string, menu->GetLabelAt(index)); | 360 EXPECT_EQ(redesign_keep_string, menu->GetLabelAt(index)); |
| 320 } | 361 } |
| 321 | 362 |
| 322 } // namespace extensions | 363 } // namespace extensions |
| OLD | NEW |