[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 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 <vector> |
| 6 | |
[email protected] | ea1a3f6 | 2012-11-16 20:34:23 | [diff] [blame] | 7 | #include "base/files/scoped_temp_dir.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 8 | #include "base/json/json_reader.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 9 | #include "base/memory/scoped_vector.h" |
[email protected] | 3fc40c14 | 2011-12-01 13:09:04 | [diff] [blame] | 10 | #include "base/message_loop.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 11 | #include "base/path_service.h" |
[email protected] | 944b421 | 2010-12-14 00:00:33 | [diff] [blame] | 12 | #include "base/utf_string_conversions.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 13 | #include "base/values.h" |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 14 | #include "chrome/browser/extensions/event_names.h" |
| 15 | #include "chrome/browser/extensions/event_router.h" |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 16 | #include "chrome/browser/extensions/extension_system_factory.h" |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 17 | #include "chrome/browser/extensions/menu_manager.h" |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 18 | #include "chrome/browser/extensions/test_extension_prefs.h" |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 19 | #include "chrome/browser/extensions/test_extension_system.h" |
[email protected] | ea1a3f6 | 2012-11-16 20:34:23 | [diff] [blame] | 20 | #include "chrome/browser/prefs/pref_service.h" |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 21 | #include "chrome/common/chrome_notification_types.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 22 | #include "chrome/common/chrome_paths.h" |
| 23 | #include "chrome/common/extensions/extension.h" |
| 24 | #include "chrome/common/extensions/extension_constants.h" |
[email protected] | a4ff9eae | 2011-08-01 19:58:16 | [diff] [blame] | 25 | #include "chrome/test/base/testing_profile.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 26 | #include "content/public/browser/notification_service.h" |
[email protected] | 35be7ec | 2012-02-12 20:42:51 | [diff] [blame] | 27 | #include "content/public/common/context_menu_params.h" |
[email protected] | e97882f | 2012-06-04 02:23:17 | [diff] [blame] | 28 | #include "content/public/test/test_browser_thread.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 29 | #include "testing/gmock/include/gmock/gmock.h" |
[email protected] | f20d733 | 2011-03-08 21:11:53 | [diff] [blame] | 30 | #include "testing/gtest/include/gtest/gtest.h" |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 31 | |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 32 | using content::BrowserThread; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 33 | using testing::_; |
| 34 | using testing::AtLeast; |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 35 | using testing::DeleteArg; |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 36 | using testing::InSequence; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 37 | using testing::Return; |
| 38 | using testing::SaveArg; |
| 39 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 40 | namespace extensions { |
| 41 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 42 | // Base class for tests. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 43 | class MenuManagerTest : public testing::Test { |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 44 | public: |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 45 | MenuManagerTest() : ui_thread_(BrowserThread::UI, &message_loop_), |
| 46 | file_thread_(BrowserThread::FILE, &message_loop_), |
| 47 | manager_(&profile_), |
[email protected] | 0de615a | 2012-11-08 04:40:59 | [diff] [blame] | 48 | prefs_(message_loop_.message_loop_proxy()), |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 49 | next_id_(1) { |
[email protected] | 6cad5bf | 2011-03-10 21:21:55 | [diff] [blame] | 50 | } |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 51 | |
[email protected] | 0de615a | 2012-11-08 04:40:59 | [diff] [blame] | 52 | virtual void TearDown() OVERRIDE { |
| 53 | prefs_.pref_service()->CommitPendingWrite(); |
| 54 | message_loop_.RunUntilIdle(); |
| 55 | } |
| 56 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 57 | // Returns a test item. |
[email protected] | 6350346 | 2012-10-30 22:14:31 | [diff] [blame] | 58 | MenuItem* CreateTestItem(Extension* extension, bool incognito = false) { |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 59 | MenuItem::Type type = MenuItem::NORMAL; |
| 60 | MenuItem::ContextList contexts(MenuItem::ALL); |
[email protected] | 6350346 | 2012-10-30 22:14:31 | [diff] [blame] | 61 | MenuItem::Id id(incognito, extension->id()); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 62 | id.uid = next_id_++; |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 63 | return new MenuItem(id, "test", false, true, type, contexts); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | // Returns a test item with the given string ID. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 67 | MenuItem* CreateTestItemWithID(Extension* extension, |
| 68 | const std::string& string_id) { |
| 69 | MenuItem::Type type = MenuItem::NORMAL; |
| 70 | MenuItem::ContextList contexts(MenuItem::ALL); |
| 71 | MenuItem::Id id(false, extension->id()); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 72 | id.string_uid = string_id; |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 73 | return new MenuItem(id, "test", false, true, type, contexts); |
[email protected] | 06a0c94e | 2010-06-24 23:20:15 | [diff] [blame] | 74 | } |
| 75 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 76 | // Creates and returns a test Extension. The caller does *not* own the return |
| 77 | // value. |
| 78 | Extension* AddExtension(std::string name) { |
[email protected] | 66e4eb3 | 2010-10-27 20:37:41 | [diff] [blame] | 79 | scoped_refptr<Extension> extension = prefs_.AddExtension(name); |
[email protected] | 819faeb0 | 2010-06-25 21:16:22 | [diff] [blame] | 80 | extensions_.push_back(extension); |
| 81 | return extension; |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 82 | } |
| 83 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 84 | protected: |
[email protected] | 8b28030 | 2011-10-13 22:22:23 | [diff] [blame] | 85 | TestingProfile profile_; |
[email protected] | 6cad5bf | 2011-03-10 21:21:55 | [diff] [blame] | 86 | MessageLoopForUI message_loop_; |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 87 | content::TestBrowserThread ui_thread_; |
| 88 | content::TestBrowserThread file_thread_; |
[email protected] | 6cad5bf | 2011-03-10 21:21:55 | [diff] [blame] | 89 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 90 | MenuManager manager_; |
| 91 | ExtensionList extensions_; |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 92 | TestExtensionPrefs prefs_; |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 93 | int next_id_; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 94 | |
| 95 | private: |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 96 | DISALLOW_COPY_AND_ASSIGN(MenuManagerTest); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 97 | }; |
| 98 | |
| 99 | // Tests adding, getting, and removing items. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 100 | TEST_F(MenuManagerTest, AddGetRemoveItems) { |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 101 | Extension* extension = AddExtension("test"); |
| 102 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 103 | // Add a new item, make sure you can get it back. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 104 | MenuItem* item1 = CreateTestItem(extension); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 105 | ASSERT_TRUE(item1 != NULL); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 106 | ASSERT_TRUE(manager_.AddContextItem(extension, item1)); |
| 107 | ASSERT_EQ(item1, manager_.GetItemById(item1->id())); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 108 | const MenuItem::List* items = manager_.MenuItems(item1->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 109 | ASSERT_EQ(1u, items->size()); |
| 110 | ASSERT_EQ(item1, items->at(0)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 111 | |
| 112 | // Add a second item, make sure it comes back too. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 113 | MenuItem* item2 = CreateTestItemWithID(extension, "id2"); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 114 | ASSERT_TRUE(manager_.AddContextItem(extension, item2)); |
| 115 | ASSERT_EQ(item2, manager_.GetItemById(item2->id())); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 116 | items = manager_.MenuItems(item2->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 117 | ASSERT_EQ(2u, items->size()); |
| 118 | ASSERT_EQ(item1, items->at(0)); |
| 119 | ASSERT_EQ(item2, items->at(1)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 120 | |
| 121 | // Try adding item 3, then removing it. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 122 | MenuItem* item3 = CreateTestItem(extension); |
| 123 | MenuItem::Id id3 = item3->id(); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 124 | std::string extension_id = item3->extension_id(); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 125 | ASSERT_TRUE(manager_.AddContextItem(extension, item3)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 126 | ASSERT_EQ(item3, manager_.GetItemById(id3)); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 127 | ASSERT_EQ(3u, manager_.MenuItems(extension_id)->size()); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 128 | ASSERT_TRUE(manager_.RemoveContextMenuItem(id3)); |
| 129 | ASSERT_EQ(NULL, manager_.GetItemById(id3)); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 130 | ASSERT_EQ(2u, manager_.MenuItems(extension_id)->size()); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 131 | |
| 132 | // Make sure removing a non-existent item returns false. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 133 | MenuItem::Id id(false, extension->id()); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 134 | id.uid = id3.uid + 50; |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 135 | ASSERT_FALSE(manager_.RemoveContextMenuItem(id)); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 136 | |
| 137 | // Make sure adding an item with the same string ID returns false. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 138 | scoped_ptr<MenuItem> item2too(CreateTestItemWithID(extension, "id2")); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 139 | ASSERT_FALSE(manager_.AddContextItem(extension, item2too.get())); |
| 140 | |
| 141 | // But the same string ID should not collide with another extension. |
| 142 | Extension* extension2 = AddExtension("test2"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 143 | MenuItem* item2other = CreateTestItemWithID(extension2, "id2"); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 144 | ASSERT_TRUE(manager_.AddContextItem(extension2, item2other)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 145 | } |
| 146 | |
| 147 | // Test adding/removing child items. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 148 | TEST_F(MenuManagerTest, ChildFunctions) { |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 149 | Extension* extension1 = AddExtension("1111"); |
| 150 | Extension* extension2 = AddExtension("2222"); |
| 151 | Extension* extension3 = AddExtension("3333"); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 152 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 153 | MenuItem* item1 = CreateTestItem(extension1); |
| 154 | MenuItem* item2 = CreateTestItem(extension2); |
| 155 | MenuItem* item2_child = CreateTestItemWithID(extension2, "2child"); |
| 156 | MenuItem* item2_grandchild = CreateTestItem(extension2); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 157 | |
| 158 | // This third item we expect to fail inserting, so we use a scoped_ptr to make |
| 159 | // sure it gets deleted. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 160 | scoped_ptr<MenuItem> item3(CreateTestItem(extension3)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 161 | |
| 162 | // Add in the first two items. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 163 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
| 164 | ASSERT_TRUE(manager_.AddContextItem(extension2, item2)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 165 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 166 | MenuItem::Id id1 = item1->id(); |
| 167 | MenuItem::Id id2 = item2->id(); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 168 | |
| 169 | // Try adding item3 as a child of item2 - this should fail because item3 has |
| 170 | // a different extension id. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 171 | ASSERT_FALSE(manager_.AddChildItem(id2, item3.get())); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 172 | |
| 173 | // Add item2_child as a child of item2. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 174 | MenuItem::Id id2_child = item2_child->id(); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 175 | ASSERT_TRUE(manager_.AddChildItem(id2, item2_child)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 176 | ASSERT_EQ(1, item2->child_count()); |
| 177 | ASSERT_EQ(0, item1->child_count()); |
| 178 | ASSERT_EQ(item2_child, manager_.GetItemById(id2_child)); |
| 179 | |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 180 | ASSERT_EQ(1u, manager_.MenuItems(item1->extension_id())->size()); |
| 181 | ASSERT_EQ(item1, manager_.MenuItems(item1->extension_id())->at(0)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 182 | |
| 183 | // Add item2_grandchild as a child of item2_child, then remove it. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 184 | MenuItem::Id id2_grandchild = item2_grandchild->id(); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 185 | ASSERT_TRUE(manager_.AddChildItem(id2_child, item2_grandchild)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 186 | ASSERT_EQ(1, item2->child_count()); |
| 187 | ASSERT_EQ(1, item2_child->child_count()); |
| 188 | ASSERT_TRUE(manager_.RemoveContextMenuItem(id2_grandchild)); |
| 189 | |
| 190 | // We should only get 1 thing back when asking for item2's extension id, since |
| 191 | // it has a child item. |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 192 | ASSERT_EQ(1u, manager_.MenuItems(item2->extension_id())->size()); |
| 193 | ASSERT_EQ(item2, manager_.MenuItems(item2->extension_id())->at(0)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 194 | |
| 195 | // Remove child2_item. |
| 196 | ASSERT_TRUE(manager_.RemoveContextMenuItem(id2_child)); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 197 | ASSERT_EQ(1u, manager_.MenuItems(item2->extension_id())->size()); |
| 198 | ASSERT_EQ(item2, manager_.MenuItems(item2->extension_id())->at(0)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 199 | ASSERT_EQ(0, item2->child_count()); |
| 200 | } |
| 201 | |
[email protected] | 8af81c0 | 2012-08-14 23:06:15 | [diff] [blame] | 202 | TEST_F(MenuManagerTest, PopulateFromValue) { |
| 203 | Extension* extension = AddExtension("test"); |
| 204 | |
| 205 | bool incognito = true; |
| 206 | int type = MenuItem::CHECKBOX; |
| 207 | std::string title("TITLE"); |
| 208 | bool checked = true; |
| 209 | bool enabled = true; |
| 210 | MenuItem::ContextList contexts; |
| 211 | contexts.Add(MenuItem::PAGE); |
| 212 | contexts.Add(MenuItem::SELECTION); |
| 213 | int contexts_value = 0; |
| 214 | ASSERT_TRUE(contexts.ToValue()->GetAsInteger(&contexts_value)); |
| 215 | |
| 216 | ListValue* document_url_patterns(new ListValue()); |
| 217 | document_url_patterns->Append( |
| 218 | Value::CreateStringValue("http://www.google.com/*")); |
| 219 | document_url_patterns->Append( |
| 220 | Value::CreateStringValue("http://www.reddit.com/*")); |
| 221 | |
| 222 | ListValue* target_url_patterns(new ListValue()); |
| 223 | target_url_patterns->Append( |
| 224 | Value::CreateStringValue("http://www.yahoo.com/*")); |
| 225 | target_url_patterns->Append( |
| 226 | Value::CreateStringValue("http://www.facebook.com/*")); |
| 227 | |
| 228 | base::DictionaryValue value; |
| 229 | value.SetBoolean("incognito", incognito); |
| 230 | value.SetString("string_uid", std::string()); |
| 231 | value.SetInteger("type", type); |
| 232 | value.SetString("title", title); |
| 233 | value.SetBoolean("checked", checked); |
| 234 | value.SetBoolean("enabled", enabled); |
| 235 | value.SetInteger("contexts", contexts_value); |
| 236 | value.Set("document_url_patterns", document_url_patterns); |
| 237 | value.Set("target_url_patterns", target_url_patterns); |
| 238 | |
| 239 | std::string error; |
| 240 | scoped_ptr<MenuItem> item(MenuItem::Populate(extension->id(), value, &error)); |
| 241 | ASSERT_TRUE(item.get()); |
| 242 | |
| 243 | EXPECT_EQ(extension->id(), item->extension_id()); |
| 244 | EXPECT_EQ(incognito, item->incognito()); |
| 245 | EXPECT_EQ(title, item->title()); |
| 246 | EXPECT_EQ(checked, item->checked()); |
| 247 | EXPECT_EQ(item->checked(), item->checked()); |
| 248 | EXPECT_EQ(enabled, item->enabled()); |
| 249 | EXPECT_EQ(contexts, item->contexts()); |
| 250 | |
| 251 | URLPatternSet document_url_pattern_set; |
| 252 | document_url_pattern_set.Populate(*document_url_patterns, |
| 253 | URLPattern::SCHEME_ALL, |
| 254 | true, |
| 255 | &error); |
| 256 | EXPECT_EQ(document_url_pattern_set, item->document_url_patterns()); |
| 257 | |
| 258 | URLPatternSet target_url_pattern_set; |
| 259 | target_url_pattern_set.Populate(*target_url_patterns, |
| 260 | URLPattern::SCHEME_ALL, |
| 261 | true, |
| 262 | &error); |
| 263 | EXPECT_EQ(target_url_pattern_set, item->target_url_patterns()); |
| 264 | } |
| 265 | |
[email protected] | 2b07c93f | 2010-08-02 23:13:04 | [diff] [blame] | 266 | // Tests that deleting a parent properly removes descendants. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 267 | TEST_F(MenuManagerTest, DeleteParent) { |
[email protected] | 2b07c93f | 2010-08-02 23:13:04 | [diff] [blame] | 268 | Extension* extension = AddExtension("1111"); |
| 269 | |
| 270 | // Set up 5 items to add. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 271 | MenuItem* item1 = CreateTestItem(extension); |
| 272 | MenuItem* item2 = CreateTestItem(extension); |
| 273 | MenuItem* item3 = CreateTestItemWithID(extension, "id3"); |
| 274 | MenuItem* item4 = CreateTestItemWithID(extension, "id4"); |
| 275 | MenuItem* item5 = CreateTestItem(extension); |
| 276 | MenuItem* item6 = CreateTestItem(extension); |
| 277 | MenuItem::Id item1_id = item1->id(); |
| 278 | MenuItem::Id item2_id = item2->id(); |
| 279 | MenuItem::Id item3_id = item3->id(); |
| 280 | MenuItem::Id item4_id = item4->id(); |
| 281 | MenuItem::Id item5_id = item5->id(); |
| 282 | MenuItem::Id item6_id = item6->id(); |
[email protected] | 2b07c93f | 2010-08-02 23:13:04 | [diff] [blame] | 283 | |
| 284 | // Add the items in the hierarchy |
| 285 | // item1 -> item2 -> item3 -> item4 -> item5 -> item6. |
| 286 | ASSERT_TRUE(manager_.AddContextItem(extension, item1)); |
| 287 | ASSERT_TRUE(manager_.AddChildItem(item1_id, item2)); |
| 288 | ASSERT_TRUE(manager_.AddChildItem(item2_id, item3)); |
| 289 | ASSERT_TRUE(manager_.AddChildItem(item3_id, item4)); |
| 290 | ASSERT_TRUE(manager_.AddChildItem(item4_id, item5)); |
| 291 | ASSERT_TRUE(manager_.AddChildItem(item5_id, item6)); |
| 292 | ASSERT_EQ(item1, manager_.GetItemById(item1_id)); |
| 293 | ASSERT_EQ(item2, manager_.GetItemById(item2_id)); |
| 294 | ASSERT_EQ(item3, manager_.GetItemById(item3_id)); |
| 295 | ASSERT_EQ(item4, manager_.GetItemById(item4_id)); |
| 296 | ASSERT_EQ(item5, manager_.GetItemById(item5_id)); |
| 297 | ASSERT_EQ(item6, manager_.GetItemById(item6_id)); |
| 298 | ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size()); |
| 299 | ASSERT_EQ(6u, manager_.items_by_id_.size()); |
| 300 | |
| 301 | // Remove item6 (a leaf node). |
| 302 | ASSERT_TRUE(manager_.RemoveContextMenuItem(item6_id)); |
| 303 | ASSERT_EQ(item1, manager_.GetItemById(item1_id)); |
| 304 | ASSERT_EQ(item2, manager_.GetItemById(item2_id)); |
| 305 | ASSERT_EQ(item3, manager_.GetItemById(item3_id)); |
| 306 | ASSERT_EQ(item4, manager_.GetItemById(item4_id)); |
| 307 | ASSERT_EQ(item5, manager_.GetItemById(item5_id)); |
| 308 | ASSERT_EQ(NULL, manager_.GetItemById(item6_id)); |
| 309 | ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size()); |
| 310 | ASSERT_EQ(5u, manager_.items_by_id_.size()); |
| 311 | |
| 312 | // Remove item4 and make sure item5 is gone as well. |
| 313 | ASSERT_TRUE(manager_.RemoveContextMenuItem(item4_id)); |
| 314 | ASSERT_EQ(item1, manager_.GetItemById(item1_id)); |
| 315 | ASSERT_EQ(item2, manager_.GetItemById(item2_id)); |
| 316 | ASSERT_EQ(item3, manager_.GetItemById(item3_id)); |
| 317 | ASSERT_EQ(NULL, manager_.GetItemById(item4_id)); |
| 318 | ASSERT_EQ(NULL, manager_.GetItemById(item5_id)); |
| 319 | ASSERT_EQ(1u, manager_.MenuItems(extension->id())->size()); |
| 320 | ASSERT_EQ(3u, manager_.items_by_id_.size()); |
| 321 | |
| 322 | // Now remove item1 and make sure item2 and item3 are gone as well. |
| 323 | ASSERT_TRUE(manager_.RemoveContextMenuItem(item1_id)); |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 324 | ASSERT_EQ(NULL, manager_.MenuItems(extension->id())); |
[email protected] | 2b07c93f | 2010-08-02 23:13:04 | [diff] [blame] | 325 | ASSERT_EQ(0u, manager_.items_by_id_.size()); |
| 326 | ASSERT_EQ(NULL, manager_.GetItemById(item1_id)); |
| 327 | ASSERT_EQ(NULL, manager_.GetItemById(item2_id)); |
| 328 | ASSERT_EQ(NULL, manager_.GetItemById(item3_id)); |
| 329 | } |
| 330 | |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 331 | // Tests changing parents. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 332 | TEST_F(MenuManagerTest, ChangeParent) { |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 333 | Extension* extension1 = AddExtension("1111"); |
[email protected] | 06a0c94e | 2010-06-24 23:20:15 | [diff] [blame] | 334 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 335 | // First create two items and add them both to the manager. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 336 | MenuItem* item1 = CreateTestItem(extension1); |
| 337 | MenuItem* item2 = CreateTestItem(extension1); |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 338 | |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 339 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
| 340 | ASSERT_TRUE(manager_.AddContextItem(extension1, item2)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 341 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 342 | const MenuItem::List* items = manager_.MenuItems(item1->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 343 | ASSERT_EQ(2u, items->size()); |
| 344 | ASSERT_EQ(item1, items->at(0)); |
| 345 | ASSERT_EQ(item2, items->at(1)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 346 | |
| 347 | // Now create a third item, initially add it as a child of item1, then move |
| 348 | // it to be a child of item2. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 349 | MenuItem* item3 = CreateTestItem(extension1); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 350 | |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 351 | ASSERT_TRUE(manager_.AddChildItem(item1->id(), item3)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 352 | ASSERT_EQ(1, item1->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 353 | ASSERT_EQ(item3, item1->children()[0]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 354 | |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 355 | ASSERT_TRUE(manager_.ChangeParent(item3->id(), &item2->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 356 | ASSERT_EQ(0, item1->child_count()); |
| 357 | ASSERT_EQ(1, item2->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 358 | ASSERT_EQ(item3, item2->children()[0]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 359 | |
| 360 | // Move item2 to be a child of item1. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 361 | ASSERT_TRUE(manager_.ChangeParent(item2->id(), &item1->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 362 | ASSERT_EQ(1, item1->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 363 | ASSERT_EQ(item2, item1->children()[0]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 364 | ASSERT_EQ(1, item2->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 365 | ASSERT_EQ(item3, item2->children()[0]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 366 | |
| 367 | // Since item2 was a top-level item but is no longer, we should only have 1 |
| 368 | // top-level item. |
| 369 | items = manager_.MenuItems(item1->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 370 | ASSERT_EQ(1u, items->size()); |
| 371 | ASSERT_EQ(item1, items->at(0)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 372 | |
| 373 | // Move item3 back to being a child of item1, so it's now a sibling of item2. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 374 | ASSERT_TRUE(manager_.ChangeParent(item3->id(), &item1->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 375 | ASSERT_EQ(2, item1->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 376 | ASSERT_EQ(item2, item1->children()[0]); |
| 377 | ASSERT_EQ(item3, item1->children()[1]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 378 | |
| 379 | // Try switching item3 to be the parent of item1 - this should fail. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 380 | ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item3->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 381 | ASSERT_EQ(0, item3->child_count()); |
| 382 | ASSERT_EQ(2, item1->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 383 | ASSERT_EQ(item2, item1->children()[0]); |
| 384 | ASSERT_EQ(item3, item1->children()[1]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 385 | items = manager_.MenuItems(item1->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 386 | ASSERT_EQ(1u, items->size()); |
| 387 | ASSERT_EQ(item1, items->at(0)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 388 | |
| 389 | // Move item2 to be a top-level item. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 390 | ASSERT_TRUE(manager_.ChangeParent(item2->id(), NULL)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 391 | items = manager_.MenuItems(item1->extension_id()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 392 | ASSERT_EQ(2u, items->size()); |
| 393 | ASSERT_EQ(item1, items->at(0)); |
| 394 | ASSERT_EQ(item2, items->at(1)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 395 | ASSERT_EQ(1, item1->child_count()); |
[email protected] | 63a414b5 | 2010-06-03 23:20:49 | [diff] [blame] | 396 | ASSERT_EQ(item3, item1->children()[0]); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 397 | |
| 398 | // Make sure you can't move a node to be a child of another extension's item. |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 399 | Extension* extension2 = AddExtension("2222"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 400 | MenuItem* item4 = CreateTestItem(extension2); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 401 | ASSERT_TRUE(manager_.AddContextItem(extension2, item4)); |
| 402 | ASSERT_FALSE(manager_.ChangeParent(item4->id(), &item1->id())); |
| 403 | ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item4->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 404 | |
| 405 | // Make sure you can't make an item be it's own parent. |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 406 | ASSERT_FALSE(manager_.ChangeParent(item1->id(), &item1->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 407 | } |
| 408 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 409 | // Tests that we properly remove an extension's menu item when that extension is |
| 410 | // unloaded. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 411 | TEST_F(MenuManagerTest, ExtensionUnloadRemovesMenuItems) { |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 412 | content::NotificationService* notifier = |
| 413 | content::NotificationService::current(); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 414 | ASSERT_TRUE(notifier != NULL); |
| 415 | |
| 416 | // Create a test extension. |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 417 | Extension* extension1 = AddExtension("1111"); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 418 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 419 | // Create an MenuItem and put it into the manager. |
| 420 | MenuItem* item1 = CreateTestItem(extension1); |
| 421 | MenuItem::Id id1 = item1->id(); |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 422 | ASSERT_EQ(extension1->id(), item1->extension_id()); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 423 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 424 | ASSERT_EQ(1u, manager_.MenuItems(extension1->id())->size()); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 425 | |
| 426 | // Create a menu item with a different extension id and add it to the manager. |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 427 | Extension* extension2 = AddExtension("2222"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 428 | MenuItem* item2 = CreateTestItem(extension2); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 429 | ASSERT_NE(item1->extension_id(), item2->extension_id()); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 430 | ASSERT_TRUE(manager_.AddContextItem(extension2, item2)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 431 | |
| 432 | // Notify that the extension was unloaded, and make sure the right item is |
| 433 | // gone. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 434 | UnloadedExtensionInfo details( |
[email protected] | 814a7bf0f | 2011-08-13 05:30:59 | [diff] [blame] | 435 | extension1, extension_misc::UNLOAD_REASON_DISABLE); |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 436 | notifier->Notify(chrome::NOTIFICATION_EXTENSION_UNLOADED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 437 | content::Source<Profile>(&profile_), |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 438 | content::Details<UnloadedExtensionInfo>( |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 439 | &details)); |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 440 | ASSERT_EQ(NULL, manager_.MenuItems(extension1->id())); |
| 441 | ASSERT_EQ(1u, manager_.MenuItems(extension2->id())->size()); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 442 | ASSERT_TRUE(manager_.GetItemById(id1) == NULL); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 443 | ASSERT_TRUE(manager_.GetItemById(item2->id()) != NULL); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 444 | } |
| 445 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 446 | // A mock message service for tests of MenuManager::ExecuteCommand. |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 447 | class MockEventRouter : public EventRouter { |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 448 | public: |
[email protected] | 79cb81bb | 2012-09-20 02:23:31 | [diff] [blame] | 449 | explicit MockEventRouter(Profile* profile) : EventRouter(profile, NULL) {} |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 450 | |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 451 | MOCK_METHOD6(DispatchEventToExtensionMock, |
[email protected] | b085856f | 2012-03-02 04:37:25 | [diff] [blame] | 452 | void(const std::string& extension_id, |
| 453 | const std::string& event_name, |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 454 | base::ListValue* event_args, |
[email protected] | b085856f | 2012-03-02 04:37:25 | [diff] [blame] | 455 | Profile* source_profile, |
| 456 | const GURL& event_url, |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 457 | EventRouter::UserGestureState state)); |
[email protected] | f72d0c6 | 2011-08-31 16:27:44 | [diff] [blame] | 458 | |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 459 | virtual void DispatchEventToExtension(const std::string& extension_id, |
[email protected] | 01f7a804 | 2012-12-07 07:48:02 | [diff] [blame] | 460 | scoped_ptr<Event> event) { |
| 461 | DispatchEventToExtensionMock(extension_id, |
| 462 | event->event_name, |
| 463 | event->event_args.release(), |
| 464 | event->restrict_to_profile, |
| 465 | event->event_url, |
| 466 | event->user_gesture); |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 467 | } |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 468 | |
| 469 | private: |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 470 | DISALLOW_COPY_AND_ASSIGN(MockEventRouter); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 471 | }; |
| 472 | |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 473 | // A mock ExtensionSystem to serve our MockEventRouter. |
| 474 | class MockExtensionSystem : public TestExtensionSystem { |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 475 | public: |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 476 | explicit MockExtensionSystem(Profile* profile) |
| 477 | : TestExtensionSystem(profile) {} |
| 478 | |
| 479 | virtual EventRouter* event_router() { |
| 480 | if (!mock_event_router_.get()) |
| 481 | mock_event_router_.reset(new MockEventRouter(profile_)); |
| 482 | return mock_event_router_.get(); |
| 483 | } |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 484 | |
| 485 | private: |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 486 | scoped_ptr<MockEventRouter> mock_event_router_; |
| 487 | |
| 488 | DISALLOW_COPY_AND_ASSIGN(MockExtensionSystem); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 489 | }; |
| 490 | |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 491 | ProfileKeyedService* BuildMockExtensionSystem(Profile* profile) { |
| 492 | return new MockExtensionSystem(profile); |
| 493 | } |
| 494 | |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 495 | // Tests the RemoveAll functionality. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 496 | TEST_F(MenuManagerTest, RemoveAll) { |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 497 | // Try removing all items for an extension id that doesn't have any items. |
| 498 | manager_.RemoveAllContextItems("CCCC"); |
| 499 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 500 | // Add 2 top-level and one child item for extension 1. |
| 501 | Extension* extension1 = AddExtension("1111"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 502 | MenuItem* item1 = CreateTestItem(extension1); |
| 503 | MenuItem* item2 = CreateTestItem(extension1); |
| 504 | MenuItem* item3 = CreateTestItem(extension1); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 505 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
| 506 | ASSERT_TRUE(manager_.AddContextItem(extension1, item2)); |
| 507 | ASSERT_TRUE(manager_.AddChildItem(item1->id(), item3)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 508 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 509 | // Add one top-level item for extension 2. |
| 510 | Extension* extension2 = AddExtension("2222"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 511 | MenuItem* item4 = CreateTestItem(extension2); |
[email protected] | f4f0459 | 2010-07-14 20:40:13 | [diff] [blame] | 512 | ASSERT_TRUE(manager_.AddContextItem(extension2, item4)); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 513 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 514 | EXPECT_EQ(2u, manager_.MenuItems(extension1->id())->size()); |
| 515 | EXPECT_EQ(1u, manager_.MenuItems(extension2->id())->size()); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 516 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 517 | // Remove extension2's item. |
| 518 | manager_.RemoveAllContextItems(extension2->id()); |
| 519 | EXPECT_EQ(2u, manager_.MenuItems(extension1->id())->size()); |
| 520 | EXPECT_EQ(NULL, manager_.MenuItems(extension2->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 521 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 522 | // Remove extension1's items. |
| 523 | manager_.RemoveAllContextItems(extension1->id()); |
| 524 | EXPECT_EQ(NULL, manager_.MenuItems(extension1->id())); |
[email protected] | 66dbfb2c | 2010-05-12 20:20:15 | [diff] [blame] | 525 | } |
| 526 | |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 527 | // Tests that removing all items one-by-one doesn't leave an entry around. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 528 | TEST_F(MenuManagerTest, RemoveOneByOne) { |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 529 | // Add 2 test items. |
| 530 | Extension* extension1 = AddExtension("1111"); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 531 | MenuItem* item1 = CreateTestItem(extension1); |
| 532 | MenuItem* item2 = CreateTestItem(extension1); |
| 533 | MenuItem* item3 = CreateTestItemWithID(extension1, "id3"); |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 534 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
| 535 | ASSERT_TRUE(manager_.AddContextItem(extension1, item2)); |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 536 | ASSERT_TRUE(manager_.AddContextItem(extension1, item3)); |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 537 | |
| 538 | ASSERT_FALSE(manager_.context_items_.empty()); |
| 539 | |
[email protected] | 619c5dba | 2012-05-16 00:44:48 | [diff] [blame] | 540 | manager_.RemoveContextMenuItem(item3->id()); |
[email protected] | f50da859 | 2010-10-28 23:39:32 | [diff] [blame] | 541 | manager_.RemoveContextMenuItem(item1->id()); |
| 542 | manager_.RemoveContextMenuItem(item2->id()); |
| 543 | |
| 544 | ASSERT_TRUE(manager_.context_items_.empty()); |
| 545 | } |
| 546 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 547 | TEST_F(MenuManagerTest, ExecuteCommand) { |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 548 | TestingProfile profile; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 549 | |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 550 | MockExtensionSystem* mock_extension_system = |
| 551 | static_cast<MockExtensionSystem*>(ExtensionSystemFactory::GetInstance()-> |
| 552 | SetTestingFactoryAndUse(&profile, &BuildMockExtensionSystem)); |
| 553 | MockEventRouter* mock_event_router = |
| 554 | static_cast<MockEventRouter*>(mock_extension_system->event_router()); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 555 | |
[email protected] | 35be7ec | 2012-02-12 20:42:51 | [diff] [blame] | 556 | content::ContextMenuParams params; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 557 | params.media_type = WebKit::WebContextMenuData::MediaTypeImage; |
| 558 | params.src_url = GURL("http://foo.bar/image.png"); |
| 559 | params.page_url = GURL("http://foo.bar"); |
[email protected] | 944b421 | 2010-12-14 00:00:33 | [diff] [blame] | 560 | params.selection_text = ASCIIToUTF16("Hello World"); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 561 | params.is_editable = false; |
| 562 | |
[email protected] | 052c9270 | 2010-06-25 07:25:52 | [diff] [blame] | 563 | Extension* extension = AddExtension("test"); |
[email protected] | 504bf9c | 2012-12-13 01:51:20 | [diff] [blame^] | 564 | MenuItem* parent = CreateTestItem(extension); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 565 | MenuItem* item = CreateTestItem(extension); |
[email protected] | 504bf9c | 2012-12-13 01:51:20 | [diff] [blame^] | 566 | MenuItem::Id parent_id = parent->id(); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 567 | MenuItem::Id id = item->id(); |
[email protected] | 504bf9c | 2012-12-13 01:51:20 | [diff] [blame^] | 568 | ASSERT_TRUE(manager_.AddContextItem(extension, parent)); |
| 569 | ASSERT_TRUE(manager_.AddChildItem(parent->id(), item)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 570 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 571 | // Use the magic of googlemock to save a parameter to our mock's |
[email protected] | 0a184b5 | 2011-06-23 00:41:13 | [diff] [blame] | 572 | // DispatchEventToExtension method into event_args. |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 573 | base::ListValue* list = NULL; |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 574 | { |
| 575 | InSequence s; |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 576 | EXPECT_CALL(*mock_event_router, |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 577 | DispatchEventToExtensionMock( |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 578 | item->extension_id(), |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 579 | extensions::event_names::kOnContextMenus, |
| 580 | _, |
| 581 | &profile, |
| 582 | GURL(), |
| 583 | EventRouter::USER_GESTURE_ENABLED)) |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 584 | .Times(1) |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 585 | .WillOnce(SaveArg<2>(&list)); |
[email protected] | 9e5be1f9 | 2012-10-29 19:01:45 | [diff] [blame] | 586 | EXPECT_CALL(*mock_event_router, |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 587 | DispatchEventToExtensionMock( |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 588 | item->extension_id(), |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 589 | extensions::event_names::kOnContextMenuClicked, |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 590 | _, |
| 591 | &profile, |
| 592 | GURL(), |
[email protected] | 5a38dfd | 2012-07-23 23:22:10 | [diff] [blame] | 593 | EventRouter::USER_GESTURE_ENABLED)) |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 594 | .Times(1) |
| 595 | .WillOnce(DeleteArg<2>()); |
[email protected] | bc4ae15 | 2012-06-01 22:23:34 | [diff] [blame] | 596 | } |
[email protected] | 9531f74 | 2012-12-11 22:02:40 | [diff] [blame] | 597 | manager_.ExecuteCommand(&profile, NULL /* web_contents */, params, id); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 598 | |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 599 | ASSERT_EQ(2u, list->GetSize()); |
| 600 | |
| 601 | DictionaryValue* info; |
| 602 | ASSERT_TRUE(list->GetDictionary(0, &info)); |
| 603 | |
| 604 | int tmp_id = 0; |
[email protected] | 88dc069 | 2010-08-14 16:29:42 | [diff] [blame] | 605 | ASSERT_TRUE(info->GetInteger("menuItemId", &tmp_id)); |
[email protected] | 5a7b5eaf | 2010-11-02 20:52:19 | [diff] [blame] | 606 | ASSERT_EQ(id.uid, tmp_id); |
[email protected] | 504bf9c | 2012-12-13 01:51:20 | [diff] [blame^] | 607 | ASSERT_TRUE(info->GetInteger("parentMenuItemId", &tmp_id)); |
| 608 | ASSERT_EQ(parent_id.uid, tmp_id); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 609 | |
| 610 | std::string tmp; |
[email protected] | 88dc069 | 2010-08-14 16:29:42 | [diff] [blame] | 611 | ASSERT_TRUE(info->GetString("mediaType", &tmp)); |
[email protected] | 1741b97 | 2010-08-04 23:47:41 | [diff] [blame] | 612 | ASSERT_EQ("image", tmp); |
[email protected] | 88dc069 | 2010-08-14 16:29:42 | [diff] [blame] | 613 | ASSERT_TRUE(info->GetString("srcUrl", &tmp)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 614 | ASSERT_EQ(params.src_url.spec(), tmp); |
[email protected] | 88dc069 | 2010-08-14 16:29:42 | [diff] [blame] | 615 | ASSERT_TRUE(info->GetString("pageUrl", &tmp)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 616 | ASSERT_EQ(params.page_url.spec(), tmp); |
| 617 | |
[email protected] | 944b421 | 2010-12-14 00:00:33 | [diff] [blame] | 618 | string16 tmp16; |
| 619 | ASSERT_TRUE(info->GetString("selectionText", &tmp16)); |
| 620 | ASSERT_EQ(params.selection_text, tmp16); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 621 | |
| 622 | bool bool_tmp = true; |
[email protected] | 88dc069 | 2010-08-14 16:29:42 | [diff] [blame] | 623 | ASSERT_TRUE(info->GetBoolean("editable", &bool_tmp)); |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 624 | ASSERT_EQ(params.is_editable, bool_tmp); |
[email protected] | c9bd90f | 2012-08-07 23:58:15 | [diff] [blame] | 625 | |
| 626 | delete list; |
[email protected] | 2e3b520 | 2010-03-23 06:52:41 | [diff] [blame] | 627 | } |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 628 | |
| 629 | // Test that there is always only one radio item selected. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 630 | TEST_F(MenuManagerTest, SanitizeRadioButtons) { |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 631 | Extension* extension = AddExtension("test"); |
| 632 | |
| 633 | // A single unchecked item should get checked |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 634 | MenuItem* item1 = CreateTestItem(extension); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 635 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 636 | item1->set_type(MenuItem::RADIO); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 637 | item1->SetChecked(false); |
| 638 | ASSERT_FALSE(item1->checked()); |
| 639 | manager_.AddContextItem(extension, item1); |
| 640 | ASSERT_TRUE(item1->checked()); |
| 641 | |
| 642 | // In a run of two unchecked items, the first should get selected. |
| 643 | item1->SetChecked(false); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 644 | MenuItem* item2 = CreateTestItem(extension); |
| 645 | item2->set_type(MenuItem::RADIO); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 646 | item2->SetChecked(false); |
| 647 | ASSERT_FALSE(item1->checked()); |
| 648 | ASSERT_FALSE(item2->checked()); |
| 649 | manager_.AddContextItem(extension, item2); |
| 650 | ASSERT_TRUE(item1->checked()); |
| 651 | ASSERT_FALSE(item2->checked()); |
| 652 | |
| 653 | // If multiple items are checked, only the last item should get checked. |
| 654 | item1->SetChecked(true); |
| 655 | item2->SetChecked(true); |
| 656 | ASSERT_TRUE(item1->checked()); |
| 657 | ASSERT_TRUE(item2->checked()); |
| 658 | manager_.ItemUpdated(item1->id()); |
| 659 | ASSERT_FALSE(item1->checked()); |
| 660 | ASSERT_TRUE(item2->checked()); |
| 661 | |
| 662 | // If the checked item is removed, the new first item should get checked. |
| 663 | item1->SetChecked(false); |
| 664 | item2->SetChecked(true); |
| 665 | ASSERT_FALSE(item1->checked()); |
| 666 | ASSERT_TRUE(item2->checked()); |
| 667 | manager_.RemoveContextMenuItem(item2->id()); |
| 668 | item2 = NULL; |
| 669 | ASSERT_TRUE(item1->checked()); |
| 670 | |
| 671 | // If a checked item is added to a run that already has a checked item, |
| 672 | // then the new item should get checked. |
| 673 | item1->SetChecked(true); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 674 | MenuItem* new_item = CreateTestItem(extension); |
| 675 | new_item->set_type(MenuItem::RADIO); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 676 | new_item->SetChecked(true); |
| 677 | ASSERT_TRUE(item1->checked()); |
| 678 | ASSERT_TRUE(new_item->checked()); |
| 679 | manager_.AddContextItem(extension, new_item); |
| 680 | ASSERT_FALSE(item1->checked()); |
| 681 | ASSERT_TRUE(new_item->checked()); |
| 682 | // Make sure that children are checked as well. |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 683 | MenuItem* parent = CreateTestItem(extension); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 684 | manager_.AddContextItem(extension, parent); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 685 | MenuItem* child1 = CreateTestItem(extension); |
| 686 | child1->set_type(MenuItem::RADIO); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 687 | child1->SetChecked(false); |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 688 | MenuItem* child2 = CreateTestItem(extension); |
| 689 | child2->set_type(MenuItem::RADIO); |
[email protected] | 7dddebc3 | 2012-01-11 22:01:03 | [diff] [blame] | 690 | child2->SetChecked(true); |
| 691 | ASSERT_FALSE(child1->checked()); |
| 692 | ASSERT_TRUE(child2->checked()); |
| 693 | |
| 694 | manager_.AddChildItem(parent->id(), child1); |
| 695 | ASSERT_TRUE(child1->checked()); |
| 696 | |
| 697 | manager_.AddChildItem(parent->id(), child2); |
| 698 | ASSERT_FALSE(child1->checked()); |
| 699 | ASSERT_TRUE(child2->checked()); |
| 700 | |
| 701 | // Removing the checked item from the children should cause the |
| 702 | // remaining child to be checked. |
| 703 | manager_.RemoveContextMenuItem(child2->id()); |
| 704 | child2 = NULL; |
| 705 | ASSERT_TRUE(child1->checked()); |
| 706 | |
| 707 | // This should NOT cause |new_item| to be deseleted because |
| 708 | // |parent| will be seperating the two runs of radio items. |
| 709 | manager_.ChangeParent(child1->id(), NULL); |
| 710 | ASSERT_TRUE(new_item->checked()); |
| 711 | ASSERT_TRUE(child1->checked()); |
| 712 | |
| 713 | // Removing |parent| should cause only |child1| to be selected. |
| 714 | manager_.RemoveContextMenuItem(parent->id()); |
| 715 | parent = NULL; |
| 716 | ASSERT_FALSE(new_item->checked()); |
| 717 | ASSERT_TRUE(child1->checked()); |
| 718 | } |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 719 | |
[email protected] | 6350346 | 2012-10-30 22:14:31 | [diff] [blame] | 720 | // Tests the RemoveAllIncognitoContextItems functionality. |
| 721 | TEST_F(MenuManagerTest, RemoveAllIncognito) { |
| 722 | Extension* extension1 = AddExtension("1111"); |
| 723 | // Add 2 top-level and one child item for extension 1 |
| 724 | // with incognito 'true'. |
| 725 | MenuItem* item1 = CreateTestItem(extension1, true); |
| 726 | MenuItem* item2 = CreateTestItem(extension1, true); |
| 727 | MenuItem* item3 = CreateTestItem(extension1, true); |
| 728 | ASSERT_TRUE(manager_.AddContextItem(extension1, item1)); |
| 729 | ASSERT_TRUE(manager_.AddContextItem(extension1, item2)); |
| 730 | ASSERT_TRUE(manager_.AddChildItem(item1->id(), item3)); |
| 731 | |
| 732 | // Add 2 top-level and one child item for extension 1 |
| 733 | // with incognito 'false'. |
| 734 | MenuItem* item4 = CreateTestItem(extension1); |
| 735 | MenuItem* item5 = CreateTestItem(extension1); |
| 736 | MenuItem* item6 = CreateTestItem(extension1); |
| 737 | ASSERT_TRUE(manager_.AddContextItem(extension1, item4)); |
| 738 | ASSERT_TRUE(manager_.AddContextItem(extension1, item5)); |
| 739 | ASSERT_TRUE(manager_.AddChildItem(item4->id(), item6)); |
| 740 | |
| 741 | // Add one top-level item for extension 2. |
| 742 | Extension* extension2 = AddExtension("2222"); |
| 743 | MenuItem* item7 = CreateTestItem(extension2); |
| 744 | ASSERT_TRUE(manager_.AddContextItem(extension2, item7)); |
| 745 | |
| 746 | EXPECT_EQ(4u, manager_.MenuItems(extension1->id())->size()); |
| 747 | EXPECT_EQ(1u, manager_.MenuItems(extension2->id())->size()); |
| 748 | |
| 749 | // Remove all context menu items with incognito true. |
| 750 | manager_.RemoveAllIncognitoContextItems(); |
| 751 | EXPECT_EQ(2u, manager_.MenuItems(extension1->id())->size()); |
| 752 | EXPECT_EQ(1u, manager_.MenuItems(extension2->id())->size()); |
| 753 | } |
| 754 | |
[email protected] | 5aeeae1 | 2012-07-05 19:13:11 | [diff] [blame] | 755 | } // namespace extensions |