1 // Copyright 2016 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 "ios/chrome/browser/sync/profile_sync_service_factory.h"
6 
7 #include <stddef.h>
8 
9 #include <vector>
10 
11 #include "base/command_line.h"
12 #include "base/task/thread_pool/thread_pool_instance.h"
13 #include "components/browser_sync/browser_sync_switches.h"
14 #include "components/sync/base/model_type.h"
15 #include "components/sync/base/pref_names.h"
16 #include "components/sync/driver/data_type_controller.h"
17 #include "components/sync/driver/profile_sync_service.h"
18 #include "components/sync/driver/sync_driver_switches.h"
19 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
20 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
21 #include "ios/web/public/test/web_task_environment.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h"
24 
25 using syncer::DataTypeController;
26 
27 class ProfileSyncServiceFactoryTest : public PlatformTest {
28  public:
ProfileSyncServiceFactoryTest()29   ProfileSyncServiceFactoryTest() {
30     TestChromeBrowserState::Builder browser_state_builder;
31     // BOOKMARKS requires the FaviconService, which requires the HistoryService.
32     browser_state_builder.AddTestingFactory(
33         ios::FaviconServiceFactory::GetInstance(),
34         ios::FaviconServiceFactory::GetDefaultFactory());
35     chrome_browser_state_ = browser_state_builder.Build();
36     CHECK(chrome_browser_state_->CreateHistoryService());
37   }
38 
SetUp()39   void SetUp() override {
40     // Some services will only be created if there is a WebDataService.
41     chrome_browser_state_->CreateWebDataService();
42   }
43 
TearDown()44   void TearDown() override {
45     base::ThreadPoolInstance::Get()->FlushForTesting();
46   }
47 
48  protected:
49   // Returns the collection of default datatypes.
DefaultDatatypes()50   std::vector<syncer::ModelType> DefaultDatatypes() {
51     static_assert(41 == syncer::ModelType::NUM_ENTRIES,
52                   "When adding a new type, you probably want to add it here as "
53                   "well (assuming it is already enabled).");
54 
55     std::vector<syncer::ModelType> datatypes;
56 
57     // Common types. This excludes PASSWORDS because the password store factory
58     // is null for testing and hence no controller gets instantiated.
59     datatypes.push_back(syncer::AUTOFILL);
60     datatypes.push_back(syncer::AUTOFILL_PROFILE);
61     datatypes.push_back(syncer::AUTOFILL_WALLET_DATA);
62     datatypes.push_back(syncer::AUTOFILL_WALLET_METADATA);
63     datatypes.push_back(syncer::BOOKMARKS);
64     datatypes.push_back(syncer::DEVICE_INFO);
65     datatypes.push_back(syncer::HISTORY_DELETE_DIRECTIVES);
66     datatypes.push_back(syncer::PREFERENCES);
67     datatypes.push_back(syncer::PRIORITY_PREFERENCES);
68     datatypes.push_back(syncer::READING_LIST);
69     // TODO(crbug.com/919489) Add SECURITY_EVENTS data type once it is enabled.
70     datatypes.push_back(syncer::SESSIONS);
71     datatypes.push_back(syncer::PROXY_TABS);
72     datatypes.push_back(syncer::TYPED_URLS);
73     datatypes.push_back(syncer::USER_EVENTS);
74     datatypes.push_back(syncer::USER_CONSENTS);
75     datatypes.push_back(syncer::SEND_TAB_TO_SELF);
76 
77     return datatypes;
78   }
79 
80   // Returns the number of default datatypes.
DefaultDatatypesCount()81   size_t DefaultDatatypesCount() { return DefaultDatatypes().size(); }
82 
83   // Asserts that all the default datatypes are in |types|, except
84   // for |exception_types|, which are asserted to not be in |types|.
CheckDefaultDatatypesInSetExcept(syncer::ModelTypeSet types,syncer::ModelTypeSet exception_types)85   void CheckDefaultDatatypesInSetExcept(syncer::ModelTypeSet types,
86                                         syncer::ModelTypeSet exception_types) {
87     std::vector<syncer::ModelType> defaults = DefaultDatatypes();
88     std::vector<syncer::ModelType>::iterator iter;
89     for (iter = defaults.begin(); iter != defaults.end(); ++iter) {
90       if (exception_types.Has(*iter))
91         EXPECT_FALSE(types.Has(*iter))
92             << *iter << " found in dataypes map, shouldn't be there.";
93       else
94         EXPECT_TRUE(types.Has(*iter)) << *iter << " not found in datatypes map";
95     }
96   }
97 
SetDisabledTypes(syncer::ModelTypeSet disabled_types)98   void SetDisabledTypes(syncer::ModelTypeSet disabled_types) {
99     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
100         switches::kDisableSyncTypes,
101         syncer::ModelTypeSetToString(disabled_types));
102   }
103 
chrome_browser_state()104   ChromeBrowserState* chrome_browser_state() {
105     return chrome_browser_state_.get();
106   }
107 
108  private:
109   web::WebTaskEnvironment task_environment_;
110   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
111 };
112 
113 // Verify that the disable sync flag disables creation of the sync service.
TEST_F(ProfileSyncServiceFactoryTest,DisableSyncFlag)114 TEST_F(ProfileSyncServiceFactoryTest, DisableSyncFlag) {
115   base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
116   EXPECT_FALSE(
117       ProfileSyncServiceFactory::GetForBrowserState(chrome_browser_state()));
118 }
119 
120 // Verify that a normal (no command line flags) PSS can be created and
121 // properly initialized.
TEST_F(ProfileSyncServiceFactoryTest,CreatePSSDefault)122 TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDefault) {
123   syncer::ProfileSyncService* sync_service =
124       ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
125           chrome_browser_state());
126   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
127   EXPECT_EQ(DefaultDatatypesCount(), types.Size());
128   CheckDefaultDatatypesInSetExcept(types, syncer::ModelTypeSet());
129 }
130 
131 // Verify that a PSS with a disabled datatype can be created and properly
132 // initialized.
TEST_F(ProfileSyncServiceFactoryTest,CreatePSSDisableOne)133 TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableOne) {
134   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL);
135   SetDisabledTypes(disabled_types);
136   syncer::ProfileSyncService* sync_service =
137       ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
138           chrome_browser_state());
139   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
140   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
141   CheckDefaultDatatypesInSetExcept(types, disabled_types);
142 }
143 
144 // Verify that a PSS with multiple disabled datatypes can be created and
145 // properly initialized.
TEST_F(ProfileSyncServiceFactoryTest,CreatePSSDisableMultiple)146 TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableMultiple) {
147   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL_PROFILE,
148                                       syncer::BOOKMARKS);
149   SetDisabledTypes(disabled_types);
150   syncer::ProfileSyncService* sync_service =
151       ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
152           chrome_browser_state());
153   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
154   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
155   CheckDefaultDatatypesInSetExcept(types, disabled_types);
156 }
157