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/themes/theme_syncable_service.h"
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "base/files/file_path.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/test_extension_system.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/themes/theme_service.h"
16 #include "chrome/browser/themes/theme_service_factory.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "content/public/test/test_browser_thread.h"
20 #include "extensions/browser/extension_prefs.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/common/extension.h"
23 #include "extensions/common/manifest_constants.h"
24 #include "extensions/common/manifest_url_handlers.h"
25 #include "extensions/common/permissions/api_permission_set.h"
26 #include "extensions/common/permissions/permission_set.h"
27 #include "sync/api/attachments/attachment_id.h"
28 #include "sync/api/fake_sync_change_processor.h"
29 #include "sync/api/sync_change_processor_wrapper_for_test.h"
30 #include "sync/api/sync_error.h"
31 #include "sync/api/sync_error_factory_mock.h"
32 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
33 #include "sync/protocol/sync.pb.h"
34 #include "sync/protocol/theme_specifics.pb.h"
35 #include "testing/gtest/include/gtest/gtest.h"
37 #if defined(OS_CHROMEOS)
38 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
39 #include "chrome/browser/chromeos/settings/cros_settings.h"
40 #include "chrome/browser/chromeos/settings/device_settings_service.h"
47 static const char kCustomThemeName
[] = "name";
48 static const char kCustomThemeUrl
[] = "http://update.url/foo";
51 const base::FilePath::CharType kExtensionFilePath
[] =
52 FILE_PATH_LITERAL("c:\\foo");
53 #elif defined(OS_POSIX)
54 const base::FilePath::CharType kExtensionFilePath
[] = FILE_PATH_LITERAL("/oo");
57 class FakeThemeService
: public ThemeService
{
60 using_system_theme_(false),
61 using_default_theme_(false),
62 theme_extension_(NULL
),
65 // ThemeService implementation
66 void SetTheme(const extensions::Extension
* extension
) override
{
68 theme_extension_
= extension
;
69 using_system_theme_
= false;
70 using_default_theme_
= false;
73 void UseDefaultTheme() override
{
75 using_default_theme_
= true;
76 using_system_theme_
= false;
77 theme_extension_
= NULL
;
80 void UseSystemTheme() override
{
82 using_system_theme_
= true;
83 using_default_theme_
= false;
84 theme_extension_
= NULL
;
87 bool UsingDefaultTheme() const override
{ return using_default_theme_
; }
89 bool UsingSystemTheme() const override
{ return using_system_theme_
; }
91 string
GetThemeID() const override
{
92 if (theme_extension_
.get())
93 return theme_extension_
->id();
98 const extensions::Extension
* theme_extension() const {
99 return theme_extension_
.get();
102 bool is_dirty() const {
111 bool using_system_theme_
;
112 bool using_default_theme_
;
113 scoped_refptr
<const extensions::Extension
> theme_extension_
;
117 scoped_ptr
<KeyedService
> BuildMockThemeService(
118 content::BrowserContext
* profile
) {
119 return make_scoped_ptr(new FakeThemeService
);
122 scoped_refptr
<extensions::Extension
> MakeThemeExtension(
123 const base::FilePath
& extension_path
,
125 extensions::Manifest::Location location
,
126 const string
& update_url
) {
127 base::DictionaryValue source
;
128 source
.SetString(extensions::manifest_keys::kName
, name
);
129 source
.Set(extensions::manifest_keys::kTheme
, new base::DictionaryValue());
130 source
.SetString(extensions::manifest_keys::kUpdateURL
, update_url
);
131 source
.SetString(extensions::manifest_keys::kVersion
, "0.0.0.0");
133 scoped_refptr
<extensions::Extension
> extension
=
134 extensions::Extension::Create(
135 extension_path
, location
, source
,
136 extensions::Extension::NO_FLAGS
, &error
);
137 EXPECT_TRUE(extension
.get());
138 EXPECT_EQ("", error
);
144 class ThemeSyncableServiceTest
: public testing::Test
{
146 ThemeSyncableServiceTest()
147 : ui_thread_(content::BrowserThread::UI
, &loop_
),
148 file_thread_(content::BrowserThread::FILE, &loop_
),
149 fake_theme_service_(NULL
) {}
151 ~ThemeSyncableServiceTest() override
{}
153 void SetUp() override
{
154 // Setting a matching update URL is necessary to make the test theme
155 // considered syncable.
156 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
157 switches::kAppsGalleryUpdateURL
, kCustomThemeUrl
);
159 profile_
.reset(new TestingProfile
);
160 fake_theme_service_
= BuildForProfile(profile_
.get());
161 theme_sync_service_
.reset(new ThemeSyncableService(profile_
.get(),
162 fake_theme_service_
));
163 fake_change_processor_
.reset(new syncer::FakeSyncChangeProcessor
);
167 void TearDown() override
{
169 loop_
.RunUntilIdle();
172 void SetUpExtension() {
173 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
174 extensions::TestExtensionSystem
* test_ext_system
=
175 static_cast<extensions::TestExtensionSystem
*>(
176 extensions::ExtensionSystem::Get(profile_
.get()));
177 ExtensionService
* service
= test_ext_system
->CreateExtensionService(
178 &command_line
, base::FilePath(kExtensionFilePath
), false);
179 EXPECT_TRUE(service
->extensions_enabled());
181 loop_
.RunUntilIdle();
183 // Create and add custom theme extension so the ThemeSyncableService can
185 theme_extension_
= MakeThemeExtension(base::FilePath(kExtensionFilePath
),
189 extensions::APIPermissionSet empty_set
;
190 extensions::ManifestPermissionSet empty_manifest_permissions
;
191 extensions::URLPatternSet empty_extent
;
192 scoped_refptr
<extensions::PermissionSet
> permissions
=
193 new extensions::PermissionSet(empty_set
, empty_manifest_permissions
,
194 empty_extent
, empty_extent
);
195 extensions::ExtensionPrefs::Get(profile_
.get())
196 ->AddGrantedPermissions(theme_extension_
->id(), permissions
.get());
197 service
->AddExtension(theme_extension_
.get());
198 extensions::ExtensionRegistry
* registry
=
199 extensions::ExtensionRegistry::Get(profile_
.get());
200 ASSERT_EQ(1u, registry
->enabled_extensions().size());
203 // Overridden in PolicyInstalledThemeTest below.
204 virtual extensions::Manifest::Location
GetThemeLocation() {
205 return extensions::Manifest::INTERNAL
;
208 FakeThemeService
* BuildForProfile(Profile
* profile
) {
209 return static_cast<FakeThemeService
*>(
210 ThemeServiceFactory::GetInstance()->SetTestingFactoryAndUse(
211 profile
, &BuildMockThemeService
));
214 syncer::SyncDataList
MakeThemeDataList(
215 const sync_pb::ThemeSpecifics
& theme_specifics
) {
216 syncer::SyncDataList list
;
217 sync_pb::EntitySpecifics entity_specifics
;
218 entity_specifics
.mutable_theme()->CopyFrom(theme_specifics
);
219 list
.push_back(syncer::SyncData::CreateLocalData(
220 ThemeSyncableService::kCurrentThemeClientTag
,
221 ThemeSyncableService::kCurrentThemeNodeTitle
,
226 // Needed for setting up extension service.
227 base::MessageLoop loop_
;
228 content::TestBrowserThread ui_thread_
;
229 content::TestBrowserThread file_thread_
;
231 #if defined OS_CHROMEOS
232 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
233 chromeos::ScopedTestCrosSettings test_cros_settings_
;
234 chromeos::ScopedTestUserManager test_user_manager_
;
237 scoped_ptr
<TestingProfile
> profile_
;
238 FakeThemeService
* fake_theme_service_
;
239 scoped_refptr
<extensions::Extension
> theme_extension_
;
240 scoped_ptr
<ThemeSyncableService
> theme_sync_service_
;
241 scoped_ptr
<syncer::FakeSyncChangeProcessor
> fake_change_processor_
;
244 class PolicyInstalledThemeTest
: public ThemeSyncableServiceTest
{
245 extensions::Manifest::Location
GetThemeLocation() override
{
246 return extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD
;
250 TEST_F(ThemeSyncableServiceTest
, AreThemeSpecificsEqual
) {
251 sync_pb::ThemeSpecifics a
, b
;
252 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
253 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
255 // Custom vs. non-custom.
257 a
.set_use_custom_theme(true);
258 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
259 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
261 // Custom theme equality.
263 b
.set_use_custom_theme(true);
264 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
265 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
267 a
.set_custom_theme_id("id");
268 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
269 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
271 b
.set_custom_theme_id("id");
272 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
273 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
275 a
.set_custom_theme_update_url("http://update.url");
276 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
277 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
279 a
.set_custom_theme_name("name");
280 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
281 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
283 // Non-custom theme equality.
285 a
.set_use_custom_theme(false);
286 b
.set_use_custom_theme(false);
287 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
288 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
290 a
.set_use_system_theme_by_default(true);
291 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
292 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
294 b
.set_use_system_theme_by_default(true);
295 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, false));
296 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a
, b
, true));
299 TEST_F(ThemeSyncableServiceTest
, SetCurrentThemeDefaultTheme
) {
300 // Set up theme service to use custom theme.
301 fake_theme_service_
->SetTheme(theme_extension_
.get());
303 syncer::SyncError error
=
305 ->MergeDataAndStartSyncing(
307 MakeThemeDataList(sync_pb::ThemeSpecifics()),
308 scoped_ptr
<syncer::SyncChangeProcessor
>(
309 new syncer::SyncChangeProcessorWrapperForTest(
310 fake_change_processor_
.get())),
311 scoped_ptr
<syncer::SyncErrorFactory
>(
312 new syncer::SyncErrorFactoryMock()))
314 EXPECT_FALSE(error
.IsSet()) << error
.message();
315 EXPECT_FALSE(fake_theme_service_
->UsingDefaultTheme());
316 EXPECT_EQ(fake_theme_service_
->theme_extension(), theme_extension_
.get());
319 TEST_F(ThemeSyncableServiceTest
, SetCurrentThemeSystemTheme
) {
320 sync_pb::ThemeSpecifics theme_specifics
;
321 theme_specifics
.set_use_system_theme_by_default(true);
323 // Set up theme service to use custom theme.
324 fake_theme_service_
->SetTheme(theme_extension_
.get());
325 syncer::SyncError error
=
327 ->MergeDataAndStartSyncing(
329 MakeThemeDataList(theme_specifics
),
330 scoped_ptr
<syncer::SyncChangeProcessor
>(
331 new syncer::SyncChangeProcessorWrapperForTest(
332 fake_change_processor_
.get())),
333 scoped_ptr
<syncer::SyncErrorFactory
>(
334 new syncer::SyncErrorFactoryMock()))
336 EXPECT_FALSE(error
.IsSet()) << error
.message();
337 EXPECT_FALSE(fake_theme_service_
->UsingSystemTheme());
338 EXPECT_EQ(fake_theme_service_
->theme_extension(), theme_extension_
.get());
341 TEST_F(ThemeSyncableServiceTest
, SetCurrentThemeCustomTheme
) {
342 sync_pb::ThemeSpecifics theme_specifics
;
343 theme_specifics
.set_use_custom_theme(true);
344 theme_specifics
.set_custom_theme_id(theme_extension_
->id());
345 theme_specifics
.set_custom_theme_name(kCustomThemeName
);
346 theme_specifics
.set_custom_theme_name(kCustomThemeUrl
);
348 // Set up theme service to use default theme.
349 fake_theme_service_
->UseDefaultTheme();
350 syncer::SyncError error
=
352 ->MergeDataAndStartSyncing(
354 MakeThemeDataList(theme_specifics
),
355 scoped_ptr
<syncer::SyncChangeProcessor
>(
356 new syncer::SyncChangeProcessorWrapperForTest(
357 fake_change_processor_
.get())),
358 scoped_ptr
<syncer::SyncErrorFactory
>(
359 new syncer::SyncErrorFactoryMock()))
361 EXPECT_FALSE(error
.IsSet()) << error
.message();
362 EXPECT_EQ(fake_theme_service_
->theme_extension(), theme_extension_
.get());
365 TEST_F(ThemeSyncableServiceTest
, DontResetThemeWhenSpecificsAreEqual
) {
366 // Set up theme service to use default theme and expect no changes.
367 fake_theme_service_
->UseDefaultTheme();
368 fake_theme_service_
->MarkClean();
369 syncer::SyncError error
=
371 ->MergeDataAndStartSyncing(
373 MakeThemeDataList(sync_pb::ThemeSpecifics()),
374 scoped_ptr
<syncer::SyncChangeProcessor
>(
375 new syncer::SyncChangeProcessorWrapperForTest(
376 fake_change_processor_
.get())),
377 scoped_ptr
<syncer::SyncErrorFactory
>(
378 new syncer::SyncErrorFactoryMock()))
380 EXPECT_FALSE(error
.IsSet()) << error
.message();
381 EXPECT_FALSE(fake_theme_service_
->is_dirty());
384 TEST_F(ThemeSyncableServiceTest
, UpdateThemeSpecificsFromCurrentTheme
) {
385 // Set up theme service to use custom theme.
386 fake_theme_service_
->SetTheme(theme_extension_
.get());
388 syncer::SyncError error
=
390 ->MergeDataAndStartSyncing(
392 syncer::SyncDataList(),
393 scoped_ptr
<syncer::SyncChangeProcessor
>(
394 new syncer::SyncChangeProcessorWrapperForTest(
395 fake_change_processor_
.get())),
396 scoped_ptr
<syncer::SyncErrorFactory
>(
397 new syncer::SyncErrorFactoryMock()))
399 EXPECT_FALSE(error
.IsSet()) << error
.message();
400 const syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
401 ASSERT_EQ(1u, changes
.size());
402 EXPECT_TRUE(changes
[0].IsValid());
403 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, changes
[0].change_type());
404 EXPECT_EQ(syncer::THEMES
, changes
[0].sync_data().GetDataType());
406 const sync_pb::ThemeSpecifics
& theme_specifics
=
407 changes
[0].sync_data().GetSpecifics().theme();
408 EXPECT_TRUE(theme_specifics
.use_custom_theme());
409 EXPECT_EQ(theme_extension_
->id(), theme_specifics
.custom_theme_id());
410 EXPECT_EQ(theme_extension_
->name(), theme_specifics
.custom_theme_name());
412 extensions::ManifestURL::GetUpdateURL(theme_extension_
.get()).spec(),
413 theme_specifics
.custom_theme_update_url());
416 TEST_F(ThemeSyncableServiceTest
, GetAllSyncData
) {
417 // Set up theme service to use custom theme.
418 fake_theme_service_
->SetTheme(theme_extension_
.get());
420 syncer::SyncDataList data_list
=
421 theme_sync_service_
->GetAllSyncData(syncer::THEMES
);
423 ASSERT_EQ(1u, data_list
.size());
424 const sync_pb::ThemeSpecifics
& theme_specifics
=
425 data_list
[0].GetSpecifics().theme();
426 EXPECT_TRUE(theme_specifics
.use_custom_theme());
427 EXPECT_EQ(theme_extension_
->id(), theme_specifics
.custom_theme_id());
428 EXPECT_EQ(theme_extension_
->name(), theme_specifics
.custom_theme_name());
430 extensions::ManifestURL::GetUpdateURL(theme_extension_
.get()).spec(),
431 theme_specifics
.custom_theme_update_url());
434 TEST_F(ThemeSyncableServiceTest
, ProcessSyncThemeChange
) {
435 // Set up theme service to use default theme.
436 fake_theme_service_
->UseDefaultTheme();
437 fake_theme_service_
->MarkClean();
440 syncer::SyncError error
=
442 ->MergeDataAndStartSyncing(
444 MakeThemeDataList(sync_pb::ThemeSpecifics()),
445 scoped_ptr
<syncer::SyncChangeProcessor
>(
446 new syncer::SyncChangeProcessorWrapperForTest(
447 fake_change_processor_
.get())),
448 scoped_ptr
<syncer::SyncErrorFactory
>(
449 new syncer::SyncErrorFactoryMock()))
451 EXPECT_FALSE(error
.IsSet()) << error
.message();
452 // Don't expect theme change initially because specifics are equal.
453 EXPECT_FALSE(fake_theme_service_
->is_dirty());
455 // Change specifics to use custom theme and update.
456 sync_pb::ThemeSpecifics theme_specifics
;
457 theme_specifics
.set_use_custom_theme(true);
458 theme_specifics
.set_custom_theme_id(theme_extension_
->id());
459 theme_specifics
.set_custom_theme_name(kCustomThemeName
);
460 theme_specifics
.set_custom_theme_name(kCustomThemeUrl
);
461 sync_pb::EntitySpecifics entity_specifics
;
462 entity_specifics
.mutable_theme()->CopyFrom(theme_specifics
);
463 syncer::SyncChangeList change_list
;
464 change_list
.push_back(
465 syncer::SyncChange(FROM_HERE
,
466 syncer::SyncChange::ACTION_UPDATE
,
467 syncer::SyncData::CreateRemoteData(
471 syncer::AttachmentIdList(),
472 syncer::AttachmentServiceProxyForTest::Create())));
473 error
= theme_sync_service_
->ProcessSyncChanges(FROM_HERE
, change_list
);
474 EXPECT_FALSE(error
.IsSet()) << error
.message();
475 EXPECT_EQ(fake_theme_service_
->theme_extension(), theme_extension_
.get());
478 TEST_F(ThemeSyncableServiceTest
, OnThemeChangeByUser
) {
479 // Set up theme service to use default theme.
480 fake_theme_service_
->UseDefaultTheme();
483 syncer::SyncError error
=
485 ->MergeDataAndStartSyncing(
487 MakeThemeDataList(sync_pb::ThemeSpecifics()),
488 scoped_ptr
<syncer::SyncChangeProcessor
>(
489 new syncer::SyncChangeProcessorWrapperForTest(
490 fake_change_processor_
.get())),
491 scoped_ptr
<syncer::SyncErrorFactory
>(
492 new syncer::SyncErrorFactoryMock()))
494 EXPECT_FALSE(error
.IsSet()) << error
.message();
495 const syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
496 EXPECT_EQ(0u, changes
.size());
498 // Change current theme to custom theme and notify theme_sync_service_.
499 fake_theme_service_
->SetTheme(theme_extension_
.get());
500 theme_sync_service_
->OnThemeChange();
501 EXPECT_EQ(1u, changes
.size());
502 const sync_pb::ThemeSpecifics
& change_specifics
=
503 changes
[0].sync_data().GetSpecifics().theme();
504 EXPECT_TRUE(change_specifics
.use_custom_theme());
505 EXPECT_EQ(theme_extension_
->id(), change_specifics
.custom_theme_id());
506 EXPECT_EQ(theme_extension_
->name(), change_specifics
.custom_theme_name());
508 extensions::ManifestURL::GetUpdateURL(theme_extension_
.get()).spec(),
509 change_specifics
.custom_theme_update_url());
512 TEST_F(ThemeSyncableServiceTest
, StopSync
) {
513 // Set up theme service to use default theme.
514 fake_theme_service_
->UseDefaultTheme();
517 syncer::SyncError error
=
519 ->MergeDataAndStartSyncing(
521 MakeThemeDataList(sync_pb::ThemeSpecifics()),
522 scoped_ptr
<syncer::SyncChangeProcessor
>(
523 new syncer::SyncChangeProcessorWrapperForTest(
524 fake_change_processor_
.get())),
525 scoped_ptr
<syncer::SyncErrorFactory
>(
526 new syncer::SyncErrorFactoryMock()))
528 EXPECT_FALSE(error
.IsSet()) << error
.message();
529 const syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
530 EXPECT_EQ(0u, changes
.size());
533 theme_sync_service_
->StopSyncing(syncer::THEMES
);
535 // Change current theme to custom theme and notify theme_sync_service_.
536 // No change is output because sync has stopped.
537 fake_theme_service_
->SetTheme(theme_extension_
.get());
538 theme_sync_service_
->OnThemeChange();
539 EXPECT_EQ(0u, changes
.size());
541 // ProcessSyncChanges() should return error when sync has stopped.
542 error
= theme_sync_service_
->ProcessSyncChanges(FROM_HERE
, changes
);
543 EXPECT_TRUE(error
.IsSet());
544 EXPECT_EQ(syncer::THEMES
, error
.model_type());
545 EXPECT_EQ("Theme syncable service is not started.", error
.message());
548 TEST_F(ThemeSyncableServiceTest
, RestoreSystemThemeBitWhenChangeToCustomTheme
) {
549 // Initialize to use system theme.
550 fake_theme_service_
->UseDefaultTheme();
551 sync_pb::ThemeSpecifics theme_specifics
;
552 theme_specifics
.set_use_system_theme_by_default(true);
553 syncer::SyncError error
=
555 ->MergeDataAndStartSyncing(
557 MakeThemeDataList(theme_specifics
),
558 scoped_ptr
<syncer::SyncChangeProcessor
>(
559 new syncer::SyncChangeProcessorWrapperForTest(
560 fake_change_processor_
.get())),
561 scoped_ptr
<syncer::SyncErrorFactory
>(
562 new syncer::SyncErrorFactoryMock()))
565 // Change to custom theme and notify theme_sync_service_.
566 // use_system_theme_by_default bit should be preserved.
567 fake_theme_service_
->SetTheme(theme_extension_
.get());
568 theme_sync_service_
->OnThemeChange();
569 const syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
570 EXPECT_EQ(1u, changes
.size());
571 const sync_pb::ThemeSpecifics
& change_specifics
=
572 changes
[0].sync_data().GetSpecifics().theme();
573 EXPECT_TRUE(change_specifics
.use_system_theme_by_default());
576 #if defined(TOOLKIT_GTK)
577 TEST_F(ThemeSyncableServiceTest
,
578 GtkUpdateSystemThemeBitWhenChangeBetweenSystemAndDefault
) {
579 // Initialize to use native theme.
580 fake_theme_service_
->UseSystemTheme();
581 fake_theme_service_
->MarkClean();
582 sync_pb::ThemeSpecifics theme_specifics
;
583 theme_specifics
.set_use_system_theme_by_default(true);
584 syncer::SyncError error
=
586 ->MergeDataAndStartSyncing(
588 MakeThemeDataList(theme_specifics
),
589 scoped_ptr
<syncer::SyncChangeProcessor
>(
590 new syncer::SyncChangeProcessorWrapperForTest(
591 fake_change_processor_
.get())),
592 scoped_ptr
<syncer::SyncErrorFactory
>(
593 new syncer::SyncErrorFactoryMock()))
595 EXPECT_FALSE(fake_theme_service_
->is_dirty());
597 // Change to default theme and notify theme_sync_service_.
598 // use_system_theme_by_default bit should be false.
599 fake_theme_service_
->UseDefaultTheme();
600 theme_sync_service_
->OnThemeChange();
601 syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
602 EXPECT_EQ(1u, changes
.size());
603 EXPECT_FALSE(changes
[0]
607 .use_system_theme_by_default());
609 // Change to native theme and notify theme_sync_service_.
610 // use_system_theme_by_default bit should be true.
612 fake_theme_service_
->UseSystemTheme();
613 theme_sync_service_
->OnThemeChange();
614 EXPECT_EQ(1u, changes
.size());
615 EXPECT_TRUE(changes
[0]
619 .use_system_theme_by_default());
624 TEST_F(ThemeSyncableServiceTest
,
625 NonGtkPreserveSystemThemeBitWhenChangeToDefaultTheme
) {
626 // Set up theme service to use default theme.
627 fake_theme_service_
->UseDefaultTheme();
629 // Initialize to use custom theme with use_system_theme_by_default set true.
630 sync_pb::ThemeSpecifics theme_specifics
;
631 theme_specifics
.set_use_custom_theme(true);
632 theme_specifics
.set_custom_theme_id(theme_extension_
->id());
633 theme_specifics
.set_custom_theme_name(kCustomThemeName
);
634 theme_specifics
.set_custom_theme_name(kCustomThemeUrl
);
635 theme_specifics
.set_use_system_theme_by_default(true);
636 syncer::SyncError error
=
638 ->MergeDataAndStartSyncing(
640 MakeThemeDataList(theme_specifics
),
641 scoped_ptr
<syncer::SyncChangeProcessor
>(
642 new syncer::SyncChangeProcessorWrapperForTest(
643 fake_change_processor_
.get())),
644 scoped_ptr
<syncer::SyncErrorFactory
>(
645 new syncer::SyncErrorFactoryMock()))
647 EXPECT_EQ(fake_theme_service_
->theme_extension(), theme_extension_
.get());
649 // Change to default theme and notify theme_sync_service_.
650 // use_system_theme_by_default bit should be preserved.
651 fake_theme_service_
->UseDefaultTheme();
652 theme_sync_service_
->OnThemeChange();
653 const syncer::SyncChangeList
& changes
= fake_change_processor_
->changes();
654 EXPECT_EQ(1u, changes
.size());
655 const sync_pb::ThemeSpecifics
& change_specifics
=
656 changes
[0].sync_data().GetSpecifics().theme();
657 EXPECT_FALSE(change_specifics
.use_custom_theme());
658 EXPECT_TRUE(change_specifics
.use_system_theme_by_default());
662 TEST_F(PolicyInstalledThemeTest
, InstallThemeByPolicy
) {
663 // Set up theme service to use custom theme that was installed by policy.
664 fake_theme_service_
->SetTheme(theme_extension_
.get());
666 syncer::SyncDataList data_list
=
667 theme_sync_service_
->GetAllSyncData(syncer::THEMES
);
669 ASSERT_EQ(0u, data_list
.size());