MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / chrome / browser / extensions / extension_action_icon_factory_unittest.cc
blob657eaaf735d897eafc6b16ea727dcddc6a66bbbd
1 // Copyright (c) 2012 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_icon_factory.h"
7 #include "base/command_line.h"
8 #include "base/files/file_util.h"
9 #include "base/json/json_file_value_serializer.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/path_service.h"
12 #include "chrome/browser/extensions/extension_action.h"
13 #include "chrome/browser/extensions/extension_action_manager.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread.h"
19 #include "extensions/common/extension.h"
20 #include "grit/theme_resources.h"
21 #include "skia/ext/image_operations.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/codec/png_codec.h"
25 #include "ui/gfx/image/image_skia.h"
26 #include "ui/gfx/skia_util.h"
28 #if defined(OS_CHROMEOS)
29 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
30 #include "chrome/browser/chromeos/settings/cros_settings.h"
31 #include "chrome/browser/chromeos/settings/device_settings_service.h"
32 #endif
34 using content::BrowserThread;
36 namespace extensions {
37 namespace {
39 bool ImageRepsAreEqual(const gfx::ImageSkiaRep& image_rep1,
40 const gfx::ImageSkiaRep& image_rep2) {
41 return image_rep1.scale() == image_rep2.scale() &&
42 gfx::BitmapsAreEqual(image_rep1.sk_bitmap(), image_rep2.sk_bitmap());
45 gfx::Image EnsureImageSize(const gfx::Image& original, int size) {
46 const SkBitmap* original_bitmap = original.ToSkBitmap();
47 if (original_bitmap->width() == size && original_bitmap->height() == size)
48 return original;
50 SkBitmap resized = skia::ImageOperations::Resize(
51 *original.ToSkBitmap(), skia::ImageOperations::RESIZE_LANCZOS3,
52 size, size);
53 return gfx::Image::CreateFrom1xBitmap(resized);
56 gfx::ImageSkiaRep CreateBlankRep(int size_dip, float scale) {
57 SkBitmap bitmap;
58 bitmap.allocN32Pixels(static_cast<int>(size_dip * scale),
59 static_cast<int>(size_dip * scale));
60 bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0));
61 return gfx::ImageSkiaRep(bitmap, scale);
64 gfx::Image LoadIcon(const std::string& filename) {
65 base::FilePath path;
66 PathService::Get(chrome::DIR_TEST_DATA, &path);
67 path = path.AppendASCII("extensions/api_test").AppendASCII(filename);
69 std::string file_contents;
70 base::ReadFileToString(path, &file_contents);
71 const unsigned char* data =
72 reinterpret_cast<const unsigned char*>(file_contents.data());
74 SkBitmap bitmap;
75 gfx::PNGCodec::Decode(data, file_contents.length(), &bitmap);
77 return gfx::Image::CreateFrom1xBitmap(bitmap);
80 class ExtensionActionIconFactoryTest
81 : public testing::Test,
82 public ExtensionActionIconFactory::Observer {
83 public:
84 ExtensionActionIconFactoryTest()
85 : quit_in_icon_updated_(false),
86 ui_thread_(BrowserThread::UI, &ui_loop_),
87 file_thread_(BrowserThread::FILE),
88 io_thread_(BrowserThread::IO) {
91 virtual ~ExtensionActionIconFactoryTest() {}
93 void WaitForIconUpdate() {
94 quit_in_icon_updated_ = true;
95 base::MessageLoop::current()->Run();
96 quit_in_icon_updated_ = false;
99 scoped_refptr<Extension> CreateExtension(const char* name,
100 Manifest::Location location) {
101 // Create and load an extension.
102 base::FilePath test_file;
103 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) {
104 EXPECT_FALSE(true);
105 return NULL;
107 test_file = test_file.AppendASCII("extensions/api_test").AppendASCII(name);
108 int error_code = 0;
109 std::string error;
110 JSONFileValueSerializer serializer(test_file.AppendASCII("manifest.json"));
111 scoped_ptr<base::DictionaryValue> valid_value(
112 static_cast<base::DictionaryValue*>(serializer.Deserialize(&error_code,
113 &error)));
114 EXPECT_EQ(0, error_code) << error;
115 if (error_code != 0)
116 return NULL;
118 EXPECT_TRUE(valid_value.get());
119 if (!valid_value)
120 return NULL;
122 scoped_refptr<Extension> extension =
123 Extension::Create(test_file, location, *valid_value,
124 Extension::NO_FLAGS, &error);
125 EXPECT_TRUE(extension.get()) << error;
126 if (extension.get())
127 extension_service_->AddExtension(extension.get());
128 return extension;
131 // testing::Test overrides:
132 virtual void SetUp() override {
133 file_thread_.Start();
134 io_thread_.Start();
135 profile_.reset(new TestingProfile);
136 CommandLine command_line(CommandLine::NO_PROGRAM);
137 extension_service_ = static_cast<extensions::TestExtensionSystem*>(
138 extensions::ExtensionSystem::Get(profile_.get()))->
139 CreateExtensionService(&command_line, base::FilePath(), false);
142 virtual void TearDown() override {
143 profile_.reset(); // Get all DeleteSoon calls sent to ui_loop_.
144 ui_loop_.RunUntilIdle();
147 // ExtensionActionIconFactory::Observer overrides:
148 void OnIconUpdated() override {
149 if (quit_in_icon_updated_)
150 base::MessageLoop::current()->Quit();
153 gfx::ImageSkia GetFavicon() {
154 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
155 IDR_EXTENSIONS_FAVICON);
158 ExtensionAction* GetBrowserAction(const Extension& extension) {
159 return ExtensionActionManager::Get(profile())->GetBrowserAction(extension);
162 TestingProfile* profile() { return profile_.get(); }
164 private:
165 bool quit_in_icon_updated_;
166 base::MessageLoop ui_loop_;
167 content::TestBrowserThread ui_thread_;
168 content::TestBrowserThread file_thread_;
169 content::TestBrowserThread io_thread_;
170 scoped_ptr<TestingProfile> profile_;
171 ExtensionService* extension_service_;
173 #if defined OS_CHROMEOS
174 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
175 chromeos::ScopedTestCrosSettings test_cros_settings_;
176 chromeos::ScopedTestUserManager test_user_manager_;
177 #endif
179 DISALLOW_COPY_AND_ASSIGN(ExtensionActionIconFactoryTest);
182 // If there is no default icon, and the icon has not been set using |SetIcon|,
183 // the factory should return favicon.
184 TEST_F(ExtensionActionIconFactoryTest, NoIcons) {
185 // Load an extension that has browser action without default icon set in the
186 // manifest and does not call |SetIcon| by default.
187 scoped_refptr<Extension> extension(CreateExtension(
188 "browser_action/no_icon", Manifest::INVALID_LOCATION));
189 ASSERT_TRUE(extension.get() != NULL);
190 ExtensionAction* browser_action = GetBrowserAction(*extension.get());
191 ASSERT_TRUE(browser_action);
192 ASSERT_FALSE(browser_action->default_icon());
193 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull());
195 gfx::ImageSkia favicon = GetFavicon();
197 ExtensionActionIconFactory icon_factory(
198 profile(), extension.get(), browser_action, this);
200 gfx::Image icon = icon_factory.GetIcon(0);
202 EXPECT_TRUE(ImageRepsAreEqual(
203 favicon.GetRepresentation(1.0f),
204 icon.ToImageSkia()->GetRepresentation(1.0f)));
207 // If the icon has been set using |SetIcon|, the factory should return that
208 // icon.
209 TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) {
210 // Load an extension that has browser action without default icon set in the
211 // manifest and does not call |SetIcon| by default (but has an browser action
212 // icon resource).
213 scoped_refptr<Extension> extension(CreateExtension(
214 "browser_action/no_icon", Manifest::INVALID_LOCATION));
215 ASSERT_TRUE(extension.get() != NULL);
216 ExtensionAction* browser_action = GetBrowserAction(*extension.get());
217 ASSERT_TRUE(browser_action);
218 ASSERT_FALSE(browser_action->default_icon());
219 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull());
221 gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png");
222 ASSERT_FALSE(set_icon.IsEmpty());
224 browser_action->SetIcon(0, set_icon);
226 ASSERT_FALSE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull());
228 ExtensionActionIconFactory icon_factory(
229 profile(), extension.get(), browser_action, this);
231 gfx::Image icon = icon_factory.GetIcon(0);
233 EXPECT_TRUE(ImageRepsAreEqual(
234 set_icon.ToImageSkia()->GetRepresentation(1.0f),
235 icon.ToImageSkia()->GetRepresentation(1.0f)));
237 // It should still return favicon for another tabs.
238 icon = icon_factory.GetIcon(1);
240 EXPECT_TRUE(ImageRepsAreEqual(
241 GetFavicon().GetRepresentation(1.0f),
242 icon.ToImageSkia()->GetRepresentation(1.0f)));
245 // If there is a default icon, and the icon has not been set using |SetIcon|,
246 // the factory should return the default icon.
247 TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) {
248 // Load an extension that has browser action without default icon set in the
249 // manifest and does not call |SetIcon| by default (but has an browser action
250 // icon resource).
251 scoped_refptr<Extension> extension(CreateExtension(
252 "browser_action/no_icon", Manifest::INVALID_LOCATION));
253 ASSERT_TRUE(extension.get() != NULL);
254 ExtensionAction* browser_action = GetBrowserAction(*extension.get());
255 ASSERT_TRUE(browser_action);
256 ASSERT_FALSE(browser_action->default_icon());
257 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull());
259 gfx::Image default_icon =
260 EnsureImageSize(LoadIcon("browser_action/no_icon/icon.png"), 19);
261 ASSERT_FALSE(default_icon.IsEmpty());
263 scoped_ptr<ExtensionIconSet> default_icon_set(new ExtensionIconSet());
264 default_icon_set->Add(19, "icon.png");
266 browser_action->set_default_icon(default_icon_set.Pass());
267 ASSERT_TRUE(browser_action->default_icon());
269 ExtensionActionIconFactory icon_factory(
270 profile(), extension.get(), browser_action, this);
272 gfx::Image icon = icon_factory.GetIcon(0);
274 // The icon should be loaded asynchronously. Initially a transparent icon
275 // should be returned.
276 EXPECT_TRUE(ImageRepsAreEqual(
277 CreateBlankRep(19, 1.0f),
278 icon.ToImageSkia()->GetRepresentation(1.0f)));
280 WaitForIconUpdate();
282 icon = icon_factory.GetIcon(0);
284 // The default icon representation should be loaded at this point.
285 EXPECT_TRUE(ImageRepsAreEqual(
286 default_icon.ToImageSkia()->GetRepresentation(1.0f),
287 icon.ToImageSkia()->GetRepresentation(1.0f)));
289 // The same icon should be returned for the other tabs.
290 icon = icon_factory.GetIcon(1);
292 EXPECT_TRUE(ImageRepsAreEqual(
293 default_icon.ToImageSkia()->GetRepresentation(1.0f),
294 icon.ToImageSkia()->GetRepresentation(1.0f)));
298 } // namespace
299 } // namespace extensions