EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.sync.notifier]

COVERAGE SUMMARY FOR SOURCE FILE [InvalidationControllerTest.java]

nameclass, %method, %block, %line, %
InvalidationControllerTest.java100% (5/5)96%  (25/26)99%  (627/631)99%  (144/145)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class InvalidationControllerTest$IntentSavingContext100% (1/1)80%  (4/5)89%  (31/35)88%  (7/8)
getPackageManager (): PackageManager 0%   (0/1)0%   (0/4)0%   (0/1)
InvalidationControllerTest$IntentSavingContext (Context): void 100% (1/1)100% (9/9)100% (3/3)
getNumStartedIntents (): int 100% (1/1)100% (4/4)100% (1/1)
getStartedIntent (int): Intent 100% (1/1)100% (6/6)100% (1/1)
startService (Intent): ComponentName 100% (1/1)100% (12/12)100% (2/2)
     
class InvalidationControllerTest100% (1/1)100% (15/15)100% (523/523)100% (127/127)
InvalidationControllerTest (): void 100% (1/1)100% (3/3)100% (2/2)
setUp (): void 100% (1/1)100% (25/25)100% (6/6)
setupSync (boolean): void 100% (1/1)100% (25/25)100% (8/8)
testEnsureConstructorRegistersListener (): void 100% (1/1)100% (24/24)100% (6/6)
testPausingMainActivity (): void 100% (1/1)100% (34/34)100% (9/9)
testPausingMainActivityWithSyncDisabled (): void 100% (1/1)100% (13/13)100% (4/4)
testRefreshShouldReadValuesFromDiskWithAllTypes (): void 100% (1/1)100% (68/68)100% (16/16)
testRefreshShouldReadValuesFromDiskWithSpecificTypes (): void 100% (1/1)100% (89/89)100% (21/21)
testRegisterForAllTypes (): void 100% (1/1)100% (68/68)100% (13/13)
testRegisterForSpecificTypes (): void 100% (1/1)100% (79/79)100% (14/14)
testResumingMainActivity (): void 100% (1/1)100% (23/23)100% (7/7)
testResumingMainActivityWithSyncDisabled (): void 100% (1/1)100% (13/13)100% (4/4)
testStart (): void 100% (1/1)100% (19/19)100% (6/6)
testStop (): void 100% (1/1)100% (30/30)100% (8/8)
validateIntentComponent (Intent): void 100% (1/1)100% (10/10)100% (3/3)
     
class InvalidationControllerTest$1100% (1/1)100% (2/2)100% (15/15)100% (3/3)
InvalidationControllerTest$1 (InvalidationControllerTest, Context, AtomicBool... 100% (1/1)100% (10/10)100% (1/1)
onActivityStateChange (int): void 100% (1/1)100% (5/5)100% (2/2)
     
class InvalidationControllerTest$2100% (1/1)100% (2/2)100% (29/29)100% (5/5)
InvalidationControllerTest$2 (InvalidationControllerTest, Context, AtomicRefe... 100% (1/1)100% (16/16)100% (1/1)
setRegisteredTypes (Account, boolean, Set): void 100% (1/1)100% (13/13)100% (4/4)
     
class InvalidationControllerTest$3100% (1/1)100% (2/2)100% (29/29)100% (5/5)
InvalidationControllerTest$3 (InvalidationControllerTest, Context, AtomicRefe... 100% (1/1)100% (16/16)100% (1/1)
setRegisteredTypes (Account, boolean, Set): void 100% (1/1)100% (13/13)100% (4/4)

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

[all classes][org.chromium.sync.notifier]
EMMA 2.0.5312 (C) Vladimir Roubtsov