Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / android / javatests / src / org / chromium / chrome / browser / invalidation / InvalidationControllerTest.java
1 // Copyright 2013 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.chrome.browser.invalidation;
6
7 import android.accounts.Account;
8 import android.app.Activity;
9 import android.content.Intent;
10 import android.test.InstrumentationTestCase;
11 import android.test.suitebuilder.annotation.SmallTest;
12
13 import org.chromium.base.ActivityState;
14 import org.chromium.base.ApplicationState;
15 import org.chromium.base.ApplicationStatus;
16 import org.chromium.base.CollectionUtil;
17 import org.chromium.base.test.util.Feature;
18 import org.chromium.components.invalidation.InvalidationClientService;
19 import org.chromium.sync.internal_api.pub.base.ModelType;
20 import org.chromium.sync.notifier.InvalidationIntentProtocol;
21 import org.chromium.sync.notifier.InvalidationPreferences;
22 import org.chromium.sync.notifier.SyncStatusHelper;
23 import org.chromium.sync.signin.AccountManagerHelper;
24 import org.chromium.sync.signin.ChromeSigninController;
25 import org.chromium.sync.test.util.MockSyncContentResolverDelegate;
26
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.concurrent.atomic.AtomicBoolean;
32 import java.util.concurrent.atomic.AtomicReference;
33
34 /**
35  * Tests for the {@link InvalidationController}.
36  */
37 public class InvalidationControllerTest extends InstrumentationTestCase {
38     private IntentSavingContext mContext;
39     private InvalidationController mController;
40
41     @Override
42     protected void setUp() throws Exception {
43         mContext = new IntentSavingContext(getInstrumentation().getTargetContext());
44         mController = InvalidationController.get(mContext);
45         // We don't want to use the system content resolver, so we override it.
46         MockSyncContentResolverDelegate delegate = new MockSyncContentResolverDelegate();
47         // Android master sync can safely always be on.
48         delegate.setMasterSyncAutomatically(true);
49         SyncStatusHelper.overrideSyncStatusHelperForTests(mContext, delegate);
50     }
51
52     @SmallTest
53     @Feature({"Sync"})
54     public void testStart() throws Exception {
55         mController.start();
56         assertEquals(1, mContext.getNumStartedIntents());
57         Intent intent = mContext.getStartedIntent(0);
58         validateIntentComponent(intent);
59     }
60
61     @SmallTest
62     @Feature({"Sync"})
63     public void testStop() throws Exception {
64         mController.stop();
65         assertEquals(1, mContext.getNumStartedIntents());
66         Intent intent = mContext.getStartedIntent(0);
67         validateIntentComponent(intent);
68         assertEquals(1, intent.getExtras().size());
69         assertTrue(intent.hasExtra(InvalidationIntentProtocol.EXTRA_STOP));
70         assertTrue(intent.getBooleanExtra(InvalidationIntentProtocol.EXTRA_STOP, false));
71     }
72
73     @SmallTest
74     @Feature({"Sync"})
75     public void testResumingMainActivity() throws Exception {
76         // Resuming main activity should trigger a start if sync is enabled.
77         setupSync(true);
78         mController.onApplicationStateChange(ApplicationState.HAS_RUNNING_ACTIVITIES);
79         assertEquals(1, mContext.getNumStartedIntents());
80         Intent intent = mContext.getStartedIntent(0);
81         validateIntentComponent(intent);
82     }
83
84     @SmallTest
85     @Feature({"Sync"})
86     public void testResumingMainActivityWithSyncDisabled() throws Exception {
87         // Resuming main activity should NOT trigger a start if sync is disabled.
88         setupSync(false);
89         mController.onApplicationStateChange(ApplicationState.HAS_RUNNING_ACTIVITIES);
90         assertEquals(0, mContext.getNumStartedIntents());
91     }
92
93     @SmallTest
94     @Feature({"Sync"})
95     public void testPausingMainActivity() throws Exception {
96         // Resuming main activity should trigger a stop if sync is enabled.
97         setupSync(true);
98         mController.onApplicationStateChange(ApplicationState.HAS_PAUSED_ACTIVITIES);
99         assertEquals(1, mContext.getNumStartedIntents());
100         Intent intent = mContext.getStartedIntent(0);
101         validateIntentComponent(intent);
102         assertEquals(1, intent.getExtras().size());
103         assertTrue(intent.hasExtra(InvalidationIntentProtocol.EXTRA_STOP));
104         assertTrue(intent.getBooleanExtra(InvalidationIntentProtocol.EXTRA_STOP, false));
105     }
106
107     @SmallTest
108     @Feature({"Sync"})
109     public void testPausingMainActivityWithSyncDisabled() throws Exception {
110         // Resuming main activity should NOT trigger a stop if sync is disabled.
111         setupSync(false);
112         mController.onApplicationStateChange(ApplicationState.HAS_PAUSED_ACTIVITIES);
113         assertEquals(0, mContext.getNumStartedIntents());
114     }
115
116     private void setupSync(boolean syncEnabled) {
117         Account account = AccountManagerHelper.createAccountFromName("test@gmail.com");
118         ChromeSigninController chromeSigninController = ChromeSigninController.get(mContext);
119         chromeSigninController.setSignedInAccountName(account.name);
120         SyncStatusHelper syncStatusHelper = SyncStatusHelper.get(mContext);
121         if (syncEnabled) {
122             syncStatusHelper.enableAndroidSync(account);
123         } else {
124             syncStatusHelper.disableAndroidSync(account);
125         }
126     }
127
128     @SmallTest
129     @Feature({"Sync"})
130     public void testEnsureConstructorRegistersListener() throws Exception {
131         final AtomicBoolean listenerCallbackCalled = new AtomicBoolean();
132
133         // Create instance.
134         new InvalidationController(mContext) {
135             @Override
136             public void onApplicationStateChange(int newState) {
137                 listenerCallbackCalled.set(true);
138             }
139         };
140
141         // Ensure initial state is correct.
142         assertFalse(listenerCallbackCalled.get());
143
144         // Ensure we get a callback, which means we have registered for them.
145         ApplicationStatus.onStateChangeForTesting(new Activity(), ActivityState.CREATED);
146         assertTrue(listenerCallbackCalled.get());
147     }
148
149     @SmallTest
150     @Feature({"Sync"})
151     public void testRegisterForSpecificTypes() {
152         InvalidationController controller = new InvalidationController(mContext);
153         Account account = new Account("test@example.com", "bogus");
154         controller.setRegisteredTypes(account, false,
155                 CollectionUtil.newHashSet(ModelType.BOOKMARK, ModelType.SESSION));
156         assertEquals(1, mContext.getNumStartedIntents());
157
158         // Validate destination.
159         Intent intent = mContext.getStartedIntent(0);
160         validateIntentComponent(intent);
161         assertEquals(InvalidationIntentProtocol.ACTION_REGISTER, intent.getAction());
162
163         // Validate account.
164         Account intentAccount =
165                 intent.getParcelableExtra(InvalidationIntentProtocol.EXTRA_ACCOUNT);
166         assertEquals(account, intentAccount);
167
168         // Validate registered types.
169         Set<String> expectedTypes = CollectionUtil.newHashSet(ModelType.BOOKMARK.name(),
170                 ModelType.SESSION.name());
171         Set<String> actualTypes = new HashSet<String>();
172         actualTypes.addAll(intent.getStringArrayListExtra(
173                                 InvalidationIntentProtocol.EXTRA_REGISTERED_TYPES));
174         assertEquals(expectedTypes, actualTypes);
175         assertNull(InvalidationIntentProtocol.getRegisteredObjectIds(intent));
176     }
177
178     @SmallTest
179     @Feature({"Sync"})
180     public void testRegisterForAllTypes() {
181         Account account = new Account("test@example.com", "bogus");
182         mController.setRegisteredTypes(account, true,
183                 CollectionUtil.newHashSet(ModelType.BOOKMARK, ModelType.SESSION));
184         assertEquals(1, mContext.getNumStartedIntents());
185
186         // Validate destination.
187         Intent intent = mContext.getStartedIntent(0);
188         validateIntentComponent(intent);
189         assertEquals(InvalidationIntentProtocol.ACTION_REGISTER, intent.getAction());
190
191         // Validate account.
192         Account intentAccount =
193                 intent.getParcelableExtra(InvalidationIntentProtocol.EXTRA_ACCOUNT);
194         assertEquals(account, intentAccount);
195
196         // Validate registered types.
197         Set<String> expectedTypes = CollectionUtil.newHashSet(ModelType.ALL_TYPES_TYPE);
198         Set<String> actualTypes = new HashSet<String>();
199         actualTypes.addAll(intent.getStringArrayListExtra(
200                                 InvalidationIntentProtocol.EXTRA_REGISTERED_TYPES));
201         assertEquals(expectedTypes, actualTypes);
202         assertNull(InvalidationIntentProtocol.getRegisteredObjectIds(intent));
203     }
204
205     @SmallTest
206     @Feature({"Sync"})
207     public void testRefreshShouldReadValuesFromDiskWithSpecificTypes() {
208         // Store some preferences for ModelTypes and account. We are using the helper class
209         // for this, so we don't have to deal with low-level details such as preference keys.
210         InvalidationPreferences invalidationPreferences = new InvalidationPreferences(mContext);
211         InvalidationPreferences.EditContext edit = invalidationPreferences.edit();
212         Set<String> storedModelTypes = new HashSet<String>();
213         storedModelTypes.add(ModelType.BOOKMARK.name());
214         storedModelTypes.add(ModelType.TYPED_URL.name());
215         Set<ModelType> refreshedTypes = new HashSet<ModelType>();
216         refreshedTypes.add(ModelType.BOOKMARK);
217         refreshedTypes.add(ModelType.TYPED_URL);
218         invalidationPreferences.setSyncTypes(edit, storedModelTypes);
219         Account storedAccount = AccountManagerHelper.createAccountFromName("test@gmail.com");
220         invalidationPreferences.setAccount(edit, storedAccount);
221         invalidationPreferences.commit(edit);
222
223         // Ensure all calls to {@link InvalidationController#setRegisteredTypes} store values
224         // we can inspect in the test.
225         final AtomicReference<Account> resultAccount = new AtomicReference<Account>();
226         final AtomicBoolean resultAllTypes = new AtomicBoolean();
227         final AtomicReference<Set<ModelType>> resultTypes = new AtomicReference<Set<ModelType>>();
228         InvalidationController controller = new InvalidationController(mContext) {
229             @Override
230             public void setRegisteredTypes(
231                     Account account, boolean allTypes, Set<ModelType> types) {
232                 resultAccount.set(account);
233                 resultAllTypes.set(allTypes);
234                 resultTypes.set(types);
235             }
236         };
237
238         // Execute the test.
239         controller.refreshRegisteredTypes(refreshedTypes);
240
241         // Validate the values.
242         assertEquals(storedAccount, resultAccount.get());
243         assertEquals(false, resultAllTypes.get());
244         assertEquals(ModelType.syncTypesToModelTypes(storedModelTypes), resultTypes.get());
245     }
246
247     @SmallTest
248     @Feature({"Sync"})
249     public void testRefreshShouldReadValuesFromDiskWithAllTypes() {
250         // Store preferences for the ModelType.ALL_TYPES_TYPE and account. We
251         // are using the helper class for this, so we don't have to deal with
252         // low-level details such as preference keys.
253         InvalidationPreferences invalidationPreferences = new InvalidationPreferences(mContext);
254         InvalidationPreferences.EditContext edit = invalidationPreferences.edit();
255         List<String> storedModelTypes = new ArrayList<String>();
256         storedModelTypes.add(ModelType.ALL_TYPES_TYPE);
257         invalidationPreferences.setSyncTypes(edit, storedModelTypes);
258         Account storedAccount = AccountManagerHelper.createAccountFromName("test@gmail.com");
259         invalidationPreferences.setAccount(edit, storedAccount);
260         invalidationPreferences.commit(edit);
261
262         // Ensure all calls to {@link InvalidationController#setRegisteredTypes} store values
263         // we can inspect in the test.
264         final AtomicReference<Account> resultAccount = new AtomicReference<Account>();
265         final AtomicBoolean resultAllTypes = new AtomicBoolean();
266         final AtomicReference<Set<ModelType>> resultTypes = new AtomicReference<Set<ModelType>>();
267         InvalidationController controller = new InvalidationController(mContext) {
268             @Override
269             public void setRegisteredTypes(
270                     Account account, boolean allTypes, Set<ModelType> types) {
271                 resultAccount.set(account);
272                 resultAllTypes.set(allTypes);
273                 resultTypes.set(types);
274             }
275         };
276
277         // Execute the test.
278         controller.refreshRegisteredTypes(new HashSet<ModelType>());
279
280         // Validate the values.
281         assertEquals(storedAccount, resultAccount.get());
282         assertEquals(true, resultAllTypes.get());
283     }
284
285     /**
286      * Asserts that {@code intent} is destined for the correct component.
287      */
288     private static void validateIntentComponent(Intent intent) {
289         assertNotNull(intent.getComponent());
290         assertEquals(InvalidationClientService.class.getName(),
291                 intent.getComponent().getClassName());
292     }
293
294 }