Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_action_manager_unittest.cc
blobb29328e05a87d6166145aa67c33a1140452fcc5c
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.
5 #include "chrome/browser/extensions/extension_action_manager.h"
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 "content/public/test/test_browser_thread_bundle.h"
11 #include "extensions/browser/extension_registry.h"
12 #include "extensions/common/extension_builder.h"
13 #include "extensions/common/manifest_handlers/icons_handler.h"
14 #include "extensions/common/value_builder.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace extensions {
19 namespace {
21 const char kBrowserAction[] = "browser_action";
22 const char kPageAction[] = "page_action";
24 } // namespace
26 class ExtensionActionManagerTest : public testing::Test {
27 public:
28 ExtensionActionManagerTest();
30 protected:
31 // Build an extension, populating |action_type| key with |action|, and
32 // "icons" key with |extension_icons|.
33 scoped_refptr<Extension> BuildExtension(DictionaryBuilder& extension_icons,
34 DictionaryBuilder& action,
35 const char* action_type);
37 // Returns true if |action|'s title matches |extension|'s name.
38 bool TitlesMatch(const Extension& extension, const ExtensionAction& action);
40 // Returns true if |action|'s icon for size |action_key| matches
41 // |extension|'s icon for size |extension_key|;
42 bool IconsMatch(const Extension& extension,
43 int extension_key,
44 const ExtensionAction& action,
45 int action_key);
47 // Returns the appropriate action for |extension| according to |action_type|.
48 ExtensionAction* GetAction(const char* action_type,
49 const Extension& extension);
51 // Tests that values that are missing from the |action_type| key are properly
52 // populated with values from the other keys in the manifest (e.g.
53 // "default_icon" key of |action_type| is populated with "icons" key).
54 void TestPopulateMissingValues(const char* action_type);
56 ExtensionActionManager* manager() { return manager_; }
58 private:
59 content::TestBrowserThreadBundle thread_bundle_;
60 ExtensionRegistry* registry_;
61 int curr_id_;
62 ExtensionActionManager* manager_;
63 scoped_ptr<TestingProfile> profile_;
66 ExtensionActionManagerTest::ExtensionActionManagerTest()
67 : curr_id_(0),
68 profile_(new TestingProfile) {
69 registry_ = ExtensionRegistry::Get(profile_.get());
70 manager_ = ExtensionActionManager::Get(profile_.get());
73 scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension(
74 DictionaryBuilder& extension_icons,
75 DictionaryBuilder& action,
76 const char* action_type) {
77 std::string id = base::IntToString(curr_id_++);
78 scoped_refptr<Extension> extension = ExtensionBuilder()
79 .SetManifest(DictionaryBuilder().Set("version", "1")
80 .Set("manifest_version", 2)
81 .Set("icons", extension_icons)
82 .Set(action_type, action)
83 .Set("name",
84 std::string("Test Extension").append(id)))
85 .SetID(id)
86 .Build();
87 registry_->AddEnabled(extension);
88 return extension;
91 bool ExtensionActionManagerTest::TitlesMatch(const Extension& extension,
92 const ExtensionAction& action) {
93 return action.GetTitle(ExtensionAction::kDefaultTabId) == extension.name();
96 bool ExtensionActionManagerTest::IconsMatch(const Extension& extension,
97 int extension_key,
98 const ExtensionAction& action,
99 int action_key) {
100 return action.default_icon()->Get(action_key,
101 ExtensionIconSet::MATCH_EXACTLY) ==
102 IconsInfo::GetIcons(&extension).Get(extension_key,
103 ExtensionIconSet::MATCH_EXACTLY);
106 ExtensionAction* ExtensionActionManagerTest::GetAction(
107 const char* action_type,
108 const Extension& extension) {
109 return (action_type == kBrowserAction) ?
110 manager_->GetBrowserAction(extension) :
111 manager_->GetPageAction(extension);
114 void ExtensionActionManagerTest::TestPopulateMissingValues(
115 const char* action_type) {
116 // Test that the largest icon from the extension's "icons" key is chosen as a
117 // replacement for missing action default_icons keys. "19" should not be
118 // replaced because "38" can always be used in its place.
119 scoped_refptr<Extension> extension = BuildExtension(
120 DictionaryBuilder().Set("48", "icon48.png")
121 .Set("128", "icon128.png"),
122 DictionaryBuilder().Pass(),
123 action_type);
125 ASSERT_TRUE(extension.get());
126 const ExtensionAction* action = GetAction(action_type, *extension.get());
127 ASSERT_TRUE(action);
129 ASSERT_TRUE(TitlesMatch(*extension.get(), *action));
130 ASSERT_TRUE(IconsMatch(*extension.get(), 128, *action, 38));
132 // Test that the action's missing default_icons are not replaced with smaller
133 // icons.
134 extension = BuildExtension(
135 DictionaryBuilder().Set("24", "icon24.png"),
136 DictionaryBuilder().Pass(),
137 action_type);
139 ASSERT_TRUE(extension.get());
140 action = GetAction(action_type, *extension.get());
141 ASSERT_TRUE(action);
143 ASSERT_TRUE(IconsMatch(*extension.get(), 24, *action, 19));
144 ASSERT_FALSE(IconsMatch(*extension.get(), 24, *action, 38));
146 // Test that an action's 19px icon is not replaced if a 38px action icon
147 // exists.
148 extension = BuildExtension(
149 DictionaryBuilder().Set("128", "icon128.png"),
150 DictionaryBuilder().Set("default_icon", DictionaryBuilder()
151 .Set("38", "action38.png")),
152 action_type);
154 ASSERT_TRUE(extension.get());
155 action = GetAction(action_type, *extension.get());
156 ASSERT_TRUE(action);
158 ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 19));
160 // Test that existing default_icons and default_title are not replaced.
161 extension = BuildExtension(
162 DictionaryBuilder().Set("128", "icon128.png"),
163 DictionaryBuilder().Set("default_title", "Action!")
164 .Set("default_icon", DictionaryBuilder()
165 .Set("19", "action19.png")
166 .Set("38", "action38.png")),
167 action_type);
169 ASSERT_TRUE(extension.get());
170 action = GetAction(action_type, *extension.get());
171 ASSERT_TRUE(action);
173 ASSERT_FALSE(TitlesMatch(*extension.get(), *action));
174 ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 19));
175 ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 38));
178 namespace {
180 TEST_F(ExtensionActionManagerTest, PopulateBrowserAction) {
181 TestPopulateMissingValues(kBrowserAction);
184 TEST_F(ExtensionActionManagerTest, PopulatePageAction) {
185 TestPopulateMissingValues(kPageAction);
188 TEST_F(ExtensionActionManagerTest, GetBestFitActionTest) {
189 // Create an extension with page action defaults.
190 scoped_refptr<Extension> extension = BuildExtension(
191 DictionaryBuilder().Set("48", "icon48.png"),
192 DictionaryBuilder().Set("default_title", "Action!")
193 .Set("default_icon", DictionaryBuilder()
194 .Set("38", "action38.png")),
195 kPageAction);
196 ASSERT_TRUE(extension.get());
198 // Get a "best fit" browser action for |extension|.
199 scoped_ptr<ExtensionAction> action =
200 manager()->GetBestFitAction(*extension.get(), ActionInfo::TYPE_BROWSER);
201 ASSERT_TRUE(action.get());
202 ASSERT_EQ(action->action_type(), ActionInfo::TYPE_BROWSER);
204 // |action|'s title and default icon should match |extension|'s page action's.
205 ASSERT_EQ(action->GetTitle(ExtensionAction::kDefaultTabId), "Action!");
206 ASSERT_EQ(action->default_icon()->Get(38, ExtensionIconSet::MATCH_EXACTLY),
207 "action38.png");
209 // Create a new extension without page action defaults.
210 extension = BuildExtension(
211 DictionaryBuilder().Set("48", "icon48.png"),
212 DictionaryBuilder().Pass(),
213 kPageAction);
214 ASSERT_TRUE(extension.get());
216 action =
217 manager()->GetBestFitAction(*extension.get(), ActionInfo::TYPE_BROWSER);
219 // Now these values match because |extension| does not have page action
220 // defaults.
221 ASSERT_TRUE(TitlesMatch(*extension.get(), *action));
222 ASSERT_TRUE(IconsMatch(*extension.get(), 48, *action, 38));
225 } // namespace
226 } // namespace extensions