Move manifest_url_handler to //extensions
[chromium-blink-merge.git] / chrome / browser / themes / theme_syncable_service_unittest.cc
blobbbeb1bcffaf0bb855adad90e5922e769f16ab6ce
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/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread.h"
19 #include "extensions/browser/extension_prefs.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/manifest_constants.h"
22 #include "extensions/common/manifest_url_handlers.h"
23 #include "extensions/common/permissions/api_permission_set.h"
24 #include "extensions/common/permissions/permission_set.h"
25 #include "sync/api/attachments/attachment_id.h"
26 #include "sync/api/fake_sync_change_processor.h"
27 #include "sync/api/sync_change_processor_wrapper_for_test.h"
28 #include "sync/api/sync_error.h"
29 #include "sync/api/sync_error_factory_mock.h"
30 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
31 #include "sync/protocol/sync.pb.h"
32 #include "sync/protocol/theme_specifics.pb.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 #if defined(OS_CHROMEOS)
36 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
37 #include "chrome/browser/chromeos/settings/cros_settings.h"
38 #include "chrome/browser/chromeos/settings/device_settings_service.h"
39 #endif
41 using std::string;
43 namespace {
45 static const char kCustomThemeName[] = "name";
46 static const char kCustomThemeUrl[] = "http://update.url/foo";
48 #if defined(OS_WIN)
49 const base::FilePath::CharType kExtensionFilePath[] =
50 FILE_PATH_LITERAL("c:\\foo");
51 #elif defined(OS_POSIX)
52 const base::FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/oo");
53 #endif
55 class FakeThemeService : public ThemeService {
56 public:
57 FakeThemeService() :
58 using_system_theme_(false),
59 using_default_theme_(false),
60 theme_extension_(NULL),
61 is_dirty_(false) {}
63 // ThemeService implementation
64 virtual void SetTheme(const extensions::Extension* extension) override {
65 is_dirty_ = true;
66 theme_extension_ = extension;
67 using_system_theme_ = false;
68 using_default_theme_ = false;
71 virtual void UseDefaultTheme() override {
72 is_dirty_ = true;
73 using_default_theme_ = true;
74 using_system_theme_ = false;
75 theme_extension_ = NULL;
78 virtual void UseSystemTheme() override {
79 is_dirty_ = true;
80 using_system_theme_ = true;
81 using_default_theme_ = false;
82 theme_extension_ = NULL;
85 virtual bool UsingDefaultTheme() const override {
86 return using_default_theme_;
89 virtual bool UsingSystemTheme() const override {
90 return using_system_theme_;
93 virtual string GetThemeID() const override {
94 if (theme_extension_.get())
95 return theme_extension_->id();
96 else
97 return std::string();
100 const extensions::Extension* theme_extension() const {
101 return theme_extension_.get();
104 bool is_dirty() const {
105 return is_dirty_;
108 void MarkClean() {
109 is_dirty_ = false;
112 private:
113 bool using_system_theme_;
114 bool using_default_theme_;
115 scoped_refptr<const extensions::Extension> theme_extension_;
116 bool is_dirty_;
119 KeyedService* BuildMockThemeService(content::BrowserContext* profile) {
120 return new FakeThemeService;
123 scoped_refptr<extensions::Extension> MakeThemeExtension(
124 const base::FilePath& extension_path,
125 const string& name,
126 extensions::Manifest::Location location,
127 const string& update_url) {
128 base::DictionaryValue source;
129 source.SetString(extensions::manifest_keys::kName, name);
130 source.Set(extensions::manifest_keys::kTheme, new base::DictionaryValue());
131 source.SetString(extensions::manifest_keys::kUpdateURL, update_url);
132 source.SetString(extensions::manifest_keys::kVersion, "0.0.0.0");
133 string error;
134 scoped_refptr<extensions::Extension> extension =
135 extensions::Extension::Create(
136 extension_path, location, source,
137 extensions::Extension::NO_FLAGS, &error);
138 EXPECT_TRUE(extension.get());
139 EXPECT_EQ("", error);
140 return extension;
143 } // namespace
145 class ThemeSyncableServiceTest : public testing::Test {
146 protected:
147 ThemeSyncableServiceTest()
148 : ui_thread_(content::BrowserThread::UI, &loop_),
149 file_thread_(content::BrowserThread::FILE, &loop_),
150 fake_theme_service_(NULL) {}
152 virtual ~ThemeSyncableServiceTest() {}
154 virtual void SetUp() {
155 profile_.reset(new TestingProfile);
156 fake_theme_service_ = BuildForProfile(profile_.get());
157 theme_sync_service_.reset(new ThemeSyncableService(profile_.get(),
158 fake_theme_service_));
159 fake_change_processor_.reset(new syncer::FakeSyncChangeProcessor);
160 SetUpExtension();
163 virtual void TearDown() {
164 profile_.reset();
165 loop_.RunUntilIdle();
168 void SetUpExtension() {
169 CommandLine command_line(CommandLine::NO_PROGRAM);
170 extensions::TestExtensionSystem* test_ext_system =
171 static_cast<extensions::TestExtensionSystem*>(
172 extensions::ExtensionSystem::Get(profile_.get()));
173 ExtensionService* service = test_ext_system->CreateExtensionService(
174 &command_line, base::FilePath(kExtensionFilePath), false);
175 EXPECT_TRUE(service->extensions_enabled());
176 service->Init();
177 loop_.RunUntilIdle();
179 // Create and add custom theme extension so the ThemeSyncableService can
180 // find it.
181 theme_extension_ = MakeThemeExtension(base::FilePath(kExtensionFilePath),
182 kCustomThemeName,
183 GetThemeLocation(),
184 kCustomThemeUrl);
185 extensions::APIPermissionSet empty_set;
186 extensions::ManifestPermissionSet empty_manifest_permissions;
187 extensions::URLPatternSet empty_extent;
188 scoped_refptr<extensions::PermissionSet> permissions =
189 new extensions::PermissionSet(empty_set, empty_manifest_permissions,
190 empty_extent, empty_extent);
191 extensions::ExtensionPrefs::Get(profile_.get())
192 ->AddGrantedPermissions(theme_extension_->id(), permissions.get());
193 service->AddExtension(theme_extension_.get());
194 ASSERT_EQ(1u, service->extensions()->size());
197 // Overridden in PolicyInstalledThemeTest below.
198 virtual extensions::Manifest::Location GetThemeLocation() {
199 return extensions::Manifest::INTERNAL;
202 FakeThemeService* BuildForProfile(Profile* profile) {
203 return static_cast<FakeThemeService*>(
204 ThemeServiceFactory::GetInstance()->SetTestingFactoryAndUse(
205 profile, &BuildMockThemeService));
208 syncer::SyncDataList MakeThemeDataList(
209 const sync_pb::ThemeSpecifics& theme_specifics) {
210 syncer::SyncDataList list;
211 sync_pb::EntitySpecifics entity_specifics;
212 entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
213 list.push_back(syncer::SyncData::CreateLocalData(
214 ThemeSyncableService::kCurrentThemeClientTag,
215 ThemeSyncableService::kCurrentThemeNodeTitle,
216 entity_specifics));
217 return list;
220 // Needed for setting up extension service.
221 base::MessageLoop loop_;
222 content::TestBrowserThread ui_thread_;
223 content::TestBrowserThread file_thread_;
225 #if defined OS_CHROMEOS
226 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
227 chromeos::ScopedTestCrosSettings test_cros_settings_;
228 chromeos::ScopedTestUserManager test_user_manager_;
229 #endif
231 scoped_ptr<TestingProfile> profile_;
232 FakeThemeService* fake_theme_service_;
233 scoped_refptr<extensions::Extension> theme_extension_;
234 scoped_ptr<ThemeSyncableService> theme_sync_service_;
235 scoped_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_;
238 class PolicyInstalledThemeTest : public ThemeSyncableServiceTest {
239 virtual extensions::Manifest::Location GetThemeLocation() override {
240 return extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD;
244 TEST_F(ThemeSyncableServiceTest, AreThemeSpecificsEqual) {
245 sync_pb::ThemeSpecifics a, b;
246 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
247 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
249 // Custom vs. non-custom.
251 a.set_use_custom_theme(true);
252 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
253 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
255 // Custom theme equality.
257 b.set_use_custom_theme(true);
258 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
259 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
261 a.set_custom_theme_id("id");
262 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
263 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
265 b.set_custom_theme_id("id");
266 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
267 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
269 a.set_custom_theme_update_url("http://update.url");
270 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
271 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
273 a.set_custom_theme_name("name");
274 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
275 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
277 // Non-custom theme equality.
279 a.set_use_custom_theme(false);
280 b.set_use_custom_theme(false);
281 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
282 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
284 a.set_use_system_theme_by_default(true);
285 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
286 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
288 b.set_use_system_theme_by_default(true);
289 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
290 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
293 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeDefaultTheme) {
294 // Set up theme service to use custom theme.
295 fake_theme_service_->SetTheme(theme_extension_.get());
297 syncer::SyncError error =
298 theme_sync_service_
299 ->MergeDataAndStartSyncing(
300 syncer::THEMES,
301 MakeThemeDataList(sync_pb::ThemeSpecifics()),
302 scoped_ptr<syncer::SyncChangeProcessor>(
303 new syncer::SyncChangeProcessorWrapperForTest(
304 fake_change_processor_.get())),
305 scoped_ptr<syncer::SyncErrorFactory>(
306 new syncer::SyncErrorFactoryMock()))
307 .error();
308 EXPECT_FALSE(error.IsSet()) << error.message();
309 EXPECT_TRUE(fake_theme_service_->UsingDefaultTheme());
312 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeSystemTheme) {
313 sync_pb::ThemeSpecifics theme_specifics;
314 theme_specifics.set_use_system_theme_by_default(true);
316 // Set up theme service to use custom theme.
317 fake_theme_service_->SetTheme(theme_extension_.get());
318 syncer::SyncError error =
319 theme_sync_service_
320 ->MergeDataAndStartSyncing(
321 syncer::THEMES,
322 MakeThemeDataList(theme_specifics),
323 scoped_ptr<syncer::SyncChangeProcessor>(
324 new syncer::SyncChangeProcessorWrapperForTest(
325 fake_change_processor_.get())),
326 scoped_ptr<syncer::SyncErrorFactory>(
327 new syncer::SyncErrorFactoryMock()))
328 .error();
329 EXPECT_FALSE(error.IsSet()) << error.message();
330 EXPECT_TRUE(fake_theme_service_->UsingSystemTheme());
333 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeCustomTheme) {
334 sync_pb::ThemeSpecifics theme_specifics;
335 theme_specifics.set_use_custom_theme(true);
336 theme_specifics.set_custom_theme_id(theme_extension_->id());
337 theme_specifics.set_custom_theme_name(kCustomThemeName);
338 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
340 // Set up theme service to use default theme.
341 fake_theme_service_->UseDefaultTheme();
342 syncer::SyncError error =
343 theme_sync_service_
344 ->MergeDataAndStartSyncing(
345 syncer::THEMES,
346 MakeThemeDataList(theme_specifics),
347 scoped_ptr<syncer::SyncChangeProcessor>(
348 new syncer::SyncChangeProcessorWrapperForTest(
349 fake_change_processor_.get())),
350 scoped_ptr<syncer::SyncErrorFactory>(
351 new syncer::SyncErrorFactoryMock()))
352 .error();
353 EXPECT_FALSE(error.IsSet()) << error.message();
354 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
357 TEST_F(ThemeSyncableServiceTest, DontResetThemeWhenSpecificsAreEqual) {
358 // Set up theme service to use default theme and expect no changes.
359 fake_theme_service_->UseDefaultTheme();
360 fake_theme_service_->MarkClean();
361 syncer::SyncError error =
362 theme_sync_service_
363 ->MergeDataAndStartSyncing(
364 syncer::THEMES,
365 MakeThemeDataList(sync_pb::ThemeSpecifics()),
366 scoped_ptr<syncer::SyncChangeProcessor>(
367 new syncer::SyncChangeProcessorWrapperForTest(
368 fake_change_processor_.get())),
369 scoped_ptr<syncer::SyncErrorFactory>(
370 new syncer::SyncErrorFactoryMock()))
371 .error();
372 EXPECT_FALSE(error.IsSet()) << error.message();
373 EXPECT_FALSE(fake_theme_service_->is_dirty());
376 TEST_F(ThemeSyncableServiceTest, UpdateThemeSpecificsFromCurrentTheme) {
377 // Set up theme service to use custom theme.
378 fake_theme_service_->SetTheme(theme_extension_.get());
380 syncer::SyncError error =
381 theme_sync_service_
382 ->MergeDataAndStartSyncing(
383 syncer::THEMES,
384 syncer::SyncDataList(),
385 scoped_ptr<syncer::SyncChangeProcessor>(
386 new syncer::SyncChangeProcessorWrapperForTest(
387 fake_change_processor_.get())),
388 scoped_ptr<syncer::SyncErrorFactory>(
389 new syncer::SyncErrorFactoryMock()))
390 .error();
391 EXPECT_FALSE(error.IsSet()) << error.message();
392 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
393 ASSERT_EQ(1u, changes.size());
394 EXPECT_TRUE(changes[0].IsValid());
395 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
396 EXPECT_EQ(syncer::THEMES, changes[0].sync_data().GetDataType());
398 const sync_pb::ThemeSpecifics& theme_specifics =
399 changes[0].sync_data().GetSpecifics().theme();
400 EXPECT_TRUE(theme_specifics.use_custom_theme());
401 EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
402 EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
403 EXPECT_EQ(
404 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
405 theme_specifics.custom_theme_update_url());
408 TEST_F(ThemeSyncableServiceTest, GetAllSyncData) {
409 // Set up theme service to use custom theme.
410 fake_theme_service_->SetTheme(theme_extension_.get());
412 syncer::SyncDataList data_list =
413 theme_sync_service_->GetAllSyncData(syncer::THEMES);
415 ASSERT_EQ(1u, data_list.size());
416 const sync_pb::ThemeSpecifics& theme_specifics =
417 data_list[0].GetSpecifics().theme();
418 EXPECT_TRUE(theme_specifics.use_custom_theme());
419 EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
420 EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
421 EXPECT_EQ(
422 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
423 theme_specifics.custom_theme_update_url());
426 TEST_F(ThemeSyncableServiceTest, ProcessSyncThemeChange) {
427 // Set up theme service to use default theme.
428 fake_theme_service_->UseDefaultTheme();
429 fake_theme_service_->MarkClean();
431 // Start syncing.
432 syncer::SyncError error =
433 theme_sync_service_
434 ->MergeDataAndStartSyncing(
435 syncer::THEMES,
436 MakeThemeDataList(sync_pb::ThemeSpecifics()),
437 scoped_ptr<syncer::SyncChangeProcessor>(
438 new syncer::SyncChangeProcessorWrapperForTest(
439 fake_change_processor_.get())),
440 scoped_ptr<syncer::SyncErrorFactory>(
441 new syncer::SyncErrorFactoryMock()))
442 .error();
443 EXPECT_FALSE(error.IsSet()) << error.message();
444 // Don't expect theme change initially because specifics are equal.
445 EXPECT_FALSE(fake_theme_service_->is_dirty());
447 // Change specifics to use custom theme and update.
448 sync_pb::ThemeSpecifics theme_specifics;
449 theme_specifics.set_use_custom_theme(true);
450 theme_specifics.set_custom_theme_id(theme_extension_->id());
451 theme_specifics.set_custom_theme_name(kCustomThemeName);
452 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
453 sync_pb::EntitySpecifics entity_specifics;
454 entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
455 syncer::SyncChangeList change_list;
456 change_list.push_back(
457 syncer::SyncChange(FROM_HERE,
458 syncer::SyncChange::ACTION_UPDATE,
459 syncer::SyncData::CreateRemoteData(
461 entity_specifics,
462 base::Time(),
463 syncer::AttachmentIdList(),
464 syncer::AttachmentServiceProxyForTest::Create())));
465 error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
466 EXPECT_FALSE(error.IsSet()) << error.message();
467 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
470 TEST_F(ThemeSyncableServiceTest, OnThemeChangeByUser) {
471 // Set up theme service to use default theme.
472 fake_theme_service_->UseDefaultTheme();
474 // Start syncing.
475 syncer::SyncError error =
476 theme_sync_service_
477 ->MergeDataAndStartSyncing(
478 syncer::THEMES,
479 MakeThemeDataList(sync_pb::ThemeSpecifics()),
480 scoped_ptr<syncer::SyncChangeProcessor>(
481 new syncer::SyncChangeProcessorWrapperForTest(
482 fake_change_processor_.get())),
483 scoped_ptr<syncer::SyncErrorFactory>(
484 new syncer::SyncErrorFactoryMock()))
485 .error();
486 EXPECT_FALSE(error.IsSet()) << error.message();
487 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
488 EXPECT_EQ(0u, changes.size());
490 // Change current theme to custom theme and notify theme_sync_service_.
491 fake_theme_service_->SetTheme(theme_extension_.get());
492 theme_sync_service_->OnThemeChange();
493 EXPECT_EQ(1u, changes.size());
494 const sync_pb::ThemeSpecifics& change_specifics =
495 changes[0].sync_data().GetSpecifics().theme();
496 EXPECT_TRUE(change_specifics.use_custom_theme());
497 EXPECT_EQ(theme_extension_->id(), change_specifics.custom_theme_id());
498 EXPECT_EQ(theme_extension_->name(), change_specifics.custom_theme_name());
499 EXPECT_EQ(
500 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
501 change_specifics.custom_theme_update_url());
504 TEST_F(ThemeSyncableServiceTest, StopSync) {
505 // Set up theme service to use default theme.
506 fake_theme_service_->UseDefaultTheme();
508 // Start syncing.
509 syncer::SyncError error =
510 theme_sync_service_
511 ->MergeDataAndStartSyncing(
512 syncer::THEMES,
513 MakeThemeDataList(sync_pb::ThemeSpecifics()),
514 scoped_ptr<syncer::SyncChangeProcessor>(
515 new syncer::SyncChangeProcessorWrapperForTest(
516 fake_change_processor_.get())),
517 scoped_ptr<syncer::SyncErrorFactory>(
518 new syncer::SyncErrorFactoryMock()))
519 .error();
520 EXPECT_FALSE(error.IsSet()) << error.message();
521 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
522 EXPECT_EQ(0u, changes.size());
524 // Stop syncing.
525 theme_sync_service_->StopSyncing(syncer::THEMES);
527 // Change current theme to custom theme and notify theme_sync_service_.
528 // No change is output because sync has stopped.
529 fake_theme_service_->SetTheme(theme_extension_.get());
530 theme_sync_service_->OnThemeChange();
531 EXPECT_EQ(0u, changes.size());
533 // ProcessSyncChanges() should return error when sync has stopped.
534 error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, changes);
535 EXPECT_TRUE(error.IsSet());
536 EXPECT_EQ(syncer::THEMES, error.model_type());
537 EXPECT_EQ("Theme syncable service is not started.", error.message());
540 TEST_F(ThemeSyncableServiceTest, RestoreSystemThemeBitWhenChangeToCustomTheme) {
541 // Initialize to use system theme.
542 fake_theme_service_->UseDefaultTheme();
543 sync_pb::ThemeSpecifics theme_specifics;
544 theme_specifics.set_use_system_theme_by_default(true);
545 syncer::SyncError error =
546 theme_sync_service_
547 ->MergeDataAndStartSyncing(
548 syncer::THEMES,
549 MakeThemeDataList(theme_specifics),
550 scoped_ptr<syncer::SyncChangeProcessor>(
551 new syncer::SyncChangeProcessorWrapperForTest(
552 fake_change_processor_.get())),
553 scoped_ptr<syncer::SyncErrorFactory>(
554 new syncer::SyncErrorFactoryMock()))
555 .error();
557 // Change to custom theme and notify theme_sync_service_.
558 // use_system_theme_by_default bit should be preserved.
559 fake_theme_service_->SetTheme(theme_extension_.get());
560 theme_sync_service_->OnThemeChange();
561 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
562 EXPECT_EQ(1u, changes.size());
563 const sync_pb::ThemeSpecifics& change_specifics =
564 changes[0].sync_data().GetSpecifics().theme();
565 EXPECT_TRUE(change_specifics.use_system_theme_by_default());
568 #if defined(TOOLKIT_GTK)
569 TEST_F(ThemeSyncableServiceTest,
570 GtkUpdateSystemThemeBitWhenChangeBetweenSystemAndDefault) {
571 // Initialize to use native theme.
572 fake_theme_service_->UseSystemTheme();
573 fake_theme_service_->MarkClean();
574 sync_pb::ThemeSpecifics theme_specifics;
575 theme_specifics.set_use_system_theme_by_default(true);
576 syncer::SyncError error =
577 theme_sync_service_
578 ->MergeDataAndStartSyncing(
579 syncer::THEMES,
580 MakeThemeDataList(theme_specifics),
581 scoped_ptr<syncer::SyncChangeProcessor>(
582 new syncer::SyncChangeProcessorWrapperForTest(
583 fake_change_processor_.get())),
584 scoped_ptr<syncer::SyncErrorFactory>(
585 new syncer::SyncErrorFactoryMock()))
586 .error();
587 EXPECT_FALSE(fake_theme_service_->is_dirty());
589 // Change to default theme and notify theme_sync_service_.
590 // use_system_theme_by_default bit should be false.
591 fake_theme_service_->UseDefaultTheme();
592 theme_sync_service_->OnThemeChange();
593 syncer::SyncChangeList& changes = fake_change_processor_->changes();
594 EXPECT_EQ(1u, changes.size());
595 EXPECT_FALSE(changes[0]
596 .sync_data()
597 .GetSpecifics()
598 .theme()
599 .use_system_theme_by_default());
601 // Change to native theme and notify theme_sync_service_.
602 // use_system_theme_by_default bit should be true.
603 changes.clear();
604 fake_theme_service_->UseSystemTheme();
605 theme_sync_service_->OnThemeChange();
606 EXPECT_EQ(1u, changes.size());
607 EXPECT_TRUE(changes[0]
608 .sync_data()
609 .GetSpecifics()
610 .theme()
611 .use_system_theme_by_default());
613 #endif
615 #ifndef TOOLKIT_GTK
616 TEST_F(ThemeSyncableServiceTest,
617 NonGtkPreserveSystemThemeBitWhenChangeToDefaultTheme) {
618 // Set up theme service to use default theme.
619 fake_theme_service_->UseDefaultTheme();
621 // Initialize to use custom theme with use_system_theme_by_default set true.
622 sync_pb::ThemeSpecifics theme_specifics;
623 theme_specifics.set_use_custom_theme(true);
624 theme_specifics.set_custom_theme_id(theme_extension_->id());
625 theme_specifics.set_custom_theme_name(kCustomThemeName);
626 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
627 theme_specifics.set_use_system_theme_by_default(true);
628 syncer::SyncError error =
629 theme_sync_service_
630 ->MergeDataAndStartSyncing(
631 syncer::THEMES,
632 MakeThemeDataList(theme_specifics),
633 scoped_ptr<syncer::SyncChangeProcessor>(
634 new syncer::SyncChangeProcessorWrapperForTest(
635 fake_change_processor_.get())),
636 scoped_ptr<syncer::SyncErrorFactory>(
637 new syncer::SyncErrorFactoryMock()))
638 .error();
639 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
641 // Change to default theme and notify theme_sync_service_.
642 // use_system_theme_by_default bit should be preserved.
643 fake_theme_service_->UseDefaultTheme();
644 theme_sync_service_->OnThemeChange();
645 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
646 EXPECT_EQ(1u, changes.size());
647 const sync_pb::ThemeSpecifics& change_specifics =
648 changes[0].sync_data().GetSpecifics().theme();
649 EXPECT_FALSE(change_specifics.use_custom_theme());
650 EXPECT_TRUE(change_specifics.use_system_theme_by_default());
652 #endif
654 TEST_F(PolicyInstalledThemeTest, InstallThemeByPolicy) {
655 // Set up theme service to use custom theme that was installed by policy.
656 fake_theme_service_->SetTheme(theme_extension_.get());
658 syncer::SyncDataList data_list =
659 theme_sync_service_->GetAllSyncData(syncer::THEMES);
661 ASSERT_EQ(0u, data_list.size());