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.
5 #include "chrome/browser/extensions/extension_context_menu_model.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/extension_service_test_base.h"
9 #include "chrome/browser/extensions/menu_manager.h"
10 #include "chrome/browser/extensions/menu_manager_factory.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/host_desktop.h"
13 #include "chrome/common/extensions/api/context_menus.h"
14 #include "chrome/test/base/test_browser_window.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/test_management_policy.h"
18 #include "extensions/common/extension_builder.h"
19 #include "extensions/common/value_builder.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace extensions {
24 class ExtensionContextMenuModelTest : public ExtensionServiceTestBase {
26 ExtensionContextMenuModelTest();
28 // Build an extension to pass to the menu constructor. It needs an
30 scoped_refptr<Extension> BuildExtension();
32 // Creates an extension menu item for |extension| with the given |context|
33 // and adds it to |manager|. Refreshes |model| to show new item.
34 void AddContextItemAndRefreshModel(MenuManager* manager,
36 MenuItem::Context context,
37 ExtensionContextMenuModel* model);
39 // Reinitializes the given |model|.
40 void RefreshMenu(ExtensionContextMenuModel* model);
42 // Returns the number of extension menu items that show up in |model|.
43 int CountExtensionItems(ExtensionContextMenuModel* model);
49 ExtensionContextMenuModelTest::ExtensionContextMenuModelTest() : cur_id_(0) {
52 scoped_refptr<Extension> ExtensionContextMenuModelTest::BuildExtension() {
53 return ExtensionBuilder()
54 .SetManifest(DictionaryBuilder()
55 .Set("name", "Page Action Extension")
57 .Set("manifest_version", 2)
59 DictionaryBuilder().Set("default_title", "Hello")))
63 void ExtensionContextMenuModelTest::AddContextItemAndRefreshModel(
66 MenuItem::Context context,
67 ExtensionContextMenuModel* model) {
68 MenuItem::Type type = MenuItem::NORMAL;
69 MenuItem::ContextList contexts(context);
70 const MenuItem::ExtensionKey key(extension->id());
71 MenuItem::Id id(false, key);
73 manager->AddContextItem(extension,
83 void ExtensionContextMenuModelTest::RefreshMenu(
84 ExtensionContextMenuModel* model) {
85 model->InitMenu(model->GetExtension());
88 int ExtensionContextMenuModelTest::CountExtensionItems(
89 ExtensionContextMenuModel* model) {
90 return model->extension_items_count_;
95 // Tests that applicable menu items are disabled when a ManagementPolicy
97 TEST_F(ExtensionContextMenuModelTest, PolicyDisablesItems) {
98 InitializeEmptyExtensionService();
99 scoped_refptr<Extension> extension = BuildExtension();
100 ASSERT_TRUE(extension.get());
101 service_->AddExtension(extension.get());
103 // Create a Browser for the ExtensionContextMenuModel to use.
104 Browser::CreateParams params(profile_.get(), chrome::GetActiveDesktop());
105 TestBrowserWindow test_window;
106 params.window = &test_window;
107 Browser browser(params);
109 scoped_refptr<ExtensionContextMenuModel> menu(
110 new ExtensionContextMenuModel(extension.get(), &browser));
112 extensions::ExtensionSystem* system =
113 extensions::ExtensionSystem::Get(profile_.get());
114 system->management_policy()->UnregisterAllProviders();
116 // Actions should be enabled.
117 ASSERT_TRUE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL));
119 extensions::TestManagementPolicyProvider policy_provider(
120 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
121 system->management_policy()->RegisterProvider(&policy_provider);
123 // Now the actions are disabled.
124 ASSERT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL));
126 // Don't leave |policy_provider| dangling.
127 system->management_policy()->UnregisterAllProviders();
130 TEST_F(ExtensionContextMenuModelTest, ExtensionItemTest) {
131 InitializeEmptyExtensionService();
132 scoped_refptr<Extension> extension = BuildExtension();
133 ASSERT_TRUE(extension.get());
134 service_->AddExtension(extension.get());
136 // Create a Browser for the ExtensionContextMenuModel to use.
137 Browser::CreateParams params(profile_.get(), chrome::GetActiveDesktop());
138 TestBrowserWindow test_window;
139 params.window = &test_window;
140 Browser browser(params);
142 // Create a MenuManager for adding context items.
143 MenuManager* manager = static_cast<MenuManager*>(
144 (MenuManagerFactory::GetInstance()->SetTestingFactoryAndUse(
146 &MenuManagerFactory::BuildServiceInstanceForTesting)));
147 ASSERT_TRUE(manager);
149 scoped_refptr<ExtensionContextMenuModel> menu(
150 new ExtensionContextMenuModel(extension.get(), &browser));
152 // There should be no extension items yet.
153 EXPECT_EQ(0, CountExtensionItems(menu));
155 // Add a browser action menu item for |extension| to |manager|.
156 AddContextItemAndRefreshModel(
157 manager, extension.get(), MenuItem::BROWSER_ACTION, menu);
159 // Since |extension| has a page action, the browser action menu item should
161 EXPECT_EQ(0, CountExtensionItems(menu));
163 // Add a page action menu item and reset the context menu.
164 AddContextItemAndRefreshModel(
165 manager, extension.get(), MenuItem::PAGE_ACTION, menu);
167 // The page action item should be present because |extension| has a page
169 EXPECT_EQ(1, CountExtensionItems(menu));
171 // Create more page action items to test top level menu item limitations.
172 for (int i = 0; i < api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT; ++i)
173 AddContextItemAndRefreshModel(
174 manager, extension.get(), MenuItem::PAGE_ACTION, menu);
176 // The menu should only have a limited number of extension items, since they
177 // are all top level items, and we limit the number of top level extension
179 EXPECT_EQ(api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT,
180 CountExtensionItems(menu));
182 AddContextItemAndRefreshModel(
183 manager, extension.get(), MenuItem::PAGE_ACTION, menu);
185 // Adding another top level item should not increase the count.
186 EXPECT_EQ(api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT,
187 CountExtensionItems(menu));
191 } // namespace extensions