1 // Copyright 2018 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 "components/sync/driver/sync_service_utils.h"
6
7 #include "components/sync/base/model_type.h"
8 #include "components/sync/driver/sync_service.h"
9 #include "components/sync/driver/test_sync_service.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace syncer {
13
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledIfSyncNotAllowed)14 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfSyncNotAllowed) {
15 TestSyncService service;
16
17 // If sync is not allowed, uploading should never be enabled, even if all the
18 // data types are enabled.
19 service.SetDisableReasons(
20 syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
21 service.SetTransportState(syncer::SyncService::TransportState::DISABLED);
22
23 service.SetPreferredDataTypes(ProtocolTypes());
24 service.SetActiveDataTypes(ProtocolTypes());
25
26 EXPECT_EQ(UploadState::NOT_ACTIVE,
27 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
28
29 // Once sync gets allowed (e.g. policy is updated), uploading should not be
30 // disabled anymore (though not necessarily active yet).
31 service.SetDisableReasons(SyncService::DisableReasonSet());
32 service.SetTransportState(
33 syncer::SyncService::TransportState::START_DEFERRED);
34
35 EXPECT_NE(UploadState::NOT_ACTIVE,
36 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
37 }
38
TEST(SyncServiceUtilsTest,UploadToGoogleInitializingUntilConfiguredAndActiveAndSyncCycleComplete)39 TEST(SyncServiceUtilsTest,
40 UploadToGoogleInitializingUntilConfiguredAndActiveAndSyncCycleComplete) {
41 TestSyncService service;
42 service.SetDisableReasons(SyncService::DisableReasonSet());
43 service.SetTransportState(
44 syncer::SyncService::TransportState::START_DEFERRED);
45 service.SetPreferredDataTypes(ProtocolTypes());
46 service.SetActiveDataTypes(ProtocolTypes());
47 service.SetEmptyLastCycleSnapshot();
48
49 // By default, if sync isn't disabled, we should be INITIALIZING.
50 EXPECT_EQ(UploadState::INITIALIZING,
51 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
52
53 // Finished configuration is not enough, still INITIALIZING.
54 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
55 EXPECT_EQ(UploadState::INITIALIZING,
56 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
57
58 // Only after a sync cycle has been completed is upload actually ACTIVE.
59 service.SetNonEmptyLastCycleSnapshot();
60 EXPECT_EQ(UploadState::ACTIVE,
61 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
62 }
63
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledForModelType)64 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForModelType) {
65 TestSyncService service;
66 service.SetDisableReasons(SyncService::DisableReasonSet());
67 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
68 service.SetNonEmptyLastCycleSnapshot();
69
70 // Sync is enabled only for a specific model type.
71 service.SetPreferredDataTypes(ModelTypeSet(syncer::BOOKMARKS));
72 service.SetActiveDataTypes(ModelTypeSet(syncer::BOOKMARKS));
73
74 // Sanity check: Upload is ACTIVE for this model type.
75 ASSERT_EQ(UploadState::ACTIVE,
76 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
77
78 // ...but not for other types.
79 EXPECT_EQ(
80 UploadState::NOT_ACTIVE,
81 GetUploadToGoogleState(&service, syncer::HISTORY_DELETE_DIRECTIVES));
82 EXPECT_EQ(UploadState::NOT_ACTIVE,
83 GetUploadToGoogleState(&service, syncer::PREFERENCES));
84 }
85
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledForModelTypeThatFailedToStart)86 TEST(SyncServiceUtilsTest,
87 UploadToGoogleDisabledForModelTypeThatFailedToStart) {
88 TestSyncService service;
89 service.SetDisableReasons(SyncService::DisableReasonSet());
90 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
91 service.SetNonEmptyLastCycleSnapshot();
92
93 // Sync is enabled for some model types.
94 service.SetPreferredDataTypes(
95 ModelTypeSet(syncer::BOOKMARKS, syncer::PREFERENCES));
96 // But one of them fails to actually start up!
97 service.SetActiveDataTypes(ModelTypeSet(syncer::BOOKMARKS));
98
99 // Sanity check: Upload is ACTIVE for the model type that did start up.
100 ASSERT_EQ(UploadState::ACTIVE,
101 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
102
103 // ...but not for the type that failed.
104 EXPECT_EQ(UploadState::NOT_ACTIVE,
105 GetUploadToGoogleState(&service, syncer::PREFERENCES));
106 }
107
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledIfLocalSyncEnabled)108 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfLocalSyncEnabled) {
109 TestSyncService service;
110 service.SetDisableReasons(SyncService::DisableReasonSet());
111 service.SetPreferredDataTypes(ProtocolTypes());
112 service.SetActiveDataTypes(ProtocolTypes());
113 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
114 service.SetNonEmptyLastCycleSnapshot();
115
116 // Sanity check: Upload is active now.
117 ASSERT_EQ(UploadState::ACTIVE,
118 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
119
120 // If we're in "local sync" mode, uploading should never be enabled, even if
121 // configuration is done and all the data types are enabled.
122 service.SetLocalSyncEnabled(true);
123
124 EXPECT_EQ(UploadState::NOT_ACTIVE,
125 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
126 }
127
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledOnPersistentAuthError)128 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledOnPersistentAuthError) {
129 TestSyncService service;
130 service.SetDisableReasons(SyncService::DisableReasonSet());
131 service.SetPreferredDataTypes(ProtocolTypes());
132 service.SetActiveDataTypes(ProtocolTypes());
133 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
134 service.SetNonEmptyLastCycleSnapshot();
135
136 // Sanity check: Upload is active now.
137 ASSERT_EQ(UploadState::ACTIVE,
138 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
139
140 // On a transient error, uploading goes back to INITIALIZING.
141 GoogleServiceAuthError transient_error(
142 GoogleServiceAuthError::CONNECTION_FAILED);
143 ASSERT_TRUE(transient_error.IsTransientError());
144 service.SetAuthError(transient_error);
145
146 EXPECT_EQ(UploadState::INITIALIZING,
147 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
148
149 // On a persistent error, uploading is not considered active anymore (even
150 // though Sync may still be considered active).
151 GoogleServiceAuthError persistent_error(
152 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
153 ASSERT_TRUE(persistent_error.IsPersistentError());
154 service.SetAuthError(persistent_error);
155
156 EXPECT_EQ(UploadState::NOT_ACTIVE,
157 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
158
159 // Once the auth error is resolved (e.g. user re-authenticated), uploading is
160 // active again.
161 service.SetAuthError(GoogleServiceAuthError(GoogleServiceAuthError::NONE));
162 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
163
164 EXPECT_EQ(UploadState::ACTIVE,
165 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
166 }
167
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledIfCustomPassphraseInUse)168 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfCustomPassphraseInUse) {
169 TestSyncService service;
170 service.SetDisableReasons(SyncService::DisableReasonSet());
171 service.SetPreferredDataTypes(ProtocolTypes());
172 service.SetActiveDataTypes(ProtocolTypes());
173 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
174 service.SetNonEmptyLastCycleSnapshot();
175
176 // Sanity check: Upload is ACTIVE, even for data types that are always
177 // encrypted implicitly (PASSWORDS).
178 ASSERT_EQ(UploadState::ACTIVE,
179 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
180 ASSERT_EQ(UploadState::ACTIVE,
181 GetUploadToGoogleState(&service, syncer::PASSWORDS));
182 ASSERT_EQ(UploadState::ACTIVE,
183 GetUploadToGoogleState(&service, syncer::DEVICE_INFO));
184
185 // Once a custom passphrase is in use, upload should be considered disabled:
186 // Even if we're technically still uploading, Google can't inspect the data.
187 service.SetIsUsingSecondaryPassphrase(true);
188
189 EXPECT_EQ(UploadState::NOT_ACTIVE,
190 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
191 EXPECT_EQ(UploadState::NOT_ACTIVE,
192 GetUploadToGoogleState(&service, syncer::PASSWORDS));
193 // But unencryptable types like DEVICE_INFO are still active.
194 EXPECT_EQ(UploadState::ACTIVE,
195 GetUploadToGoogleState(&service, syncer::DEVICE_INFO));
196 }
197
TEST(SyncServiceUtilsTest,UploadToGoogleDisabledForSecondaryAccount)198 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForSecondaryAccount) {
199 TestSyncService service;
200 service.SetDisableReasons(SyncService::DisableReasonSet());
201 service.SetPreferredDataTypes(ProtocolTypes());
202 service.SetActiveDataTypes(ProtocolTypes());
203 service.SetTransportState(syncer::SyncService::TransportState::ACTIVE);
204 service.SetNonEmptyLastCycleSnapshot();
205
206 // Sanity check: Everything's looking good, so upload is considered active.
207 ASSERT_EQ(UploadState::ACTIVE,
208 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
209
210 // Mark the syncing account as non-primary. With this, only Sync-the-transport
211 // (not Sync-the-feature) can run.
212 service.SetIsAuthenticatedAccountPrimary(false);
213 ASSERT_FALSE(service.CanSyncFeatureStart());
214
215 // Upload should NOT be active now. Even though the data type is active, we're
216 // running in standalone transport mode, so we don't have consent for
217 // uploading.
218 EXPECT_EQ(UploadState::NOT_ACTIVE,
219 GetUploadToGoogleState(&service, syncer::BOOKMARKS));
220 }
221
222 } // namespace syncer
223