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