OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/extensions/extension_action_manager.h" |
| 6 |
| 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "chrome/browser/extensions/extension_action.h" |
| 9 #include "chrome/test/base/testing_profile.h" |
| 10 #include "extensions/browser/extension_registry.h" |
| 11 #include "extensions/common/extension_builder.h" |
| 12 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 13 #include "extensions/common/value_builder.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 |
| 16 namespace extensions { |
| 17 |
| 18 namespace { |
| 19 |
| 20 const char kBrowserAction[] = "browser_action"; |
| 21 const char kPageAction[] = "page_action"; |
| 22 |
| 23 } // namespace |
| 24 |
| 25 class ExtensionActionManagerTest : public testing::Test { |
| 26 public: |
| 27 ExtensionActionManagerTest(); |
| 28 |
| 29 protected: |
| 30 // Build an extension, populating |action_type| key with |action|, and |
| 31 // "icons" key with |extension_icons|. |
| 32 scoped_refptr<Extension> BuildExtension(DictionaryBuilder& extension_icons, |
| 33 DictionaryBuilder& action, |
| 34 const char* action_type); |
| 35 |
| 36 // Returns true if |action|'s title matches |extension|'s name. |
| 37 bool TitlesMatch(const Extension& extension, const ExtensionAction& action); |
| 38 |
| 39 // Returns true if |action|'s icon for size |action_key| matches |
| 40 // |extension|'s icon for size |extension_key|; |
| 41 bool IconsMatch(const Extension& extension, |
| 42 int extension_key, |
| 43 const ExtensionAction& action, |
| 44 int action_key); |
| 45 |
| 46 // Returns the appropriate action for |extension| according to |action_type|. |
| 47 ExtensionAction* GetAction(const char* action_type, |
| 48 const Extension& extension); |
| 49 |
| 50 // Tests that values that are missing from the |action_type| key are properly |
| 51 // populated with values from the other keys in the manifest (e.g. |
| 52 // "default_icon" key of |action_type| is populated with "icons" key). |
| 53 void TestPopulateMissingValues(const char* action_type); |
| 54 |
| 55 ExtensionActionManager* manager() { return manager_; } |
| 56 |
| 57 private: |
| 58 ExtensionRegistry* registry_; |
| 59 int curr_id_; |
| 60 ExtensionActionManager* manager_; |
| 61 scoped_ptr<TestingProfile> profile_; |
| 62 }; |
| 63 |
| 64 ExtensionActionManagerTest::ExtensionActionManagerTest() |
| 65 : curr_id_(0), |
| 66 profile_(new TestingProfile) { |
| 67 registry_ = ExtensionRegistry::Get(profile_.get()); |
| 68 manager_ = ExtensionActionManager::Get(profile_.get()); |
| 69 } |
| 70 |
| 71 scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension( |
| 72 DictionaryBuilder& extension_icons, |
| 73 DictionaryBuilder& action, |
| 74 const char* action_type) { |
| 75 std::string id = base::IntToString(curr_id_++); |
| 76 scoped_refptr<Extension> extension = ExtensionBuilder() |
| 77 .SetManifest(DictionaryBuilder().Set("version", "1") |
| 78 .Set("manifest_version", 2) |
| 79 .Set("icons", extension_icons) |
| 80 .Set(action_type, action) |
| 81 .Set("name", |
| 82 std::string("Test Extension").append(id))) |
| 83 .SetID(id) |
| 84 .Build(); |
| 85 registry_->AddEnabled(extension); |
| 86 return extension; |
| 87 } |
| 88 |
| 89 bool ExtensionActionManagerTest::TitlesMatch(const Extension& extension, |
| 90 const ExtensionAction& action) { |
| 91 return action.GetTitle(ExtensionAction::kDefaultTabId) == extension.name(); |
| 92 } |
| 93 |
| 94 bool ExtensionActionManagerTest::IconsMatch(const Extension& extension, |
| 95 int extension_key, |
| 96 const ExtensionAction& action, |
| 97 int action_key) { |
| 98 return action.default_icon()->Get(action_key, |
| 99 ExtensionIconSet::MATCH_EXACTLY) == |
| 100 IconsInfo::GetIcons(&extension).Get(extension_key, |
| 101 ExtensionIconSet::MATCH_EXACTLY); |
| 102 } |
| 103 |
| 104 ExtensionAction* ExtensionActionManagerTest::GetAction( |
| 105 const char* action_type, |
| 106 const Extension& extension) { |
| 107 return (action_type == kBrowserAction) ? |
| 108 manager_->GetBrowserAction(extension) : |
| 109 manager_->GetPageAction(extension); |
| 110 } |
| 111 |
| 112 void ExtensionActionManagerTest::TestPopulateMissingValues( |
| 113 const char* action_type) { |
| 114 // Test that the largest icon from the extension's "icons" key is chosen as a |
| 115 // replacement for missing action default_icons keys. "19" should not be |
| 116 // replaced because "38" can always be used in its place. |
| 117 scoped_refptr<Extension> extension = BuildExtension( |
| 118 DictionaryBuilder().Set("48", "icon48.png") |
| 119 .Set("128", "icon128.png"), |
| 120 DictionaryBuilder().Pass(), |
| 121 action_type); |
| 122 |
| 123 ASSERT_TRUE(extension.get()); |
| 124 const ExtensionAction* action = GetAction(action_type, *extension); |
| 125 ASSERT_TRUE(action); |
| 126 |
| 127 ASSERT_TRUE(TitlesMatch(*extension, *action)); |
| 128 ASSERT_TRUE(IconsMatch(*extension, 128, *action, 38)); |
| 129 |
| 130 // Test that the action's missing default_icons are not replaced with smaller |
| 131 // icons. |
| 132 extension = BuildExtension( |
| 133 DictionaryBuilder().Set("24", "icon24.png"), |
| 134 DictionaryBuilder().Pass(), |
| 135 action_type); |
| 136 |
| 137 ASSERT_TRUE(extension.get()); |
| 138 action = GetAction(action_type, *extension); |
| 139 ASSERT_TRUE(action); |
| 140 |
| 141 ASSERT_TRUE(IconsMatch(*extension, 24, *action, 19)); |
| 142 ASSERT_FALSE(IconsMatch(*extension, 24, *action, 38)); |
| 143 |
| 144 // Test that an action's 19px icon is not replaced if a 38px action icon |
| 145 // exists. |
| 146 extension = BuildExtension( |
| 147 DictionaryBuilder().Set("128", "icon128.png"), |
| 148 DictionaryBuilder().Set("default_icon", DictionaryBuilder() |
| 149 .Set("38", "action38.png")), |
| 150 action_type); |
| 151 |
| 152 ASSERT_TRUE(extension.get()); |
| 153 action = GetAction(action_type, *extension); |
| 154 ASSERT_TRUE(action); |
| 155 |
| 156 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); |
| 157 |
| 158 // Test that existing default_icons and default_title are not replaced. |
| 159 extension = BuildExtension( |
| 160 DictionaryBuilder().Set("128", "icon128.png"), |
| 161 DictionaryBuilder().Set("default_title", "Action!") |
| 162 .Set("default_icon", DictionaryBuilder() |
| 163 .Set("19", "action19.png") |
| 164 .Set("38", "action38.png")), |
| 165 action_type); |
| 166 |
| 167 ASSERT_TRUE(extension.get()); |
| 168 action = GetAction(action_type, *extension); |
| 169 ASSERT_TRUE(action); |
| 170 |
| 171 ASSERT_FALSE(TitlesMatch(*extension, *action)); |
| 172 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); |
| 173 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 38)); |
| 174 } |
| 175 |
| 176 namespace { |
| 177 |
| 178 TEST_F(ExtensionActionManagerTest, PopulateBrowserAction) { |
| 179 TestPopulateMissingValues(kBrowserAction); |
| 180 } |
| 181 |
| 182 TEST_F(ExtensionActionManagerTest, PopulatePageAction) { |
| 183 TestPopulateMissingValues(kPageAction); |
| 184 } |
| 185 |
| 186 TEST_F(ExtensionActionManagerTest, GetBestFitActionTest) { |
| 187 // Create an extension with page action defaults. |
| 188 scoped_refptr<Extension> extension = BuildExtension( |
| 189 DictionaryBuilder().Set("48", "icon48.png"), |
| 190 DictionaryBuilder().Set("default_title", "Action!") |
| 191 .Set("default_icon", DictionaryBuilder() |
| 192 .Set("38", "action38.png")), |
| 193 kPageAction); |
| 194 ASSERT_TRUE(extension.get()); |
| 195 |
| 196 // Get a "best fit" browser action for |extension|. |
| 197 scoped_ptr<ExtensionAction> action = |
| 198 manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); |
| 199 ASSERT_TRUE(action.get()); |
| 200 ASSERT_EQ(action->action_type(), ActionInfo::TYPE_BROWSER); |
| 201 |
| 202 // |action|'s title and default icon should match |extension|'s page action's. |
| 203 ASSERT_EQ(action->GetTitle(ExtensionAction::kDefaultTabId), "Action!"); |
| 204 ASSERT_EQ(action->default_icon()->Get(38, ExtensionIconSet::MATCH_EXACTLY), |
| 205 "action38.png"); |
| 206 |
| 207 // Create a new extension without page action defaults. |
| 208 extension = BuildExtension( |
| 209 DictionaryBuilder().Set("48", "icon48.png"), |
| 210 DictionaryBuilder().Pass(), |
| 211 kPageAction); |
| 212 ASSERT_TRUE(extension.get()); |
| 213 |
| 214 action = manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); |
| 215 |
| 216 // Now these values match because |extension| does not have page action |
| 217 // defaults. |
| 218 ASSERT_TRUE(TitlesMatch(*extension, *action)); |
| 219 ASSERT_TRUE(IconsMatch(*extension, 48, *action, 38)); |
| 220 } |
| 221 |
| 222 } // namespace |
| 223 } // namespace extensions |
OLD | NEW |