Move extension_messages.h to extensions/common.
[chromium-blink-merge.git] / chrome / browser / themes / theme_syncable_service_unittest.cc
blob8f0a2a3f66ca21cd120b92d2e08e9f013a2d0ad5
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/extensions/manifest_url_handler.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "content/public/test/test_browser_thread.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_messages.h"
22 #include "extensions/common/manifest_constants.h"
23 #include "extensions/common/permissions/api_permission_set.h"
24 #include "extensions/common/permissions/permission_set.h"
25 #include "sync/api/fake_sync_change_processor.h"
26 #include "sync/api/sync_change_processor_wrapper_for_test.h"
27 #include "sync/api/sync_error.h"
28 #include "sync/api/sync_error_factory_mock.h"
29 #include "sync/protocol/sync.pb.h"
30 #include "sync/protocol/theme_specifics.pb.h"
31 #include "testing/gtest/include/gtest/gtest.h"
33 #if defined(OS_CHROMEOS)
34 #include "chrome/browser/chromeos/login/user_manager.h"
35 #include "chrome/browser/chromeos/settings/cros_settings.h"
36 #include "chrome/browser/chromeos/settings/device_settings_service.h"
37 #endif
39 using std::string;
41 namespace {
43 static const char kCustomThemeName[] = "name";
44 static const char kCustomThemeUrl[] = "http://update.url/foo";
46 #if defined(OS_WIN)
47 const base::FilePath::CharType kExtensionFilePath[] =
48 FILE_PATH_LITERAL("c:\\foo");
49 #elif defined(OS_POSIX)
50 const base::FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/oo");
51 #endif
53 class FakeThemeService : public ThemeService {
54 public:
55 FakeThemeService() :
56 using_native_theme_(false),
57 using_default_theme_(false),
58 theme_extension_(NULL),
59 is_dirty_(false) {}
61 // ThemeService implementation
62 virtual void SetTheme(const extensions::Extension* extension) OVERRIDE {
63 is_dirty_ = true;
64 theme_extension_ = extension;
65 using_native_theme_ = false;
66 using_default_theme_ = false;
69 virtual void UseDefaultTheme() OVERRIDE {
70 is_dirty_ = true;
71 using_default_theme_ = true;
72 using_native_theme_ = false;
73 theme_extension_ = NULL;
76 virtual void SetNativeTheme() OVERRIDE {
77 is_dirty_ = true;
78 using_native_theme_ = true;
79 using_default_theme_ = false;
80 theme_extension_ = NULL;
83 virtual bool UsingDefaultTheme() const OVERRIDE {
84 return using_default_theme_;
87 virtual bool UsingNativeTheme() const OVERRIDE {
88 return using_native_theme_;
91 virtual string GetThemeID() const OVERRIDE {
92 if (theme_extension_.get())
93 return theme_extension_->id();
94 else
95 return std::string();
98 const extensions::Extension* theme_extension() const {
99 return theme_extension_.get();
102 bool is_dirty() const {
103 return is_dirty_;
106 void MarkClean() {
107 is_dirty_ = false;
110 private:
111 bool using_native_theme_;
112 bool using_default_theme_;
113 scoped_refptr<const extensions::Extension> theme_extension_;
114 bool is_dirty_;
117 BrowserContextKeyedService* BuildMockThemeService(
118 content::BrowserContext* profile) {
119 return new FakeThemeService;
122 scoped_refptr<extensions::Extension> MakeThemeExtension(
123 const base::FilePath& extension_path,
124 const string& name,
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");
132 string error;
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);
139 return extension;
142 } // namespace
144 class ThemeSyncableServiceTest : public testing::Test {
145 protected:
146 ThemeSyncableServiceTest()
147 : ui_thread_(content::BrowserThread::UI, &loop_),
148 file_thread_(content::BrowserThread::FILE, &loop_),
149 fake_theme_service_(NULL) {}
151 virtual ~ThemeSyncableServiceTest() {}
153 virtual void SetUp() {
154 profile_.reset(new TestingProfile);
155 fake_theme_service_ = BuildForProfile(profile_.get());
156 theme_sync_service_.reset(new ThemeSyncableService(profile_.get(),
157 fake_theme_service_));
158 fake_change_processor_.reset(new syncer::FakeSyncChangeProcessor);
159 SetUpExtension();
162 virtual void TearDown() {
163 profile_.reset();
164 loop_.RunUntilIdle();
167 void SetUpExtension() {
168 CommandLine command_line(CommandLine::NO_PROGRAM);
169 extensions::TestExtensionSystem* test_ext_system =
170 static_cast<extensions::TestExtensionSystem*>(
171 extensions::ExtensionSystem::Get(profile_.get()));
172 ExtensionService* service = test_ext_system->CreateExtensionService(
173 &command_line, base::FilePath(kExtensionFilePath), false);
174 EXPECT_TRUE(service->extensions_enabled());
175 service->Init();
176 loop_.RunUntilIdle();
178 // Create and add custom theme extension so the ThemeSyncableService can
179 // find it.
180 theme_extension_ = MakeThemeExtension(base::FilePath(kExtensionFilePath),
181 kCustomThemeName,
182 GetThemeLocation(),
183 kCustomThemeUrl);
184 extensions::APIPermissionSet empty_set;
185 extensions::ManifestPermissionSet empty_manifest_permissions;
186 extensions::URLPatternSet empty_extent;
187 scoped_refptr<extensions::PermissionSet> permissions =
188 new extensions::PermissionSet(empty_set, empty_manifest_permissions,
189 empty_extent, empty_extent);
190 extensions::ExtensionPrefs::Get(profile_.get())
191 ->AddGrantedPermissions(theme_extension_->id(), permissions.get());
192 service->AddExtension(theme_extension_.get());
193 ASSERT_EQ(1u, service->extensions()->size());
196 // Overridden in PolicyInstalledThemeTest below.
197 virtual extensions::Manifest::Location GetThemeLocation() {
198 return extensions::Manifest::INTERNAL;
201 FakeThemeService* BuildForProfile(Profile* profile) {
202 return static_cast<FakeThemeService*>(
203 ThemeServiceFactory::GetInstance()->SetTestingFactoryAndUse(
204 profile, &BuildMockThemeService));
207 syncer::SyncDataList MakeThemeDataList(
208 const sync_pb::ThemeSpecifics& theme_specifics) {
209 syncer::SyncDataList list;
210 sync_pb::EntitySpecifics entity_specifics;
211 entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
212 list.push_back(syncer::SyncData::CreateLocalData(
213 ThemeSyncableService::kCurrentThemeClientTag,
214 ThemeSyncableService::kCurrentThemeNodeTitle,
215 entity_specifics));
216 return list;
219 // Needed for setting up extension service.
220 base::MessageLoop loop_;
221 content::TestBrowserThread ui_thread_;
222 content::TestBrowserThread file_thread_;
224 #if defined OS_CHROMEOS
225 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
226 chromeos::ScopedTestCrosSettings test_cros_settings_;
227 chromeos::ScopedTestUserManager test_user_manager_;
228 #endif
230 scoped_ptr<TestingProfile> profile_;
231 FakeThemeService* fake_theme_service_;
232 scoped_refptr<extensions::Extension> theme_extension_;
233 scoped_ptr<ThemeSyncableService> theme_sync_service_;
234 scoped_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_;
237 class PolicyInstalledThemeTest : public ThemeSyncableServiceTest {
238 virtual extensions::Manifest::Location GetThemeLocation() OVERRIDE {
239 return extensions::Manifest::EXTERNAL_POLICY_DOWNLOAD;
243 TEST_F(ThemeSyncableServiceTest, AreThemeSpecificsEqual) {
244 sync_pb::ThemeSpecifics a, b;
245 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
246 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
248 // Custom vs. non-custom.
250 a.set_use_custom_theme(true);
251 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
252 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
254 // Custom theme equality.
256 b.set_use_custom_theme(true);
257 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
258 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
260 a.set_custom_theme_id("id");
261 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
262 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
264 b.set_custom_theme_id("id");
265 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
266 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
268 a.set_custom_theme_update_url("http://update.url");
269 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
270 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
272 a.set_custom_theme_name("name");
273 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
274 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
276 // Non-custom theme equality.
278 a.set_use_custom_theme(false);
279 b.set_use_custom_theme(false);
280 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
281 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
283 a.set_use_system_theme_by_default(true);
284 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
285 EXPECT_FALSE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
287 b.set_use_system_theme_by_default(true);
288 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, false));
289 EXPECT_TRUE(ThemeSyncableService::AreThemeSpecificsEqual(a, b, true));
292 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeDefaultTheme) {
293 // Set up theme service to use custom theme.
294 fake_theme_service_->SetTheme(theme_extension_.get());
296 syncer::SyncError error =
297 theme_sync_service_
298 ->MergeDataAndStartSyncing(
299 syncer::THEMES,
300 MakeThemeDataList(sync_pb::ThemeSpecifics()),
301 scoped_ptr<syncer::SyncChangeProcessor>(
302 new syncer::SyncChangeProcessorWrapperForTest(
303 fake_change_processor_.get())),
304 scoped_ptr<syncer::SyncErrorFactory>(
305 new syncer::SyncErrorFactoryMock()))
306 .error();
307 EXPECT_FALSE(error.IsSet()) << error.message();
308 EXPECT_TRUE(fake_theme_service_->UsingDefaultTheme());
311 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeSystemTheme) {
312 sync_pb::ThemeSpecifics theme_specifics;
313 theme_specifics.set_use_system_theme_by_default(true);
315 // Set up theme service to use custom theme.
316 fake_theme_service_->SetTheme(theme_extension_.get());
317 syncer::SyncError error =
318 theme_sync_service_
319 ->MergeDataAndStartSyncing(
320 syncer::THEMES,
321 MakeThemeDataList(theme_specifics),
322 scoped_ptr<syncer::SyncChangeProcessor>(
323 new syncer::SyncChangeProcessorWrapperForTest(
324 fake_change_processor_.get())),
325 scoped_ptr<syncer::SyncErrorFactory>(
326 new syncer::SyncErrorFactoryMock()))
327 .error();
328 EXPECT_FALSE(error.IsSet()) << error.message();
329 EXPECT_TRUE(fake_theme_service_->UsingNativeTheme());
332 TEST_F(ThemeSyncableServiceTest, SetCurrentThemeCustomTheme) {
333 sync_pb::ThemeSpecifics theme_specifics;
334 theme_specifics.set_use_custom_theme(true);
335 theme_specifics.set_custom_theme_id(theme_extension_->id());
336 theme_specifics.set_custom_theme_name(kCustomThemeName);
337 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
339 // Set up theme service to use default theme.
340 fake_theme_service_->UseDefaultTheme();
341 syncer::SyncError error =
342 theme_sync_service_
343 ->MergeDataAndStartSyncing(
344 syncer::THEMES,
345 MakeThemeDataList(theme_specifics),
346 scoped_ptr<syncer::SyncChangeProcessor>(
347 new syncer::SyncChangeProcessorWrapperForTest(
348 fake_change_processor_.get())),
349 scoped_ptr<syncer::SyncErrorFactory>(
350 new syncer::SyncErrorFactoryMock()))
351 .error();
352 EXPECT_FALSE(error.IsSet()) << error.message();
353 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
356 TEST_F(ThemeSyncableServiceTest, DontResetThemeWhenSpecificsAreEqual) {
357 // Set up theme service to use default theme and expect no changes.
358 fake_theme_service_->UseDefaultTheme();
359 fake_theme_service_->MarkClean();
360 syncer::SyncError error =
361 theme_sync_service_
362 ->MergeDataAndStartSyncing(
363 syncer::THEMES,
364 MakeThemeDataList(sync_pb::ThemeSpecifics()),
365 scoped_ptr<syncer::SyncChangeProcessor>(
366 new syncer::SyncChangeProcessorWrapperForTest(
367 fake_change_processor_.get())),
368 scoped_ptr<syncer::SyncErrorFactory>(
369 new syncer::SyncErrorFactoryMock()))
370 .error();
371 EXPECT_FALSE(error.IsSet()) << error.message();
372 EXPECT_FALSE(fake_theme_service_->is_dirty());
375 TEST_F(ThemeSyncableServiceTest, UpdateThemeSpecificsFromCurrentTheme) {
376 // Set up theme service to use custom theme.
377 fake_theme_service_->SetTheme(theme_extension_.get());
379 syncer::SyncError error =
380 theme_sync_service_
381 ->MergeDataAndStartSyncing(
382 syncer::THEMES,
383 syncer::SyncDataList(),
384 scoped_ptr<syncer::SyncChangeProcessor>(
385 new syncer::SyncChangeProcessorWrapperForTest(
386 fake_change_processor_.get())),
387 scoped_ptr<syncer::SyncErrorFactory>(
388 new syncer::SyncErrorFactoryMock()))
389 .error();
390 EXPECT_FALSE(error.IsSet()) << error.message();
391 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
392 ASSERT_EQ(1u, changes.size());
393 EXPECT_TRUE(changes[0].IsValid());
394 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
395 EXPECT_EQ(syncer::THEMES, changes[0].sync_data().GetDataType());
397 const sync_pb::ThemeSpecifics& theme_specifics =
398 changes[0].sync_data().GetSpecifics().theme();
399 EXPECT_TRUE(theme_specifics.use_custom_theme());
400 EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
401 EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
402 EXPECT_EQ(
403 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
404 theme_specifics.custom_theme_update_url());
407 TEST_F(ThemeSyncableServiceTest, GetAllSyncData) {
408 // Set up theme service to use custom theme.
409 fake_theme_service_->SetTheme(theme_extension_.get());
411 syncer::SyncDataList data_list =
412 theme_sync_service_->GetAllSyncData(syncer::THEMES);
414 ASSERT_EQ(1u, data_list.size());
415 const sync_pb::ThemeSpecifics& theme_specifics =
416 data_list[0].GetSpecifics().theme();
417 EXPECT_TRUE(theme_specifics.use_custom_theme());
418 EXPECT_EQ(theme_extension_->id(), theme_specifics.custom_theme_id());
419 EXPECT_EQ(theme_extension_->name(), theme_specifics.custom_theme_name());
420 EXPECT_EQ(
421 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
422 theme_specifics.custom_theme_update_url());
425 TEST_F(ThemeSyncableServiceTest, ProcessSyncThemeChange) {
426 // Set up theme service to use default theme.
427 fake_theme_service_->UseDefaultTheme();
428 fake_theme_service_->MarkClean();
430 // Start syncing.
431 syncer::SyncError error =
432 theme_sync_service_
433 ->MergeDataAndStartSyncing(
434 syncer::THEMES,
435 MakeThemeDataList(sync_pb::ThemeSpecifics()),
436 scoped_ptr<syncer::SyncChangeProcessor>(
437 new syncer::SyncChangeProcessorWrapperForTest(
438 fake_change_processor_.get())),
439 scoped_ptr<syncer::SyncErrorFactory>(
440 new syncer::SyncErrorFactoryMock()))
441 .error();
442 EXPECT_FALSE(error.IsSet()) << error.message();
443 // Don't expect theme change initially because specifics are equal.
444 EXPECT_FALSE(fake_theme_service_->is_dirty());
446 // Change specifics to use custom theme and update.
447 sync_pb::ThemeSpecifics theme_specifics;
448 theme_specifics.set_use_custom_theme(true);
449 theme_specifics.set_custom_theme_id(theme_extension_->id());
450 theme_specifics.set_custom_theme_name(kCustomThemeName);
451 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
452 sync_pb::EntitySpecifics entity_specifics;
453 entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
454 syncer::SyncChangeList change_list;
455 change_list.push_back(syncer::SyncChange(
456 FROM_HERE,
457 syncer::SyncChange::ACTION_UPDATE,
458 syncer::SyncData::CreateRemoteData(
459 1, entity_specifics, base::Time())));
460 error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
461 EXPECT_FALSE(error.IsSet()) << error.message();
462 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
465 TEST_F(ThemeSyncableServiceTest, OnThemeChangeByUser) {
466 // Set up theme service to use default theme.
467 fake_theme_service_->UseDefaultTheme();
469 // Start syncing.
470 syncer::SyncError error =
471 theme_sync_service_
472 ->MergeDataAndStartSyncing(
473 syncer::THEMES,
474 MakeThemeDataList(sync_pb::ThemeSpecifics()),
475 scoped_ptr<syncer::SyncChangeProcessor>(
476 new syncer::SyncChangeProcessorWrapperForTest(
477 fake_change_processor_.get())),
478 scoped_ptr<syncer::SyncErrorFactory>(
479 new syncer::SyncErrorFactoryMock()))
480 .error();
481 EXPECT_FALSE(error.IsSet()) << error.message();
482 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
483 EXPECT_EQ(0u, changes.size());
485 // Change current theme to custom theme and notify theme_sync_service_.
486 fake_theme_service_->SetTheme(theme_extension_.get());
487 theme_sync_service_->OnThemeChange();
488 EXPECT_EQ(1u, changes.size());
489 const sync_pb::ThemeSpecifics& change_specifics =
490 changes[0].sync_data().GetSpecifics().theme();
491 EXPECT_TRUE(change_specifics.use_custom_theme());
492 EXPECT_EQ(theme_extension_->id(), change_specifics.custom_theme_id());
493 EXPECT_EQ(theme_extension_->name(), change_specifics.custom_theme_name());
494 EXPECT_EQ(
495 extensions::ManifestURL::GetUpdateURL(theme_extension_.get()).spec(),
496 change_specifics.custom_theme_update_url());
499 TEST_F(ThemeSyncableServiceTest, StopSync) {
500 // Set up theme service to use default theme.
501 fake_theme_service_->UseDefaultTheme();
503 // Start syncing.
504 syncer::SyncError error =
505 theme_sync_service_
506 ->MergeDataAndStartSyncing(
507 syncer::THEMES,
508 MakeThemeDataList(sync_pb::ThemeSpecifics()),
509 scoped_ptr<syncer::SyncChangeProcessor>(
510 new syncer::SyncChangeProcessorWrapperForTest(
511 fake_change_processor_.get())),
512 scoped_ptr<syncer::SyncErrorFactory>(
513 new syncer::SyncErrorFactoryMock()))
514 .error();
515 EXPECT_FALSE(error.IsSet()) << error.message();
516 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
517 EXPECT_EQ(0u, changes.size());
519 // Stop syncing.
520 theme_sync_service_->StopSyncing(syncer::THEMES);
522 // Change current theme to custom theme and notify theme_sync_service_.
523 // No change is output because sync has stopped.
524 fake_theme_service_->SetTheme(theme_extension_.get());
525 theme_sync_service_->OnThemeChange();
526 EXPECT_EQ(0u, changes.size());
528 // ProcessSyncChanges() should return error when sync has stopped.
529 error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, changes);
530 EXPECT_TRUE(error.IsSet());
531 EXPECT_EQ(syncer::THEMES, error.model_type());
532 EXPECT_EQ("datatype error was encountered: Theme syncable service is not "
533 "started.",
534 error.message());
537 TEST_F(ThemeSyncableServiceTest, RestoreSystemThemeBitWhenChangeToCustomTheme) {
538 // Initialize to use system theme.
539 fake_theme_service_->UseDefaultTheme();
540 sync_pb::ThemeSpecifics theme_specifics;
541 theme_specifics.set_use_system_theme_by_default(true);
542 syncer::SyncError error =
543 theme_sync_service_
544 ->MergeDataAndStartSyncing(
545 syncer::THEMES,
546 MakeThemeDataList(theme_specifics),
547 scoped_ptr<syncer::SyncChangeProcessor>(
548 new syncer::SyncChangeProcessorWrapperForTest(
549 fake_change_processor_.get())),
550 scoped_ptr<syncer::SyncErrorFactory>(
551 new syncer::SyncErrorFactoryMock()))
552 .error();
554 // Change to custom theme and notify theme_sync_service_.
555 // use_system_theme_by_default bit should be preserved.
556 fake_theme_service_->SetTheme(theme_extension_.get());
557 theme_sync_service_->OnThemeChange();
558 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
559 EXPECT_EQ(1u, changes.size());
560 const sync_pb::ThemeSpecifics& change_specifics =
561 changes[0].sync_data().GetSpecifics().theme();
562 EXPECT_TRUE(change_specifics.use_system_theme_by_default());
565 #if defined(TOOLKIT_GTK)
566 TEST_F(ThemeSyncableServiceTest,
567 GtkUpdateSystemThemeBitWhenChangeBetweenSystemAndDefault) {
568 // Initialize to use native theme.
569 fake_theme_service_->SetNativeTheme();
570 fake_theme_service_->MarkClean();
571 sync_pb::ThemeSpecifics theme_specifics;
572 theme_specifics.set_use_system_theme_by_default(true);
573 syncer::SyncError error =
574 theme_sync_service_
575 ->MergeDataAndStartSyncing(
576 syncer::THEMES,
577 MakeThemeDataList(theme_specifics),
578 scoped_ptr<syncer::SyncChangeProcessor>(
579 new syncer::SyncChangeProcessorWrapperForTest(
580 fake_change_processor_.get())),
581 scoped_ptr<syncer::SyncErrorFactory>(
582 new syncer::SyncErrorFactoryMock()))
583 .error();
584 EXPECT_FALSE(fake_theme_service_->is_dirty());
586 // Change to default theme and notify theme_sync_service_.
587 // use_system_theme_by_default bit should be false.
588 fake_theme_service_->UseDefaultTheme();
589 theme_sync_service_->OnThemeChange();
590 syncer::SyncChangeList& changes = fake_change_processor_->changes();
591 EXPECT_EQ(1u, changes.size());
592 EXPECT_FALSE(changes[0]
593 .sync_data()
594 .GetSpecifics()
595 .theme()
596 .use_system_theme_by_default());
598 // Change to native theme and notify theme_sync_service_.
599 // use_system_theme_by_default bit should be true.
600 changes.clear();
601 fake_theme_service_->SetNativeTheme();
602 theme_sync_service_->OnThemeChange();
603 EXPECT_EQ(1u, changes.size());
604 EXPECT_TRUE(changes[0]
605 .sync_data()
606 .GetSpecifics()
607 .theme()
608 .use_system_theme_by_default());
610 #endif
612 #ifndef TOOLKIT_GTK
613 TEST_F(ThemeSyncableServiceTest,
614 NonGtkPreserveSystemThemeBitWhenChangeToDefaultTheme) {
615 // Set up theme service to use default theme.
616 fake_theme_service_->UseDefaultTheme();
618 // Initialize to use custom theme with use_system_theme_by_default set true.
619 sync_pb::ThemeSpecifics theme_specifics;
620 theme_specifics.set_use_custom_theme(true);
621 theme_specifics.set_custom_theme_id(theme_extension_->id());
622 theme_specifics.set_custom_theme_name(kCustomThemeName);
623 theme_specifics.set_custom_theme_name(kCustomThemeUrl);
624 theme_specifics.set_use_system_theme_by_default(true);
625 syncer::SyncError error =
626 theme_sync_service_
627 ->MergeDataAndStartSyncing(
628 syncer::THEMES,
629 MakeThemeDataList(theme_specifics),
630 scoped_ptr<syncer::SyncChangeProcessor>(
631 new syncer::SyncChangeProcessorWrapperForTest(
632 fake_change_processor_.get())),
633 scoped_ptr<syncer::SyncErrorFactory>(
634 new syncer::SyncErrorFactoryMock()))
635 .error();
636 EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
638 // Change to default theme and notify theme_sync_service_.
639 // use_system_theme_by_default bit should be preserved.
640 fake_theme_service_->UseDefaultTheme();
641 theme_sync_service_->OnThemeChange();
642 const syncer::SyncChangeList& changes = fake_change_processor_->changes();
643 EXPECT_EQ(1u, changes.size());
644 const sync_pb::ThemeSpecifics& change_specifics =
645 changes[0].sync_data().GetSpecifics().theme();
646 EXPECT_FALSE(change_specifics.use_custom_theme());
647 EXPECT_TRUE(change_specifics.use_system_theme_by_default());
649 #endif
651 TEST_F(PolicyInstalledThemeTest, InstallThemeByPolicy) {
652 // Set up theme service to use custom theme that was installed by policy.
653 fake_theme_service_->SetTheme(theme_extension_.get());
655 syncer::SyncDataList data_list =
656 theme_sync_service_->GetAllSyncData(syncer::THEMES);
658 ASSERT_EQ(0u, data_list.size());