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 // Tests that values that are missing from the |action_type| key are properly | |
46 // populated with values from the other keys in the manifest (e.g. | |
47 // "default_icon" key of |action_type| is populated with "icons" key). | |
48 void TestPopulateMissingValues(const char* action_type); | |
49 | |
50 ExtensionActionManager* manager() { return manager_; } | |
51 | |
52 private: | |
53 int curr_id_; | |
54 ExtensionActionManager* manager_; | |
55 scoped_ptr<TestingProfile> profile_; | |
56 }; | |
57 | |
58 ExtensionActionManagerTest::ExtensionActionManagerTest() | |
59 : curr_id_(0), | |
60 profile_(new TestingProfile) { | |
61 manager_ = ExtensionActionManager::Get(profile_.get()); | |
62 } | |
63 | |
64 scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension( | |
65 DictionaryBuilder& extension_icons, | |
66 DictionaryBuilder& action, | |
67 const char* action_type) { | |
68 std::string id = base::IntToString(curr_id_++); | |
69 return ExtensionBuilder() | |
70 .SetManifest(DictionaryBuilder().Set("version", "1") | |
71 .Set("manifest_version", 2) | |
72 .Set("icons", extension_icons) | |
73 .Set(action_type, action) | |
74 .Set("name", | |
75 std::string("Test Extension").append(id))) | |
76 .SetID(id) | |
77 .Build(); | |
78 } | |
79 | |
80 bool ExtensionActionManagerTest::TitlesMatch(const Extension& extension, | |
81 const ExtensionAction& action) { | |
82 return action.GetTitle(ExtensionAction::kDefaultTabId) == extension.name(); | |
83 } | |
84 | |
85 bool ExtensionActionManagerTest::IconsMatch(const Extension& extension, | |
86 int extension_key, | |
87 const ExtensionAction& action, | |
88 int action_key) { | |
89 return action.default_icon()->Get(action_key, | |
90 ExtensionIconSet::MATCH_EXACTLY) == | |
91 IconsInfo::GetIcons(&extension).Get(extension_key, | |
92 ExtensionIconSet::MATCH_EXACTLY); | |
93 } | |
94 | |
95 void ExtensionActionManagerTest::TestPopulateMissingValues( | |
96 const char* action_type) { | |
97 // Determine the appropriate getter method for |action_type|. | |
98 const base::Callback<ExtensionAction*(const Extension&)> getter = base::Bind( | |
99 (action_type == kBrowserAction) ? | |
not at google - send to devlin
2014/08/07 16:03:37
why not just pass ExtensionActionManager::Get{Brow
gpdavis
2014/08/07 18:31:00
Well, I figured since we already need to pass |act
not at google - send to devlin
2014/08/07 20:50:18
ah, fair enough. I didn't notice you needed to pas
gpdavis
2014/08/07 21:28:18
Sure, I can dig this idea.
| |
100 &ExtensionActionManager::GetBrowserAction : | |
101 &ExtensionActionManager::GetPageAction, | |
102 base::Unretained(manager_)); | |
103 | |
104 // Test that the largest icon from the extension's "icons" key is chosen as a | |
105 // replacement for missing action default_icons keys. | |
106 scoped_ptr<DictionaryBuilder> extension_icons(new DictionaryBuilder()); | |
107 extension_icons->Set("48", "icon48.png") | |
108 .Set("128", "icon128.png"); | |
109 scoped_refptr<Extension> extension = BuildExtension( | |
110 extension_icons->Pass(), | |
not at google - send to devlin
2014/08/07 16:03:37
there are a lot of instances in this test where yo
gpdavis
2014/08/07 18:31:00
I was primarily concerned with the readability and
not at google - send to devlin
2014/08/07 20:50:18
yeah it looks odd to me, for example |extension_ic
gpdavis
2014/08/07 21:28:18
Alrighty. Will rewrite with inline DictionaryBuil
| |
111 DictionaryBuilder().Pass(), | |
112 action_type); | |
113 | |
114 ASSERT_TRUE(extension.get()); | |
115 const ExtensionAction* action = getter.Run(*extension); | |
116 ASSERT_TRUE(action); | |
117 | |
118 ASSERT_TRUE(TitlesMatch(*extension, *action)); | |
119 ASSERT_TRUE(IconsMatch(*extension, 128, *action, 19)); | |
120 ASSERT_TRUE(IconsMatch(*extension, 128, *action, 38)); | |
121 | |
122 // Test that the action's missing default_icons are not replaced with smaller | |
123 // icons. | |
124 extension_icons.reset(new DictionaryBuilder()); | |
125 extension_icons->Set("16", "icon16.png"); | |
126 extension = BuildExtension( | |
127 extension_icons->Pass(), | |
128 DictionaryBuilder().Pass(), | |
129 action_type); | |
130 | |
131 ASSERT_TRUE(extension.get()); | |
132 action = getter.Run(*extension); | |
133 ASSERT_TRUE(action); | |
134 | |
135 ASSERT_FALSE(IconsMatch(*extension, 16, *action, 19)); | |
136 ASSERT_FALSE(IconsMatch(*extension, 16, *action, 38)); | |
137 | |
138 // Test that an action's 38px icon is used as a replacement for the 19px icon | |
139 // if it is missing. No icons from the "icons" key should be used instead. | |
140 extension_icons.reset(new DictionaryBuilder()); | |
141 extension_icons->Set("128", "icon128.png"); | |
142 scoped_ptr<DictionaryBuilder> action_manifest(new DictionaryBuilder()); | |
143 action_manifest->Set("default_icon", DictionaryBuilder() | |
144 .Set("38", "action38.png")); | |
145 extension = BuildExtension( | |
146 extension_icons->Pass(), | |
147 action_manifest->Pass(), | |
148 action_type); | |
149 | |
150 ASSERT_TRUE(extension.get()); | |
151 action = getter.Run(*extension); | |
152 ASSERT_TRUE(action); | |
153 | |
154 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); | |
155 ASSERT_EQ(action->default_icon()->Get(19, ExtensionIconSet::MATCH_EXACTLY), | |
156 action->default_icon()->Get(38, ExtensionIconSet::MATCH_EXACTLY)); | |
157 | |
158 // Test that existing default_icons and default_title are not replaced. | |
159 extension_icons.reset(new DictionaryBuilder()); | |
160 extension_icons->Set("128", "icon128.png"); | |
161 action_manifest.reset(new DictionaryBuilder()); | |
162 action_manifest->Set("default_title", "Action!") | |
163 .Set("default_icon", DictionaryBuilder() | |
164 .Set("19", "action19.png") | |
165 .Set("38", "action38.png")); | |
166 extension = BuildExtension( | |
167 extension_icons->Pass(), | |
168 action_manifest->Pass(), | |
169 action_type); | |
170 | |
171 ASSERT_TRUE(extension.get()); | |
172 action = getter.Run(*extension); | |
173 ASSERT_TRUE(action); | |
174 | |
175 ASSERT_FALSE(TitlesMatch(*extension, *action)); | |
176 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); | |
177 ASSERT_FALSE(IconsMatch(*extension, 128, *action, 38)); | |
178 } | |
179 | |
180 namespace { | |
181 | |
182 TEST_F(ExtensionActionManagerTest, PopulateBrowserAction) { | |
183 TestPopulateMissingValues(kBrowserAction); | |
184 } | |
185 | |
186 TEST_F(ExtensionActionManagerTest, PopulatePageAction) { | |
187 TestPopulateMissingValues(kPageAction); | |
188 } | |
189 | |
190 TEST_F(ExtensionActionManagerTest, GetBestFitActionTest) { | |
191 // Create an extension with page action defaults. | |
192 scoped_ptr<DictionaryBuilder> extension_icons(new DictionaryBuilder()); | |
193 extension_icons->Set("48", "icon48.png"); | |
194 scoped_ptr<DictionaryBuilder> action_manifest(new DictionaryBuilder()); | |
195 action_manifest->Set("default_title", "Action!") | |
196 .Set("default_icon", DictionaryBuilder() | |
197 .Set("38", "action38.png")); | |
198 scoped_refptr<Extension> extension = BuildExtension(extension_icons->Pass(), | |
199 action_manifest->Pass(), | |
200 kPageAction); | |
201 ASSERT_TRUE(extension.get()); | |
202 | |
203 // Get a "best fit" browser action for |extension|. | |
204 scoped_ptr<ExtensionAction> action = | |
205 manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); | |
206 ASSERT_TRUE(action.get()); | |
207 | |
208 // |action|'s title and default icon should not match |extension|'s because | |
209 // the data should be pulled from |extension|'s page action manifest key. | |
210 ASSERT_FALSE(TitlesMatch(*extension, *action)); | |
not at google - send to devlin
2014/08/07 16:03:37
it's better to ASSERT_TRUE(TitlesMatch(*extension,
gpdavis
2014/08/07 18:31:00
I'm a little confused-- why would this pass if the
not at google - send to devlin
2014/08/07 20:50:18
TitlesMatch("Test Extension", "") --> false --> AS
gpdavis
2014/08/07 21:28:18
Ah, you said ASSERT_TRUE in the first comment. Th
not at google - send to devlin
2014/08/07 21:34:41
yep, that's pretty much what I'm suggesting. thoug
| |
211 ASSERT_FALSE(IconsMatch(*extension, 48, *action, 19)); | |
212 ASSERT_FALSE(IconsMatch(*extension, 48, *action, 38)); | |
213 | |
214 // Create a new extension without page action defaults. | |
215 extension_icons.reset(new DictionaryBuilder()); | |
216 extension_icons->Set("48", "icon48.png"); | |
217 extension = BuildExtension( | |
218 extension_icons->Pass(), | |
219 DictionaryBuilder().Pass(), | |
220 kPageAction); | |
221 ASSERT_TRUE(extension.get()); | |
222 | |
223 action = manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); | |
224 | |
225 // Now these values match because |extension| does not have page action | |
226 // defaults. | |
227 ASSERT_TRUE(TitlesMatch(*extension, *action)); | |
228 ASSERT_TRUE(IconsMatch(*extension, 48, *action, 19)); | |
229 ASSERT_TRUE(IconsMatch(*extension, 48, *action, 38)); | |
230 } | |
231 | |
232 } // namespace | |
233 } // namespace extensions | |
OLD | NEW |