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