Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / themes / theme_service_unittest.cc
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.
4
5 #include "chrome/browser/themes/theme_service.h"
6
7 #include "base/files/file_util.h"
8 #include "base/path_service.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_service_test_base.h"
12 #include "chrome/browser/extensions/unpacked_installer.h"
13 #include "chrome/browser/themes/custom_theme_supplier.h"
14 #include "chrome/browser/themes/theme_service_factory.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_browser_process.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "chrome/test/base/testing_profile_manager.h"
20 #include "content/public/test/test_utils.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/browser/uninstall_reason.h"
23 #include "extensions/common/extension.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 #if defined(ENABLE_MANAGED_USERS)
27 #include "chrome/browser/supervised_user/supervised_user_service.h"
28 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
29 #endif
30
31 using extensions::ExtensionRegistry;
32
33 namespace theme_service_internal {
34
35 class ThemeServiceTest : public extensions::ExtensionServiceTestBase {
36  public:
37   ThemeServiceTest() : is_supervised_(false),
38                        registry_(NULL) {}
39   ~ThemeServiceTest() override {}
40
41   // Moves a minimal theme to |temp_dir_path| and unpacks it from that
42   // directory.
43   std::string LoadUnpackedThemeAt(const base::FilePath& temp_dir) {
44     base::FilePath dst_manifest_path = temp_dir.AppendASCII("manifest.json");
45     base::FilePath test_data_dir;
46     EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
47     base::FilePath src_manifest_path =
48         test_data_dir.AppendASCII("extensions/theme_minimal/manifest.json");
49     EXPECT_TRUE(base::CopyFile(src_manifest_path, dst_manifest_path));
50
51     scoped_refptr<extensions::UnpackedInstaller> installer(
52         extensions::UnpackedInstaller::Create(service_));
53     content::WindowedNotificationObserver observer(
54         extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
55         content::Source<Profile>(profile_.get()));
56     installer->Load(temp_dir);
57     observer.Wait();
58
59     std::string extension_id =
60         content::Details<extensions::Extension>(observer.details())->id();
61
62     // Let the ThemeService finish creating the theme pack.
63     base::MessageLoop::current()->RunUntilIdle();
64
65     return extension_id;
66   }
67
68   // Update the theme with |extension_id|.
69   void UpdateUnpackedTheme(const std::string& extension_id) {
70     int updated_notification =
71         service_->IsExtensionEnabled(extension_id)
72             ? extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED
73             : extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED;
74
75     const base::FilePath& path =
76         service_->GetInstalledExtension(extension_id)->path();
77
78     scoped_refptr<extensions::UnpackedInstaller> installer(
79         extensions::UnpackedInstaller::Create(service_));
80     content::WindowedNotificationObserver observer(updated_notification,
81         content::Source<Profile>(profile_.get()));
82     installer->Load(path);
83     observer.Wait();
84
85     // Let the ThemeService finish creating the theme pack.
86     base::MessageLoop::current()->RunUntilIdle();
87   }
88
89   void SetUp() override {
90     extensions::ExtensionServiceTestBase::SetUp();
91     extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params =
92         CreateDefaultInitParams();
93     params.profile_is_supervised = is_supervised_;
94     InitializeExtensionService(params);
95     service_->Init();
96     registry_ = ExtensionRegistry::Get(profile_.get());
97     ASSERT_TRUE(registry_);
98   }
99
100   const CustomThemeSupplier* get_theme_supplier(ThemeService* theme_service) {
101     return theme_service->get_theme_supplier();
102   }
103
104  protected:
105   bool is_supervised_;
106   ExtensionRegistry* registry_;
107
108 };
109
110 // Installs then uninstalls a theme and makes sure that the ThemeService
111 // reverts to the default theme after the uninstall.
112 TEST_F(ThemeServiceTest, ThemeInstallUninstall) {
113   ThemeService* theme_service =
114       ThemeServiceFactory::GetForProfile(profile_.get());
115   theme_service->UseDefaultTheme();
116   // Let the ThemeService uninstall unused themes.
117   base::MessageLoop::current()->RunUntilIdle();
118
119   base::ScopedTempDir temp_dir;
120   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
121   const std::string& extension_id = LoadUnpackedThemeAt(temp_dir.path());
122   EXPECT_FALSE(theme_service->UsingDefaultTheme());
123   EXPECT_EQ(extension_id, theme_service->GetThemeID());
124
125   // Now uninstall the extension, should revert to the default theme.
126   service_->UninstallExtension(extension_id,
127                                extensions::UNINSTALL_REASON_FOR_TESTING,
128                                base::Bind(&base::DoNothing),
129                                NULL);
130   EXPECT_TRUE(theme_service->UsingDefaultTheme());
131 }
132
133 // Test that a theme extension is disabled when not in use. A theme may be
134 // installed but not in use if it there is an infobar to revert to the previous
135 // theme.
136 TEST_F(ThemeServiceTest, DisableUnusedTheme) {
137   ThemeService* theme_service =
138       ThemeServiceFactory::GetForProfile(profile_.get());
139   theme_service->UseDefaultTheme();
140   // Let the ThemeService uninstall unused themes.
141   base::MessageLoop::current()->RunUntilIdle();
142
143   base::ScopedTempDir temp_dir1;
144   ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
145   base::ScopedTempDir temp_dir2;
146   ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
147
148   // 1) Installing a theme should disable the previously active theme.
149   const std::string& extension1_id = LoadUnpackedThemeAt(temp_dir1.path());
150   EXPECT_FALSE(theme_service->UsingDefaultTheme());
151   EXPECT_EQ(extension1_id, theme_service->GetThemeID());
152   EXPECT_TRUE(service_->IsExtensionEnabled(extension1_id));
153
154   // Show an infobar to prevent the current theme from being uninstalled.
155   theme_service->OnInfobarDisplayed();
156
157   const std::string& extension2_id = LoadUnpackedThemeAt(temp_dir2.path());
158   EXPECT_EQ(extension2_id, theme_service->GetThemeID());
159   EXPECT_TRUE(service_->IsExtensionEnabled(extension2_id));
160   EXPECT_TRUE(registry_->GetExtensionById(extension1_id,
161                                           ExtensionRegistry::DISABLED));
162
163   // 2) Enabling a disabled theme extension should swap the current theme.
164   service_->EnableExtension(extension1_id);
165   base::MessageLoop::current()->RunUntilIdle();
166   EXPECT_EQ(extension1_id, theme_service->GetThemeID());
167   EXPECT_TRUE(service_->IsExtensionEnabled(extension1_id));
168   EXPECT_TRUE(registry_->GetExtensionById(extension2_id,
169                                           ExtensionRegistry::DISABLED));
170
171   // 3) Using SetTheme() with a disabled theme should enable and set the
172   // theme. This is the case when the user reverts to the previous theme
173   // via an infobar.
174   const extensions::Extension* extension2 =
175       service_->GetInstalledExtension(extension2_id);
176   theme_service->SetTheme(extension2);
177   base::MessageLoop::current()->RunUntilIdle();
178   EXPECT_EQ(extension2_id, theme_service->GetThemeID());
179   EXPECT_TRUE(service_->IsExtensionEnabled(extension2_id));
180   EXPECT_TRUE(registry_->GetExtensionById(extension1_id,
181                                           ExtensionRegistry::DISABLED));
182
183   // 4) Disabling the current theme extension should revert to the default theme
184   // and uninstall any installed theme extensions.
185   theme_service->OnInfobarDestroyed();
186   EXPECT_FALSE(theme_service->UsingDefaultTheme());
187   service_->DisableExtension(extension2_id,
188       extensions::Extension::DISABLE_USER_ACTION);
189   base::MessageLoop::current()->RunUntilIdle();
190   EXPECT_TRUE(theme_service->UsingDefaultTheme());
191   EXPECT_FALSE(service_->GetInstalledExtension(extension1_id));
192   EXPECT_FALSE(service_->GetInstalledExtension(extension2_id));
193 }
194
195 // Test the ThemeService's behavior when a theme is upgraded.
196 TEST_F(ThemeServiceTest, ThemeUpgrade) {
197   // Setup.
198   ThemeService* theme_service =
199       ThemeServiceFactory::GetForProfile(profile_.get());
200   theme_service->UseDefaultTheme();
201   // Let the ThemeService uninstall unused themes.
202   base::MessageLoop::current()->RunUntilIdle();
203
204   theme_service->OnInfobarDisplayed();
205
206   base::ScopedTempDir temp_dir1;
207   ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
208   base::ScopedTempDir temp_dir2;
209   ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
210
211   const std::string& extension1_id = LoadUnpackedThemeAt(temp_dir1.path());
212   const std::string& extension2_id = LoadUnpackedThemeAt(temp_dir2.path());
213
214   // Test the initial state.
215   EXPECT_TRUE(registry_->GetExtensionById(extension1_id,
216                                           ExtensionRegistry::DISABLED));
217   EXPECT_EQ(extension2_id, theme_service->GetThemeID());
218
219   // 1) Upgrading the current theme should not revert to the default theme.
220   content::WindowedNotificationObserver theme_change_observer(
221       chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
222       content::Source<ThemeService>(theme_service));
223   UpdateUnpackedTheme(extension2_id);
224
225   // The ThemeService should have sent an theme change notification even though
226   // the id of the current theme did not change.
227   theme_change_observer.Wait();
228
229   EXPECT_EQ(extension2_id, theme_service->GetThemeID());
230   EXPECT_TRUE(registry_->GetExtensionById(extension1_id,
231                                           ExtensionRegistry::DISABLED));
232
233   // 2) Upgrading a disabled theme should not change the current theme.
234   UpdateUnpackedTheme(extension1_id);
235   EXPECT_EQ(extension2_id, theme_service->GetThemeID());
236   EXPECT_TRUE(registry_->GetExtensionById(extension1_id,
237                                           ExtensionRegistry::DISABLED));
238 }
239
240 #if defined(ENABLE_MANAGED_USERS)
241 class ThemeServiceSupervisedUserTest : public ThemeServiceTest {
242  public:
243   ThemeServiceSupervisedUserTest() {}
244   ~ThemeServiceSupervisedUserTest() override {}
245
246   void SetUp() override {
247     is_supervised_ = true;
248     ThemeServiceTest::SetUp();
249   }
250 };
251
252 // Checks that supervised users have their own default theme.
253 TEST_F(ThemeServiceSupervisedUserTest,
254        SupervisedUserThemeReplacesDefaultTheme) {
255   ThemeService* theme_service =
256       ThemeServiceFactory::GetForProfile(profile_.get());
257   theme_service->UseDefaultTheme();
258   EXPECT_TRUE(theme_service->UsingDefaultTheme());
259   EXPECT_TRUE(get_theme_supplier(theme_service));
260   EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(),
261             CustomThemeSupplier::SUPERVISED_USER_THEME);
262 }
263
264 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
265 // Checks that supervised users don't use the system theme even if it is the
266 // default. The system theme is only available on Linux.
267 TEST_F(ThemeServiceSupervisedUserTest, SupervisedUserThemeReplacesNativeTheme) {
268   profile_->GetPrefs()->SetBoolean(prefs::kUsesSystemTheme, true);
269   ThemeService* theme_service =
270       ThemeServiceFactory::GetForProfile(profile_.get());
271   theme_service->UseDefaultTheme();
272   EXPECT_TRUE(theme_service->UsingDefaultTheme());
273   EXPECT_TRUE(get_theme_supplier(theme_service));
274   EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(),
275             CustomThemeSupplier::SUPERVISED_USER_THEME);
276 }
277 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
278 #endif // defined(ENABLE_MANAGED_USERS)
279
280 }; // namespace theme_service_internal