Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: chrome/browser/extensions/extension_action_manager_unittest.cc

Issue 415813003: Improve extension icon prediction (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Enhanced tests, updated icon logic Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698