blob: a70ce42dc1df1e12e4bdbe72157c1ad08c3b5917 [file] [log] [blame]
[email protected]f20d7332011-03-08 21:11:531// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]2e3b5202010-03-23 06:52:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <vector>
6
7#include "base/json/json_reader.h"
[email protected]3b63f8f42011-03-28 01:54:158#include "base/memory/scoped_vector.h"
[email protected]2e3b5202010-03-23 06:52:419#include "base/path_service.h"
[email protected]e0785902011-05-19 23:34:1710#include "base/scoped_temp_dir.h"
[email protected]944b4212010-12-14 00:00:3311#include "base/utf_string_conversions.h"
[email protected]2e3b5202010-03-23 06:52:4112#include "base/values.h"
[email protected]2c699652010-10-15 18:22:4113#include "chrome/browser/extensions/extension_event_router.h"
[email protected]2e3b5202010-03-23 06:52:4114#include "chrome/browser/extensions/extension_menu_manager.h"
[email protected]052c92702010-06-25 07:25:5215#include "chrome/browser/extensions/test_extension_prefs.h"
[email protected]432115822011-07-10 15:52:2716#include "chrome/common/chrome_notification_types.h"
[email protected]2e3b5202010-03-23 06:52:4117#include "chrome/common/chrome_paths.h"
18#include "chrome/common/extensions/extension.h"
19#include "chrome/common/extensions/extension_constants.h"
[email protected]bf9257742011-08-11 21:01:1520#include "chrome/test/base/testing_browser_process_test.h"
[email protected]a4ff9eae2011-08-01 19:58:1621#include "chrome/test/base/testing_profile.h"
[email protected]1bda97552011-03-01 20:11:5222#include "content/browser/browser_thread.h"
[email protected]f20d7332011-03-08 21:11:5323#include "content/common/notification_service.h"
[email protected]2e3b5202010-03-23 06:52:4124#include "testing/gmock/include/gmock/gmock.h"
[email protected]f20d7332011-03-08 21:11:5325#include "testing/gtest/include/gtest/gtest.h"
[email protected]2e3b5202010-03-23 06:52:4126#include "webkit/glue/context_menu.h"
27
28using testing::_;
29using testing::AtLeast;
30using testing::Return;
31using testing::SaveArg;
32
33// Base class for tests.
[email protected]a5f9f372011-08-03 23:02:2134class ExtensionMenuManagerTest : public TestingBrowserProcessTest {
[email protected]2e3b5202010-03-23 06:52:4135 public:
[email protected]6cad5bf2011-03-10 21:21:5536 ExtensionMenuManagerTest()
37 : ui_thread_(BrowserThread::UI, &message_loop_),
38 file_thread_(BrowserThread::FILE, &message_loop_),
39 next_id_(1) {
40 }
[email protected]2e3b5202010-03-23 06:52:4141
[email protected]052c92702010-06-25 07:25:5242 // Returns a test item.
[email protected]f4f04592010-07-14 20:40:1343 ExtensionMenuItem* CreateTestItem(Extension* extension) {
[email protected]2e3b5202010-03-23 06:52:4144 ExtensionMenuItem::Type type = ExtensionMenuItem::NORMAL;
45 ExtensionMenuItem::ContextList contexts(ExtensionMenuItem::ALL);
[email protected]5a7b5eaf2010-11-02 20:52:1946 ExtensionMenuItem::Id id(NULL, extension->id(), next_id_++);
[email protected]f4f04592010-07-14 20:40:1347 return new ExtensionMenuItem(id, "test", false, type, contexts);
[email protected]06a0c94e2010-06-24 23:20:1548 }
49
[email protected]052c92702010-06-25 07:25:5250 // Creates and returns a test Extension. The caller does *not* own the return
51 // value.
52 Extension* AddExtension(std::string name) {
[email protected]66e4eb32010-10-27 20:37:4153 scoped_refptr<Extension> extension = prefs_.AddExtension(name);
[email protected]819faeb02010-06-25 21:16:2254 extensions_.push_back(extension);
55 return extension;
[email protected]052c92702010-06-25 07:25:5256 }
57
[email protected]2e3b5202010-03-23 06:52:4158 protected:
[email protected]6cad5bf2011-03-10 21:21:5559 MessageLoopForUI message_loop_;
60 BrowserThread ui_thread_;
61 BrowserThread file_thread_;
62
[email protected]2e3b5202010-03-23 06:52:4163 ExtensionMenuManager manager_;
[email protected]66e4eb32010-10-27 20:37:4164 ExtensionList extensions_;
[email protected]052c92702010-06-25 07:25:5265 TestExtensionPrefs prefs_;
[email protected]f4f04592010-07-14 20:40:1366 int next_id_;
[email protected]2e3b5202010-03-23 06:52:4167
68 private:
69 DISALLOW_COPY_AND_ASSIGN(ExtensionMenuManagerTest);
70};
71
72// Tests adding, getting, and removing items.
73TEST_F(ExtensionMenuManagerTest, AddGetRemoveItems) {
[email protected]052c92702010-06-25 07:25:5274 Extension* extension = AddExtension("test");
75
[email protected]2e3b5202010-03-23 06:52:4176 // Add a new item, make sure you can get it back.
[email protected]052c92702010-06-25 07:25:5277 ExtensionMenuItem* item1 = CreateTestItem(extension);
[email protected]2e3b5202010-03-23 06:52:4178 ASSERT_TRUE(item1 != NULL);
[email protected]f4f04592010-07-14 20:40:1379 ASSERT_TRUE(manager_.AddContextItem(extension, item1));
80 ASSERT_EQ(item1, manager_.GetItemById(item1->id()));
[email protected]63a414b52010-06-03 23:20:4981 const ExtensionMenuItem::List* items =
[email protected]2e3b5202010-03-23 06:52:4182 manager_.MenuItems(item1->extension_id());
[email protected]63a414b52010-06-03 23:20:4983 ASSERT_EQ(1u, items->size());
84 ASSERT_EQ(item1, items->at(0));
[email protected]2e3b5202010-03-23 06:52:4185
86 // Add a second item, make sure it comes back too.
[email protected]052c92702010-06-25 07:25:5287 ExtensionMenuItem* item2 = CreateTestItem(extension);
[email protected]f4f04592010-07-14 20:40:1388 ASSERT_TRUE(manager_.AddContextItem(extension, item2));
89 ASSERT_EQ(item2, manager_.GetItemById(item2->id()));
[email protected]2e3b5202010-03-23 06:52:4190 items = manager_.MenuItems(item2->extension_id());
[email protected]63a414b52010-06-03 23:20:4991 ASSERT_EQ(2u, items->size());
92 ASSERT_EQ(item1, items->at(0));
93 ASSERT_EQ(item2, items->at(1));
[email protected]2e3b5202010-03-23 06:52:4194
95 // Try adding item 3, then removing it.
[email protected]052c92702010-06-25 07:25:5296 ExtensionMenuItem* item3 = CreateTestItem(extension);
[email protected]f4f04592010-07-14 20:40:1397 ExtensionMenuItem::Id id3 = item3->id();
[email protected]2e3b5202010-03-23 06:52:4198 std::string extension_id = item3->extension_id();
[email protected]f4f04592010-07-14 20:40:1399 ASSERT_TRUE(manager_.AddContextItem(extension, item3));
[email protected]2e3b5202010-03-23 06:52:41100 ASSERT_EQ(item3, manager_.GetItemById(id3));
[email protected]63a414b52010-06-03 23:20:49101 ASSERT_EQ(3u, manager_.MenuItems(extension_id)->size());
[email protected]2e3b5202010-03-23 06:52:41102 ASSERT_TRUE(manager_.RemoveContextMenuItem(id3));
103 ASSERT_EQ(NULL, manager_.GetItemById(id3));
[email protected]63a414b52010-06-03 23:20:49104 ASSERT_EQ(2u, manager_.MenuItems(extension_id)->size());
[email protected]2e3b5202010-03-23 06:52:41105
106 // Make sure removing a non-existent item returns false.
[email protected]5a7b5eaf2010-11-02 20:52:19107 ExtensionMenuItem::Id id(NULL, extension->id(), id3.uid + 50);
[email protected]f4f04592010-07-14 20:40:13108 ASSERT_FALSE(manager_.RemoveContextMenuItem(id));
[email protected]2e3b5202010-03-23 06:52:41109}
110
111// Test adding/removing child items.
112TEST_F(ExtensionMenuManagerTest, ChildFunctions) {
[email protected]052c92702010-06-25 07:25:52113 Extension* extension1 = AddExtension("1111");
114 Extension* extension2 = AddExtension("2222");
115 Extension* extension3 = AddExtension("3333");
[email protected]2e3b5202010-03-23 06:52:41116
[email protected]052c92702010-06-25 07:25:52117 ExtensionMenuItem* item1 = CreateTestItem(extension1);
118 ExtensionMenuItem* item2 = CreateTestItem(extension2);
119 ExtensionMenuItem* item2_child = CreateTestItem(extension2);
120 ExtensionMenuItem* item2_grandchild = CreateTestItem(extension2);
[email protected]2e3b5202010-03-23 06:52:41121
122 // This third item we expect to fail inserting, so we use a scoped_ptr to make
123 // sure it gets deleted.
[email protected]052c92702010-06-25 07:25:52124 scoped_ptr<ExtensionMenuItem> item3(CreateTestItem(extension3));
[email protected]2e3b5202010-03-23 06:52:41125
126 // Add in the first two items.
[email protected]f4f04592010-07-14 20:40:13127 ASSERT_TRUE(manager_.AddContextItem(extension1, item1));
128 ASSERT_TRUE(manager_.AddContextItem(extension2, item2));
[email protected]2e3b5202010-03-23 06:52:41129
[email protected]f4f04592010-07-14 20:40:13130 ExtensionMenuItem::Id id1 = item1->id();
131 ExtensionMenuItem::Id id2 = item2->id();
[email protected]2e3b5202010-03-23 06:52:41132
133 // Try adding item3 as a child of item2 - this should fail because item3 has
134 // a different extension id.
[email protected]f4f04592010-07-14 20:40:13135 ASSERT_FALSE(manager_.AddChildItem(id2, item3.get()));
[email protected]2e3b5202010-03-23 06:52:41136
137 // Add item2_child as a child of item2.
[email protected]f4f04592010-07-14 20:40:13138 ExtensionMenuItem::Id id2_child = item2_child->id();
139 ASSERT_TRUE(manager_.AddChildItem(id2, item2_child));
[email protected]2e3b5202010-03-23 06:52:41140 ASSERT_EQ(1, item2->child_count());
141 ASSERT_EQ(0, item1->child_count());
142 ASSERT_EQ(item2_child, manager_.GetItemById(id2_child));
143
[email protected]63a414b52010-06-03 23:20:49144 ASSERT_EQ(1u, manager_.MenuItems(item1->extension_id())->size());
145 ASSERT_EQ(item1, manager_.MenuItems(item1->extension_id())->at(0));
[email protected]2e3b5202010-03-23 06:52:41146
147 // Add item2_grandchild as a child of item2_child, then remove it.
[email protected]f4f04592010-07-14 20:40:13148 ExtensionMenuItem::Id id2_grandchild = item2_grandchild->id();
149 ASSERT_TRUE(manager_.AddChildItem(id2_child, item2_grandchild));
[email protected]2e3b5202010-03-23 06:52:41150 ASSERT_EQ(1, item2->child_count());
151 ASSERT_EQ(1, item2_child->child_count());
152 ASSERT_TRUE(manager_.RemoveContextMenuItem(id2_grandchild));
153
154 // We should only get 1 thing back when asking for item2's extension id, since
155 // it has a child item.
[email protected]63a414b52010-06-03 23:20:49156 ASSERT_EQ(1u, manager_.MenuItems(item2->extension_id())->size());
157 ASSERT_EQ(item2, manager_.MenuItems(item2->extension_id())->at(0));
[email protected]2e3b5202010-03-23 06:52:41158
159 // Remove child2_item.
160 ASSERT_TRUE(manager_.RemoveContextMenuItem(id2_child));
[email protected]63a414b52010-06-03 23:20:49161 ASSERT_EQ(1u, manager_.MenuItems(item2->extension_id())->size());
162 ASSERT_EQ(item2, manager_.MenuItems(item2->extension_id())->at(0));
[email protected]2e3b5202010-03-23 06:52:41163 ASSERT_EQ(0, item2->child_count());
164}
165
[email protected]2b07c93f2010-08-02 23:13:04166// Tests that deleting a parent properly removes descendants.
167TEST_F(ExtensionMenuManagerTest, DeleteParent) {
168 Extension* extension = AddExtension("1111");
169
170 // Set up 5 items to add.
171 ExtensionMenuItem* item1 = CreateTestItem(extension);
172 ExtensionMenuItem* item2 = CreateTestItem(extension);
173 ExtensionMenuItem* item3 = CreateTestItem(extension);
174 ExtensionMenuItem* item4 = CreateTestItem(extension);
175 ExtensionMenuItem* item5 = CreateTestItem(extension);
176 ExtensionMenuItem* item6 = CreateTestItem(extension);
177 ExtensionMenuItem::Id item1_id = item1->id();
178 ExtensionMenuItem::Id item2_id = item2->id();
179 ExtensionMenuItem::Id item3_id = item3->id();
180 ExtensionMenuItem::Id item4_id = item4->id();
181 ExtensionMenuItem::Id item5_id = item5->id();
182 ExtensionMenuItem::Id item6_id = item6->id();
183
184 // Add the items in the hierarchy
185 // item1 -> item2 -> item3 -> item4 -> item5 -> item6.
186 ASSERT_TRUE(manager_.AddContextItem(extension, item1));
187 ASSERT_TRUE(manager_.AddChildItem(item1_id, item2));
188 ASSERT_TRUE(manager_.AddChildItem(item2_id, item3));
189 ASSERT_TRUE(manager_.AddChildItem(item3_id, item4));
190 ASSERT_TRUE(manager_.AddChildItem(item4_id, item5));
191 ASSERT_TRUE(manager_.AddChildItem(item5_id, item6));
192 ASSERT_EQ(item1, manager_.GetItemById(item1_id));
193 ASSERT_EQ(item2, manager_.GetItemById(item2_id));
194 ASSERT_EQ(item3, manager_.GetItemById(item3_id));
195 ASSERT_EQ(item4, manager_.GetItemById(item4_id));
196 ASSERT_EQ(item5, manager_.GetItemById(item5_id));
197 ASSERT_EQ(item6, manager_.GetItemById(item6_id));
198 ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size());
199 ASSERT_EQ(6u, manager_.items_by_id_.size());
200
201 // Remove item6 (a leaf node).
202 ASSERT_TRUE(manager_.RemoveContextMenuItem(item6_id));
203 ASSERT_EQ(item1, manager_.GetItemById(item1_id));
204 ASSERT_EQ(item2, manager_.GetItemById(item2_id));
205 ASSERT_EQ(item3, manager_.GetItemById(item3_id));
206 ASSERT_EQ(item4, manager_.GetItemById(item4_id));
207 ASSERT_EQ(item5, manager_.GetItemById(item5_id));
208 ASSERT_EQ(NULL, manager_.GetItemById(item6_id));
209 ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size());
210 ASSERT_EQ(5u, manager_.items_by_id_.size());
211
212 // Remove item4 and make sure item5 is gone as well.
213 ASSERT_TRUE(manager_.RemoveContextMenuItem(item4_id));
214 ASSERT_EQ(item1, manager_.GetItemById(item1_id));
215 ASSERT_EQ(item2, manager_.GetItemById(item2_id));
216 ASSERT_EQ(item3, manager_.GetItemById(item3_id));
217 ASSERT_EQ(NULL, manager_.GetItemById(item4_id));
218 ASSERT_EQ(NULL, manager_.GetItemById(item5_id));
219 ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size());
220 ASSERT_EQ(3u, manager_.items_by_id_.size());
221
222 // Now remove item1 and make sure item2 and item3 are gone as well.
223 ASSERT_TRUE(manager_.RemoveContextMenuItem(item1_id));
[email protected]f50da8592010-10-28 23:39:32224 ASSERT_EQ(NULL, manager_.MenuItems(extension->id()));
[email protected]2b07c93f2010-08-02 23:13:04225 ASSERT_EQ(0u, manager_.items_by_id_.size());
226 ASSERT_EQ(NULL, manager_.GetItemById(item1_id));
227 ASSERT_EQ(NULL, manager_.GetItemById(item2_id));
228 ASSERT_EQ(NULL, manager_.GetItemById(item3_id));
229}
230
[email protected]66dbfb2c2010-05-12 20:20:15231// Tests changing parents.
232TEST_F(ExtensionMenuManagerTest, ChangeParent) {
[email protected]052c92702010-06-25 07:25:52233 Extension* extension1 = AddExtension("1111");
[email protected]06a0c94e2010-06-24 23:20:15234
[email protected]052c92702010-06-25 07:25:52235 // First create two items and add them both to the manager.
236 ExtensionMenuItem* item1 = CreateTestItem(extension1);
237 ExtensionMenuItem* item2 = CreateTestItem(extension1);
238
[email protected]f4f04592010-07-14 20:40:13239 ASSERT_TRUE(manager_.AddContextItem(extension1, item1));
240 ASSERT_TRUE(manager_.AddContextItem(extension1, item2));
[email protected]66dbfb2c2010-05-12 20:20:15241
[email protected]63a414b52010-06-03 23:20:49242 const ExtensionMenuItem::List* items =
[email protected]66dbfb2c2010-05-12 20:20:15243 manager_.MenuItems(item1->extension_id());
[email protected]63a414b52010-06-03 23:20:49244 ASSERT_EQ(2u, items->size());
245 ASSERT_EQ(item1, items->at(0));
246 ASSERT_EQ(item2, items->at(1));
[email protected]66dbfb2c2010-05-12 20:20:15247
248 // Now create a third item, initially add it as a child of item1, then move
249 // it to be a child of item2.
[email protected]052c92702010-06-25 07:25:52250 ExtensionMenuItem* item3 = CreateTestItem(extension1);
[email protected]66dbfb2c2010-05-12 20:20:15251
[email protected]f4f04592010-07-14 20:40:13252 ASSERT_TRUE(manager_.AddChildItem(item1->id(), item3));
[email protected]66dbfb2c2010-05-12 20:20:15253 ASSERT_EQ(1, item1->child_count());
[email protected]63a414b52010-06-03 23:20:49254 ASSERT_EQ(item3, item1->children()[0]);
[email protected]66dbfb2c2010-05-12 20:20:15255
[email protected]f4f04592010-07-14 20:40:13256 ASSERT_TRUE(manager_.ChangeParent(item3->id(), &item2->id()));
[email protected]66dbfb2c2010-05-12 20:20:15257 ASSERT_EQ(0, item1->child_count());
258 ASSERT_EQ(1, item2->child_count());
[email protected]63a414b52010-06-03 23:20:49259 ASSERT_EQ(item3, item2->children()[0]);
[email protected]66dbfb2c2010-05-12 20:20:15260
261 // Move item2 to be a child of item1.
[email protected]f4f04592010-07-14 20:40:13262 ASSERT_TRUE(manager_.ChangeParent(item2->id(), &item1->id()));
[email protected]66dbfb2c2010-05-12 20:20:15263 ASSERT_EQ(1, item1->child_count());
[email protected]63a414b52010-06-03 23:20:49264 ASSERT_EQ(item2, item1->children()[0]);
[email protected]66dbfb2c2010-05-12 20:20:15265 ASSERT_EQ(1, item2->child_count());
[email protected]63a414b52010-06-03 23:20:49266 ASSERT_EQ(item3, item2->children()[0]);
[email protected]66dbfb2c2010-05-12 20:20:15267
268 // Since item2 was a top-level item but is no longer, we should only have 1
269 // top-level item.
270 items = manager_.MenuItems(item1->extension_id());
[email protected]63a414b52010-06-03 23:20:49271 ASSERT_EQ(1u, items->size());
272 ASSERT_EQ(item1, items->at(0));
[email protected]66dbfb2c2010-05-12 20:20:15273
274 // Move item3 back to being a child of item1, so it's now a sibling of item2.
[email protected]f4f04592010-07-14 20:40:13275 ASSERT_TRUE(manager_.ChangeParent(item3->id(), &item1->id()));
[email protected]66dbfb2c2010-05-12 20:20:15276 ASSERT_EQ(2, item1->child_count());
[email protected]63a414b52010-06-03 23:20:49277 ASSERT_EQ(item2, item1->children()[0]);
278 ASSERT_EQ(item3, item1->children()[1]);
[email protected]66dbfb2c2010-05-12 20:20:15279
280 // Try switching item3 to be the parent of item1 - this should fail.
[email protected]f4f04592010-07-14 20:40:13281 ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item3->id()));
[email protected]66dbfb2c2010-05-12 20:20:15282 ASSERT_EQ(0, item3->child_count());
283 ASSERT_EQ(2, item1->child_count());
[email protected]63a414b52010-06-03 23:20:49284 ASSERT_EQ(item2, item1->children()[0]);
285 ASSERT_EQ(item3, item1->children()[1]);
[email protected]66dbfb2c2010-05-12 20:20:15286 items = manager_.MenuItems(item1->extension_id());
[email protected]63a414b52010-06-03 23:20:49287 ASSERT_EQ(1u, items->size());
288 ASSERT_EQ(item1, items->at(0));
[email protected]66dbfb2c2010-05-12 20:20:15289
290 // Move item2 to be a top-level item.
[email protected]f4f04592010-07-14 20:40:13291 ASSERT_TRUE(manager_.ChangeParent(item2->id(), NULL));
[email protected]66dbfb2c2010-05-12 20:20:15292 items = manager_.MenuItems(item1->extension_id());
[email protected]63a414b52010-06-03 23:20:49293 ASSERT_EQ(2u, items->size());
294 ASSERT_EQ(item1, items->at(0));
295 ASSERT_EQ(item2, items->at(1));
[email protected]66dbfb2c2010-05-12 20:20:15296 ASSERT_EQ(1, item1->child_count());
[email protected]63a414b52010-06-03 23:20:49297 ASSERT_EQ(item3, item1->children()[0]);
[email protected]66dbfb2c2010-05-12 20:20:15298
299 // Make sure you can't move a node to be a child of another extension's item.
[email protected]052c92702010-06-25 07:25:52300 Extension* extension2 = AddExtension("2222");
301 ExtensionMenuItem* item4 = CreateTestItem(extension2);
[email protected]f4f04592010-07-14 20:40:13302 ASSERT_TRUE(manager_.AddContextItem(extension2, item4));
303 ASSERT_FALSE(manager_.ChangeParent(item4->id(), &item1->id()));
304 ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item4->id()));
[email protected]66dbfb2c2010-05-12 20:20:15305
306 // Make sure you can't make an item be it's own parent.
[email protected]f4f04592010-07-14 20:40:13307 ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item1->id()));
[email protected]66dbfb2c2010-05-12 20:20:15308}
309
[email protected]2e3b5202010-03-23 06:52:41310// Tests that we properly remove an extension's menu item when that extension is
311// unloaded.
312TEST_F(ExtensionMenuManagerTest, ExtensionUnloadRemovesMenuItems) {
[email protected]2e3b5202010-03-23 06:52:41313 NotificationService* notifier = NotificationService::current();
314 ASSERT_TRUE(notifier != NULL);
315
316 // Create a test extension.
[email protected]052c92702010-06-25 07:25:52317 Extension* extension1 = AddExtension("1111");
[email protected]2e3b5202010-03-23 06:52:41318
319 // Create an ExtensionMenuItem and put it into the manager.
[email protected]052c92702010-06-25 07:25:52320 ExtensionMenuItem* item1 = CreateTestItem(extension1);
[email protected]f4f04592010-07-14 20:40:13321 ExtensionMenuItem::Id id1 = item1->id();
[email protected]052c92702010-06-25 07:25:52322 ASSERT_EQ(extension1->id(), item1->extension_id());
[email protected]f4f04592010-07-14 20:40:13323 ASSERT_TRUE(manager_.AddContextItem(extension1, item1));
[email protected]052c92702010-06-25 07:25:52324 ASSERT_EQ(1u, manager_.MenuItems(extension1->id())->size());
[email protected]2e3b5202010-03-23 06:52:41325
326 // Create a menu item with a different extension id and add it to the manager.
[email protected]052c92702010-06-25 07:25:52327 Extension* extension2 = AddExtension("2222");
328 ExtensionMenuItem* item2 = CreateTestItem(extension2);
[email protected]2e3b5202010-03-23 06:52:41329 ASSERT_NE(item1->extension_id(), item2->extension_id());
[email protected]f4f04592010-07-14 20:40:13330 ASSERT_TRUE(manager_.AddContextItem(extension2, item2));
[email protected]2e3b5202010-03-23 06:52:41331
332 // Notify that the extension was unloaded, and make sure the right item is
333 // gone.
[email protected]814a7bf0f2011-08-13 05:30:59334 UnloadedExtensionInfo details(
335 extension1, extension_misc::UNLOAD_REASON_DISABLE);
[email protected]432115822011-07-10 15:52:27336 notifier->Notify(chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]2e3b5202010-03-23 06:52:41337 Source<Profile>(NULL),
[email protected]a9f39a312010-12-23 22:14:27338 Details<UnloadedExtensionInfo>(&details));
[email protected]052c92702010-06-25 07:25:52339 ASSERT_EQ(NULL, manager_.MenuItems(extension1->id()));
340 ASSERT_EQ(1u, manager_.MenuItems(extension2->id())->size());
[email protected]2e3b5202010-03-23 06:52:41341 ASSERT_TRUE(manager_.GetItemById(id1) == NULL);
[email protected]f4f04592010-07-14 20:40:13342 ASSERT_TRUE(manager_.GetItemById(item2->id()) != NULL);
[email protected]2e3b5202010-03-23 06:52:41343}
344
345// A mock message service for tests of ExtensionMenuManager::ExecuteCommand.
[email protected]2c699652010-10-15 18:22:41346class MockExtensionEventRouter : public ExtensionEventRouter {
[email protected]2e3b5202010-03-23 06:52:41347 public:
[email protected]2c699652010-10-15 18:22:41348 explicit MockExtensionEventRouter(Profile* profile) :
349 ExtensionEventRouter(profile) {}
[email protected]2e3b5202010-03-23 06:52:41350
[email protected]0a184b52011-06-23 00:41:13351 MOCK_METHOD6(DispatchEventImpl, void(const std::string& extension_id,
[email protected]a7ab1b782010-10-21 23:24:16352 const std::string& event_name,
353 const std::string& event_args,
354 Profile* source_profile,
[email protected]0a184b52011-06-23 00:41:13355 const std::string& cross_incognito_args,
[email protected]a7ab1b782010-10-21 23:24:16356 const GURL& event_url));
[email protected]2e3b5202010-03-23 06:52:41357
358 private:
[email protected]2c699652010-10-15 18:22:41359 DISALLOW_COPY_AND_ASSIGN(MockExtensionEventRouter);
[email protected]2e3b5202010-03-23 06:52:41360};
361
362// A mock profile for tests of ExtensionMenuManager::ExecuteCommand.
363class MockTestingProfile : public TestingProfile {
364 public:
365 MockTestingProfile() {}
[email protected]2c699652010-10-15 18:22:41366 MOCK_METHOD0(GetExtensionEventRouter, ExtensionEventRouter*());
[email protected]2e3b5202010-03-23 06:52:41367 MOCK_METHOD0(IsOffTheRecord, bool());
368
369 private:
370 DISALLOW_COPY_AND_ASSIGN(MockTestingProfile);
371};
372
[email protected]66dbfb2c2010-05-12 20:20:15373// Tests the RemoveAll functionality.
374TEST_F(ExtensionMenuManagerTest, RemoveAll) {
375 // Try removing all items for an extension id that doesn't have any items.
376 manager_.RemoveAllContextItems("CCCC");
377
[email protected]052c92702010-06-25 07:25:52378 // Add 2 top-level and one child item for extension 1.
379 Extension* extension1 = AddExtension("1111");
380 ExtensionMenuItem* item1 = CreateTestItem(extension1);
381 ExtensionMenuItem* item2 = CreateTestItem(extension1);
382 ExtensionMenuItem* item3 = CreateTestItem(extension1);
[email protected]f4f04592010-07-14 20:40:13383 ASSERT_TRUE(manager_.AddContextItem(extension1, item1));
384 ASSERT_TRUE(manager_.AddContextItem(extension1, item2));
385 ASSERT_TRUE(manager_.AddChildItem(item1->id(), item3));
[email protected]66dbfb2c2010-05-12 20:20:15386
[email protected]052c92702010-06-25 07:25:52387 // Add one top-level item for extension 2.
388 Extension* extension2 = AddExtension("2222");
389 ExtensionMenuItem* item4 = CreateTestItem(extension2);
[email protected]f4f04592010-07-14 20:40:13390 ASSERT_TRUE(manager_.AddContextItem(extension2, item4));
[email protected]66dbfb2c2010-05-12 20:20:15391
[email protected]052c92702010-06-25 07:25:52392 EXPECT_EQ(2u, manager_.MenuItems(extension1->id())->size());
393 EXPECT_EQ(1u, manager_.MenuItems(extension2->id())->size());
[email protected]66dbfb2c2010-05-12 20:20:15394
[email protected]052c92702010-06-25 07:25:52395 // Remove extension2's item.
396 manager_.RemoveAllContextItems(extension2->id());
397 EXPECT_EQ(2u, manager_.MenuItems(extension1->id())->size());
398 EXPECT_EQ(NULL, manager_.MenuItems(extension2->id()));
[email protected]66dbfb2c2010-05-12 20:20:15399
[email protected]052c92702010-06-25 07:25:52400 // Remove extension1's items.
401 manager_.RemoveAllContextItems(extension1->id());
402 EXPECT_EQ(NULL, manager_.MenuItems(extension1->id()));
[email protected]66dbfb2c2010-05-12 20:20:15403}
404
[email protected]f50da8592010-10-28 23:39:32405// Tests that removing all items one-by-one doesn't leave an entry around.
406TEST_F(ExtensionMenuManagerTest, RemoveOneByOne) {
407 // Add 2 test items.
408 Extension* extension1 = AddExtension("1111");
409 ExtensionMenuItem* item1 = CreateTestItem(extension1);
410 ExtensionMenuItem* item2 = CreateTestItem(extension1);
411 ASSERT_TRUE(manager_.AddContextItem(extension1, item1));
412 ASSERT_TRUE(manager_.AddContextItem(extension1, item2));
413
414 ASSERT_FALSE(manager_.context_items_.empty());
415
416 manager_.RemoveContextMenuItem(item1->id());
417 manager_.RemoveContextMenuItem(item2->id());
418
419 ASSERT_TRUE(manager_.context_items_.empty());
420}
421
[email protected]2e3b5202010-03-23 06:52:41422TEST_F(ExtensionMenuManagerTest, ExecuteCommand) {
[email protected]2e3b5202010-03-23 06:52:41423 MockTestingProfile profile;
424
[email protected]2c699652010-10-15 18:22:41425 scoped_ptr<MockExtensionEventRouter> mock_event_router(
426 new MockExtensionEventRouter(&profile));
[email protected]2e3b5202010-03-23 06:52:41427
428 ContextMenuParams params;
429 params.media_type = WebKit::WebContextMenuData::MediaTypeImage;
430 params.src_url = GURL("http://foo.bar/image.png");
431 params.page_url = GURL("http://foo.bar");
[email protected]944b4212010-12-14 00:00:33432 params.selection_text = ASCIIToUTF16("Hello World");
[email protected]2e3b5202010-03-23 06:52:41433 params.is_editable = false;
434
[email protected]052c92702010-06-25 07:25:52435 Extension* extension = AddExtension("test");
436 ExtensionMenuItem* item = CreateTestItem(extension);
[email protected]f4f04592010-07-14 20:40:13437 ExtensionMenuItem::Id id = item->id();
438 ASSERT_TRUE(manager_.AddContextItem(extension, item));
[email protected]2e3b5202010-03-23 06:52:41439
[email protected]2c699652010-10-15 18:22:41440 EXPECT_CALL(profile, GetExtensionEventRouter())
[email protected]2e3b5202010-03-23 06:52:41441 .Times(1)
[email protected]2c699652010-10-15 18:22:41442 .WillOnce(Return(mock_event_router.get()));
[email protected]2e3b5202010-03-23 06:52:41443
[email protected]2e3b5202010-03-23 06:52:41444 // Use the magic of googlemock to save a parameter to our mock's
[email protected]0a184b52011-06-23 00:41:13445 // DispatchEventToExtension method into event_args.
[email protected]2e3b5202010-03-23 06:52:41446 std::string event_args;
[email protected]a7ab1b782010-10-21 23:24:16447 std::string expected_event_name = "contextMenus";
[email protected]2c699652010-10-15 18:22:41448 EXPECT_CALL(*mock_event_router.get(),
[email protected]a7ab1b782010-10-21 23:24:16449 DispatchEventImpl(item->extension_id(),
450 expected_event_name,
451 _,
452 &profile,
[email protected]0a184b52011-06-23 00:41:13453 "",
[email protected]a7ab1b782010-10-21 23:24:16454 GURL()))
[email protected]2e3b5202010-03-23 06:52:41455 .Times(1)
[email protected]a7ab1b782010-10-21 23:24:16456 .WillOnce(SaveArg<2>(&event_args));
[email protected]2e3b5202010-03-23 06:52:41457
458 manager_.ExecuteCommand(&profile, NULL /* tab_contents */, params, id);
459
460 // Parse the json event_args, which should turn into a 2-element list where
461 // the first element is a dictionary we want to inspect for the correct
462 // values.
463 scoped_ptr<Value> result(base::JSONReader::Read(event_args, true));
464 Value* value = result.get();
465 ASSERT_TRUE(result.get() != NULL);
466 ASSERT_EQ(Value::TYPE_LIST, value->GetType());
467 ListValue* list = static_cast<ListValue*>(value);
468 ASSERT_EQ(2u, list->GetSize());
469
470 DictionaryValue* info;
471 ASSERT_TRUE(list->GetDictionary(0, &info));
472
473 int tmp_id = 0;
[email protected]88dc0692010-08-14 16:29:42474 ASSERT_TRUE(info->GetInteger("menuItemId", &tmp_id));
[email protected]5a7b5eaf2010-11-02 20:52:19475 ASSERT_EQ(id.uid, tmp_id);
[email protected]2e3b5202010-03-23 06:52:41476
477 std::string tmp;
[email protected]88dc0692010-08-14 16:29:42478 ASSERT_TRUE(info->GetString("mediaType", &tmp));
[email protected]1741b972010-08-04 23:47:41479 ASSERT_EQ("image", tmp);
[email protected]88dc0692010-08-14 16:29:42480 ASSERT_TRUE(info->GetString("srcUrl", &tmp));
[email protected]2e3b5202010-03-23 06:52:41481 ASSERT_EQ(params.src_url.spec(), tmp);
[email protected]88dc0692010-08-14 16:29:42482 ASSERT_TRUE(info->GetString("pageUrl", &tmp));
[email protected]2e3b5202010-03-23 06:52:41483 ASSERT_EQ(params.page_url.spec(), tmp);
484
[email protected]944b4212010-12-14 00:00:33485 string16 tmp16;
486 ASSERT_TRUE(info->GetString("selectionText", &tmp16));
487 ASSERT_EQ(params.selection_text, tmp16);
[email protected]2e3b5202010-03-23 06:52:41488
489 bool bool_tmp = true;
[email protected]88dc0692010-08-14 16:29:42490 ASSERT_TRUE(info->GetBoolean("editable", &bool_tmp));
[email protected]2e3b5202010-03-23 06:52:41491 ASSERT_EQ(params.is_editable, bool_tmp);
492}