OLD | NEW |
| (Empty) |
1 // Copyright 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. | |
4 | |
5 package org.chromium.sync.notifier.signin; | |
6 | |
7 import android.accounts.Account; | |
8 import android.content.Context; | |
9 import android.test.InstrumentationTestCase; | |
10 import android.test.suitebuilder.annotation.SmallTest; | |
11 | |
12 import org.chromium.base.ThreadUtils; | |
13 import org.chromium.base.test.util.Feature; | |
14 import org.chromium.sync.notifier.SyncStatusHelper; | |
15 import org.chromium.sync.notifier.SyncStatusHelper.CachedAccountSyncSettings; | |
16 import org.chromium.sync.notifier.SyncStatusHelper.SyncSettingsChangedObserver; | |
17 import org.chromium.sync.signin.ChromeSigninController; | |
18 import org.chromium.sync.test.util.MockSyncContentResolverDelegate; | |
19 | |
20 public class SyncStatusHelperTest extends InstrumentationTestCase { | |
21 | |
22 private static class CountingMockSyncContentResolverDelegate | |
23 extends MockSyncContentResolverDelegate { | |
24 private int mGetMasterSyncAutomaticallyCalls; | |
25 private int mGetSyncAutomaticallyCalls; | |
26 private int mGetIsSyncableCalls; | |
27 private int mSetIsSyncableCalls; | |
28 private int mSetSyncAutomaticallyCalls; | |
29 | |
30 @Override | |
31 public boolean getMasterSyncAutomatically() { | |
32 mGetMasterSyncAutomaticallyCalls++; | |
33 return super.getMasterSyncAutomatically(); | |
34 } | |
35 | |
36 @Override | |
37 public boolean getSyncAutomatically(Account account, String authority) { | |
38 mGetSyncAutomaticallyCalls++; | |
39 return super.getSyncAutomatically(account, authority); | |
40 } | |
41 | |
42 @Override | |
43 public int getIsSyncable(Account account, String authority) { | |
44 mGetIsSyncableCalls++; | |
45 return super.getIsSyncable(account, authority); | |
46 } | |
47 | |
48 @Override | |
49 public void setIsSyncable(Account account, String authority, int syncabl
e) { | |
50 mSetIsSyncableCalls++; | |
51 super.setIsSyncable(account, authority, syncable); | |
52 } | |
53 | |
54 @Override | |
55 public void setSyncAutomatically(Account account, String authority, bool
ean sync) { | |
56 mSetSyncAutomaticallyCalls++; | |
57 super.setSyncAutomatically(account, authority, sync); | |
58 } | |
59 } | |
60 | |
61 private static class CountingCachedAccountSyncSettings extends CachedAccount
SyncSettings { | |
62 private int mUpdateSyncSettingsForAccountInternalCalls; | |
63 private int mSetIsSyncableInternalCalls; | |
64 private int mSetSyncAutomaticallyInternalCalls; | |
65 | |
66 public CountingCachedAccountSyncSettings(String contractAuthority, | |
67 MockSyncContentResolverDelegate contentResolverWrapper) { | |
68 super(contractAuthority, contentResolverWrapper); | |
69 } | |
70 | |
71 @Override | |
72 protected void updateSyncSettingsForAccountInternal(Account account) { | |
73 mUpdateSyncSettingsForAccountInternalCalls++; | |
74 super.updateSyncSettingsForAccountInternal(account); | |
75 } | |
76 | |
77 @Override | |
78 protected void setIsSyncableInternal(Account account) { | |
79 mSetIsSyncableInternalCalls++; | |
80 super.setIsSyncableInternal(account); | |
81 } | |
82 | |
83 @Override | |
84 protected void setSyncAutomaticallyInternal(Account account, boolean val
ue) { | |
85 mSetSyncAutomaticallyInternalCalls++; | |
86 super.setSyncAutomaticallyInternal(account, value); | |
87 } | |
88 | |
89 public void resetCount() { | |
90 mUpdateSyncSettingsForAccountInternalCalls = 0; | |
91 } | |
92 } | |
93 | |
94 private static class MockSyncSettingsObserver implements SyncSettingsChanged
Observer { | |
95 private boolean mReceivedNotification; | |
96 | |
97 public void clearNotification() { | |
98 mReceivedNotification = false; | |
99 } | |
100 | |
101 public boolean didReceiveNotification() { | |
102 return mReceivedNotification; | |
103 } | |
104 | |
105 @Override | |
106 public void syncSettingsChanged() { | |
107 mReceivedNotification = true; | |
108 } | |
109 } | |
110 | |
111 private SyncStatusHelper mHelper; | |
112 private CountingMockSyncContentResolverDelegate mSyncContentResolverDelegate
; | |
113 private String mAuthority; | |
114 private Account mTestAccount; | |
115 private Account mAlternateTestAccount; | |
116 private CountingCachedAccountSyncSettings mCachedAccountSyncSettings; | |
117 private MockSyncSettingsObserver mSyncSettingsObserver; | |
118 | |
119 @Override | |
120 protected void setUp() throws Exception { | |
121 mSyncContentResolverDelegate = new CountingMockSyncContentResolverDelega
te(); | |
122 Context context = getInstrumentation().getTargetContext(); | |
123 mCachedAccountSyncSettings = new CountingCachedAccountSyncSettings( | |
124 context.getPackageName(), mSyncContentResolverDelegate); | |
125 SyncStatusHelper.overrideSyncStatusHelperForTests( | |
126 context, mSyncContentResolverDelegate, mCachedAccountSyncSetting
s); | |
127 mHelper = SyncStatusHelper.get(getInstrumentation().getTargetContext()); | |
128 // Need to set the signed in account name to ensure that sync settings n
otifications | |
129 // update the right account. | |
130 ChromeSigninController.get( | |
131 getInstrumentation().getTargetContext()).setSignedInAccountName( | |
132 "account@example.com"); | |
133 mAuthority = SyncStatusHelper.get(getInstrumentation().getTargetContext(
)) | |
134 .getContractAuthority(); | |
135 mTestAccount = new Account("account@example.com", "com.google"); | |
136 mAlternateTestAccount = new Account("alternateAccount@example.com", "com
.google"); | |
137 | |
138 mSyncSettingsObserver = new MockSyncSettingsObserver(); | |
139 mHelper.registerSyncSettingsChangedObserver(mSyncSettingsObserver); | |
140 | |
141 super.setUp(); | |
142 } | |
143 | |
144 @SmallTest | |
145 @Feature({"Sync"}) | |
146 public void testToggleMasterSyncAutomaticallyFromSettings() throws Interrupt
edException { | |
147 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
148 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
149 assertTrue("master sync should be set", mHelper.isMasterSyncAutomaticall
yEnabled()); | |
150 | |
151 mSyncContentResolverDelegate.setMasterSyncAutomatically(false); | |
152 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
153 assertFalse("master sync should be unset", mHelper.isMasterSyncAutomatic
allyEnabled()); | |
154 } | |
155 | |
156 @SmallTest | |
157 @Feature({"Sync"}) | |
158 public void testToggleAccountSyncFromSettings() throws InterruptedException
{ | |
159 // Turn on syncability. | |
160 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
161 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
162 | |
163 // First sync | |
164 mSyncContentResolverDelegate.setIsSyncable(mTestAccount, mAuthority, 1); | |
165 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
166 mSyncContentResolverDelegate.setSyncAutomatically(mTestAccount, mAuthori
ty, true); | |
167 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
168 assertTrue("sync should be set", mHelper.isSyncEnabled(mTestAccount)); | |
169 assertTrue("sync should be set for chrome app", | |
170 mHelper.isSyncEnabledForChrome(mTestAccount)); | |
171 | |
172 // Disable sync automatically for the app | |
173 mSyncContentResolverDelegate.setSyncAutomatically(mTestAccount, mAuthori
ty, false); | |
174 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
175 assertFalse("sync should be unset", mHelper.isSyncEnabled(mTestAccount))
; | |
176 assertFalse("sync should be unset for chrome app", | |
177 mHelper.isSyncEnabledForChrome(mTestAccount)); | |
178 | |
179 // Re-enable sync | |
180 mSyncContentResolverDelegate.setSyncAutomatically(mTestAccount, mAuthori
ty, true); | |
181 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
182 assertTrue("sync should be re-enabled", mHelper.isSyncEnabled(mTestAccou
nt)); | |
183 assertTrue("sync should be unset for chrome app", | |
184 mHelper.isSyncEnabledForChrome(mTestAccount)); | |
185 | |
186 // Disabled from master sync | |
187 mSyncContentResolverDelegate.setMasterSyncAutomatically(false); | |
188 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
189 assertFalse("sync should be disabled due to master sync", | |
190 mHelper.isSyncEnabled(mTestAccount)); | |
191 assertTrue("sync should be set for chrome app", | |
192 mHelper.isSyncEnabledForChrome(mTestAccount)); | |
193 } | |
194 | |
195 @SmallTest | |
196 @Feature({"Sync"}) | |
197 public void testToggleAccountSyncFromApplication() throws InterruptedExcepti
on { | |
198 // Turn on syncability. | |
199 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
200 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
201 | |
202 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
203 @Override | |
204 public void run() { | |
205 mHelper.enableAndroidSync(mTestAccount); | |
206 } | |
207 }); | |
208 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
209 assertTrue("account should be synced", mHelper.isSyncEnabled(mTestAccoun
t)); | |
210 | |
211 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
212 @Override | |
213 public void run() { | |
214 mHelper.disableAndroidSync(mTestAccount); | |
215 } | |
216 }); | |
217 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
218 assertFalse("account should not be synced", mHelper.isSyncEnabled(mTestA
ccount)); | |
219 } | |
220 | |
221 @SmallTest | |
222 @Feature({"Sync"}) | |
223 public void testToggleSyncabilityForMultipleAccounts() throws InterruptedExc
eption { | |
224 // Turn on syncability. | |
225 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
226 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
227 | |
228 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
229 @Override | |
230 public void run() { | |
231 mHelper.enableAndroidSync(mTestAccount); | |
232 } | |
233 }); | |
234 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
235 assertTrue("account should be synced", mHelper.isSyncEnabled(mTestAccoun
t)); | |
236 | |
237 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
238 @Override | |
239 public void run() { | |
240 mHelper.enableAndroidSync(mAlternateTestAccount); | |
241 } | |
242 }); | |
243 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
244 assertTrue("alternate account should be synced", | |
245 mHelper.isSyncEnabled(mAlternateTestAccount)); | |
246 | |
247 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
248 @Override | |
249 public void run() { | |
250 mHelper.disableAndroidSync(mAlternateTestAccount); | |
251 } | |
252 }); | |
253 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
254 assertFalse("alternate account should not be synced", | |
255 mHelper.isSyncEnabled(mAlternateTestAccount)); | |
256 assertTrue("account should still be synced", mHelper.isSyncEnabled(mTest
Account)); | |
257 | |
258 // Ensure we don't erroneously re-use cached data. | |
259 assertFalse("null account should not be synced", mHelper.isSyncEnabled(n
ull)); | |
260 } | |
261 | |
262 @SmallTest | |
263 @Feature({"Sync"}) | |
264 public void testSyncSettingsCaching() throws InterruptedException { | |
265 // Turn on syncability. | |
266 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
267 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
268 | |
269 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
270 @Override | |
271 public void run() { | |
272 mHelper.enableAndroidSync(mTestAccount); | |
273 } | |
274 }); | |
275 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
276 assertTrue("account should be synced", mHelper.isSyncEnabled(mTestAccoun
t)); | |
277 | |
278 int masterSyncAutomaticallyCalls = | |
279 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls; | |
280 int isSyncableCalls = mSyncContentResolverDelegate.mGetIsSyncableCalls; | |
281 int getSyncAutomaticallyAcalls = mSyncContentResolverDelegate.mGetSyncAu
tomaticallyCalls; | |
282 | |
283 // Do a bunch of reads. | |
284 mHelper.isMasterSyncAutomaticallyEnabled(); | |
285 mHelper.isSyncEnabled(); | |
286 mHelper.isSyncEnabled(mTestAccount); | |
287 mHelper.isSyncEnabledForChrome(mTestAccount); | |
288 | |
289 // Ensure values were read from cache. | |
290 assertEquals(masterSyncAutomaticallyCalls, | |
291 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls); | |
292 assertEquals(isSyncableCalls, mSyncContentResolverDelegate.mGetIsSyncabl
eCalls); | |
293 assertEquals(getSyncAutomaticallyAcalls, | |
294 mSyncContentResolverDelegate.mGetSyncAutomaticallyCalls); | |
295 | |
296 // Do a bunch of reads for alternate account. | |
297 mHelper.isMasterSyncAutomaticallyEnabled(); | |
298 mHelper.isSyncEnabled(mAlternateTestAccount); | |
299 mHelper.isSyncEnabledForChrome(mAlternateTestAccount); | |
300 | |
301 // Ensure master sync was cached but others are fetched once. | |
302 assertEquals(masterSyncAutomaticallyCalls, | |
303 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls); | |
304 assertEquals(isSyncableCalls + 1, mSyncContentResolverDelegate.mGetIsSyn
cableCalls); | |
305 assertEquals(getSyncAutomaticallyAcalls + 1, | |
306 mSyncContentResolverDelegate.mGetSyncAutomaticallyCalls); | |
307 } | |
308 | |
309 @SmallTest | |
310 @Feature({"Sync"}) | |
311 public void testGetContractAuthority() throws Exception { | |
312 assertEquals("The contract authority should be the package name.", | |
313 getInstrumentation().getTargetContext().getPackageName(), | |
314 mHelper.getContractAuthority()); | |
315 } | |
316 | |
317 @SmallTest | |
318 @Feature({"Sync"}) | |
319 public void testCachedAccountSyncSettingsExitEarly() throws InterruptedExcep
tion { | |
320 mSyncContentResolverDelegate.disableObserverNotifications(); | |
321 | |
322 mCachedAccountSyncSettings.updateSyncSettingsForAccount(null); | |
323 assertTrue("Update sync settings failed to exit early", mCachedAccountSy
ncSettings | |
324 .mUpdateSyncSettingsForAccountInternalCalls == 0); | |
325 | |
326 mCachedAccountSyncSettings.updateSyncSettingsForAccount(mTestAccount); | |
327 assertTrue("Update sync settings should not have exited early", mCachedA
ccountSyncSettings | |
328 .mUpdateSyncSettingsForAccountInternalCalls == 1); | |
329 | |
330 mCachedAccountSyncSettings.setIsSyncable(mTestAccount); | |
331 assertTrue("setIsSyncable should not have exited early", | |
332 mCachedAccountSyncSettings.mSetIsSyncableInternalCalls == 1); | |
333 | |
334 mCachedAccountSyncSettings.setIsSyncable(mTestAccount); | |
335 assertTrue("setIsSyncable failed to exit early", mCachedAccountSyncSetti
ngs | |
336 .mSetIsSyncableInternalCalls == 1); | |
337 | |
338 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, true); | |
339 assertTrue("setSyncAutomatically should not have to exited early", | |
340 mCachedAccountSyncSettings.mSetSyncAutomaticallyInternalCalls ==
1); | |
341 | |
342 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, true); | |
343 assertTrue("setSyncAutomatically failed to exit early", | |
344 mCachedAccountSyncSettings.mSetSyncAutomaticallyInternalCalls ==
1); | |
345 | |
346 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, false); | |
347 assertTrue("setSyncAutomatically should not have to exited early", | |
348 mCachedAccountSyncSettings.mSetSyncAutomaticallyInternalCalls ==
2); | |
349 | |
350 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, false); | |
351 assertTrue("setSyncAutomatically failed to exit early", | |
352 mCachedAccountSyncSettings.mSetSyncAutomaticallyInternalCalls ==
2); | |
353 } | |
354 | |
355 @SmallTest | |
356 @Feature({"Sync"}) | |
357 public void testCachedAccountSyncSettingsDidUpdate() throws InterruptedExcep
tion { | |
358 // Since we're just testing the cache we disable observer notifications
to prevent | |
359 // notifications to SyncStatusHelper from mutating it. | |
360 mSyncContentResolverDelegate.disableObserverNotifications(); | |
361 | |
362 mCachedAccountSyncSettings.clearUpdateStatus(); | |
363 mCachedAccountSyncSettings.getSyncAutomatically(mTestAccount); | |
364 assertTrue("getSyncAutomatically on un-populated cache failed to update
DidUpdate flag", | |
365 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
366 | |
367 mCachedAccountSyncSettings.clearUpdateStatus(); | |
368 mCachedAccountSyncSettings.getSyncAutomatically(mTestAccount); | |
369 assertFalse("getSyncAutomatically on populated cache updated DidUpdate f
lag", | |
370 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
371 | |
372 mCachedAccountSyncSettings.updateSyncSettingsForAccount(mAlternateTestAc
count); | |
373 assertTrue("updateSyncSettingsForAccount failed to update DidUpdate flag
", | |
374 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
375 | |
376 mCachedAccountSyncSettings.clearUpdateStatus(); | |
377 | |
378 mCachedAccountSyncSettings.updateSyncSettingsForAccount(mTestAccount); | |
379 assertTrue("updateSyncSettingsForAccount failed to update DidUpdate flag
", | |
380 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
381 | |
382 mCachedAccountSyncSettings.clearUpdateStatus(); | |
383 | |
384 mCachedAccountSyncSettings.updateSyncSettingsForAccount(mTestAccount); | |
385 assertFalse("updateSyncSettingsForAccount updated DidUpdate flag", | |
386 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
387 | |
388 mCachedAccountSyncSettings.clearUpdateStatus(); | |
389 mCachedAccountSyncSettings.setIsSyncable(mTestAccount); | |
390 assertTrue("setIsSyncable failed to update DidUpdate flag", | |
391 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
392 | |
393 mCachedAccountSyncSettings.clearUpdateStatus(); | |
394 mCachedAccountSyncSettings.setIsSyncable(mTestAccount); | |
395 assertFalse("setIsSyncable updated DidUpdate flag", | |
396 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
397 | |
398 mCachedAccountSyncSettings.clearUpdateStatus(); | |
399 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, true); | |
400 assertTrue("setSyncAutomatically failed to update DidUpdate flag", | |
401 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
402 | |
403 mCachedAccountSyncSettings.clearUpdateStatus(); | |
404 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, true); | |
405 assertFalse("setSyncAutomatically updated DidUpdate flag", | |
406 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
407 | |
408 mCachedAccountSyncSettings.clearUpdateStatus(); | |
409 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, false); | |
410 assertTrue("setSyncAutomatically failed to update DidUpdate flag", | |
411 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
412 | |
413 mCachedAccountSyncSettings.clearUpdateStatus(); | |
414 mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, false); | |
415 assertFalse("setSyncAutomatically updated DidUpdate flag", | |
416 mCachedAccountSyncSettings.getDidUpdateStatus()); | |
417 } | |
418 | |
419 @SmallTest | |
420 @Feature({"Sync"}) | |
421 public void testSyncStatusHelperPostsNotifications() throws InterruptedExcep
tion { | |
422 // Turn on syncability. | |
423 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
424 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
425 | |
426 mSyncSettingsObserver.clearNotification(); | |
427 mHelper.isSyncEnabled(mAlternateTestAccount); | |
428 assertTrue("isSyncEnabled on wrongly populated cache did not trigger obs
ervers", | |
429 mSyncSettingsObserver.didReceiveNotification()); | |
430 | |
431 mSyncSettingsObserver.clearNotification(); | |
432 mHelper.isSyncEnabled(mTestAccount); | |
433 assertTrue("isSyncEnabled on wrongly populated cache did not trigger obs
ervers", | |
434 mSyncSettingsObserver.didReceiveNotification()); | |
435 | |
436 mSyncSettingsObserver.clearNotification(); | |
437 mHelper.enableAndroidSync(mTestAccount); | |
438 assertTrue("enableAndroidSync did not trigger observers", | |
439 mSyncSettingsObserver.didReceiveNotification()); | |
440 | |
441 mSyncSettingsObserver.clearNotification(); | |
442 mHelper.enableAndroidSync(mTestAccount); | |
443 assertFalse("enableAndroidSync triggered observers", | |
444 mSyncSettingsObserver.didReceiveNotification()); | |
445 | |
446 mSyncSettingsObserver.clearNotification(); | |
447 mHelper.disableAndroidSync(mTestAccount); | |
448 assertTrue("disableAndroidSync did not trigger observers", | |
449 mSyncSettingsObserver.didReceiveNotification()); | |
450 | |
451 mSyncSettingsObserver.clearNotification(); | |
452 mHelper.disableAndroidSync(mTestAccount); | |
453 assertFalse("disableAndroidSync triggered observers", | |
454 mSyncSettingsObserver.didReceiveNotification()); | |
455 } | |
456 } | |
OLD | NEW |