• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.email;
18 
19 import com.android.email.provider.EmailContent;
20 import com.android.email.provider.EmailProvider;
21 import com.android.email.provider.ProviderTestUtils;
22 
23 import android.content.Context;
24 import android.database.Cursor;
25 import android.test.ProviderTestCase2;
26 import android.test.suitebuilder.annotation.MediumTest;
27 
28 /**
29  * This is a series of unit tests for backup/restore of the Account class.
30  *
31  * Technically these are functional because they use the underlying preferences framework.
32  *
33  * NOTE:  These tests are destructive of any "legacy" accounts that might be lying around.
34  */
35 @MediumTest
36 public class AccountBackupRestoreTests extends ProviderTestCase2<EmailProvider> {
37 
38     private Preferences mPreferences;
39     private Context mMockContext;
40 
AccountBackupRestoreTests()41     public AccountBackupRestoreTests() {
42         super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY);
43     }
44 
45     @Override
setUp()46     protected void setUp() throws Exception {
47         super.setUp();
48 
49         mMockContext = getMockContext();
50         // Note: preferences are not supported by this mock context, so we must
51         // explicitly use (and clean out) the real ones for now.
52         mPreferences = Preferences.getPreferences(mContext);
53     }
54 
55     /**
56      * Delete any dummy accounts we set up for this test
57      */
58     @Override
tearDown()59     protected void tearDown() throws Exception {
60         super.tearDown();
61         deleteLegacyAccounts();
62     }
63 
64     /**
65      * Delete *all* legacy accounts
66      */
deleteLegacyAccounts()67     private void deleteLegacyAccounts() {
68         Account[] oldAccounts = mPreferences.getAccounts();
69         for (Account oldAccount : oldAccounts) {
70             oldAccount.delete(mPreferences);
71         }
72     }
73 
74     /**
75      * Test backup with no accounts
76      */
testNoAccountBackup()77     public void testNoAccountBackup() {
78         // create some "old" backups or legacy accounts
79         Account backupAccount = new Account(mMockContext);
80         backupAccount.save(mPreferences);
81         // confirm they are there
82         Account[] oldBackups = mPreferences.getAccounts();
83         assertTrue(oldBackups.length >= 1);
84         // make sure there are no accounts in the provider
85         int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI,
86                 null, null);
87         assertEquals(0, numAccounts);
88         // run backups
89         AccountBackupRestore.doBackupAccounts(mMockContext, mPreferences);
90         // confirm there are no backups made
91         Account[] backups = mPreferences.getAccounts();
92         assertEquals(0, backups.length);
93     }
94 
95     /**
96      * Test backup with accounts
97      */
testBackup()98     public void testBackup() {
99         // Clear the decks
100         deleteLegacyAccounts();
101 
102         // Create real accounts in need of backup
103         EmailContent.Account liveAccount1 =
104             ProviderTestUtils.setupAccount("testBackup1", false, mMockContext);
105         liveAccount1.mHostAuthRecv =
106             ProviderTestUtils.setupHostAuth("legacy-recv", 0, false, mMockContext);
107         liveAccount1.mHostAuthSend =
108             ProviderTestUtils.setupHostAuth("legacy-send", 0, false, mMockContext);
109         liveAccount1.setDefaultAccount(true);
110         liveAccount1.save(mMockContext);
111         EmailContent.Account liveAccount2 =
112             ProviderTestUtils.setupAccount("testBackup2", false, mMockContext);
113         liveAccount2.mHostAuthRecv =
114             ProviderTestUtils.setupHostAuth("legacy-recv", 0, false, mMockContext);
115         liveAccount2.mHostAuthSend =
116             ProviderTestUtils.setupHostAuth("legacy-send", 0, false, mMockContext);
117         liveAccount2.setDefaultAccount(false);
118         liveAccount2.save(mMockContext);
119 
120         // run backups
121         AccountBackupRestore.doBackupAccounts(mMockContext, mPreferences);
122 
123         // Confirm we have two backups now
124         // Deep inspection is not performed here - see LegacyConversionsTests
125         // We just check for basic identity & flags
126         Account[] backups = mPreferences.getAccounts();
127         assertEquals(2, backups.length);
128         for (Account backup : backups) {
129             if ("testBackup1".equals(backup.getDescription())) {
130                 assertTrue(0 != (backup.mBackupFlags & Account.BACKUP_FLAGS_IS_DEFAULT));
131             } else if ("testBackup2".equals(backup.getDescription())) {
132                 assertFalse(0 != (backup.mBackupFlags & Account.BACKUP_FLAGS_IS_DEFAULT));
133             } else {
134                 fail("unexpected backup name=" + backup.getDescription());
135             }
136         }
137         Account backup1 = backups[0];
138         assertTrue(0 != (backup1.mBackupFlags & Account.BACKUP_FLAGS_IS_BACKUP));
139         assertEquals(liveAccount1.getDisplayName(), backup1.getDescription());
140     }
141 
142     /**
143      * TODO: Test backup EAS accounts, with and without contacts sync
144      *
145      * Blocker:  We need to inject the dependency on ContentResolver.getSyncAutomatically()
146      * so we can make our fake accounts appear to be syncable or non-syncable
147      */
148 
149     /**
150      * Test no-restore with accounts found
151      */
testNoAccountRestore1()152     public void testNoAccountRestore1() {
153         // make sure there are no real backups
154         deleteLegacyAccounts();
155 
156         // make sure there are test backups available
157         Account backupAccount1 = setupLegacyBackupAccount("backup1");
158         backupAccount1.save(mPreferences);
159         Account backupAccount2 = setupLegacyBackupAccount("backup2");
160         backupAccount2.save(mPreferences);
161 
162         // make sure there are accounts
163         EmailContent.Account existing =
164             ProviderTestUtils.setupAccount("existing", true, mMockContext);
165 
166         // run the restore
167         boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences);
168         assertFalse(anyRestored);
169 
170         // make sure accounts still there
171         int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI,
172                 null, null);
173         assertEquals(1, numAccounts);
174     }
175 
176     /**
177      * Test no-restore with no accounts & no backups
178      */
testNoAccountRestore2()179     public void testNoAccountRestore2() {
180         // make sure there are no real backups
181         deleteLegacyAccounts();
182 
183         // make sure there are no accounts
184         int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI,
185                 null, null);
186         assertEquals(0, numAccounts);
187 
188         // run the restore
189         boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences);
190         assertFalse(anyRestored);
191 
192         // make sure accounts still there
193         numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI,
194                 null, null);
195         assertEquals(0, numAccounts);
196     }
197 
198     /**
199      * Test restore with 2 accounts.
200      * Repeats test to verify restore of default account
201      */
testAccountRestore()202     public void testAccountRestore() {
203         // make sure there are no real backups
204         deleteLegacyAccounts();
205 
206         // create test backups
207         Account backupAccount1 = setupLegacyBackupAccount("backup1");
208         backupAccount1.mBackupFlags |= Account.BACKUP_FLAGS_IS_DEFAULT;
209         backupAccount1.save(mPreferences);
210         Account backupAccount2 = setupLegacyBackupAccount("backup2");
211         backupAccount2.save(mPreferences);
212 
213         // run the restore
214         boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences);
215         assertTrue(anyRestored);
216 
217         // Check the restored accounts
218         // Deep inspection is not performed here - see LegacyConversionsTests for that
219         // We just check for basic identity & flags
220         Cursor c = mMockContext.getContentResolver().query(EmailContent.Account.CONTENT_URI,
221                 EmailContent.Account.CONTENT_PROJECTION, null, null, null);
222         try {
223             assertEquals(2, c.getCount());
224             while (c.moveToNext()) {
225                 EmailContent.Account restored =
226                     EmailContent.getContent(c, EmailContent.Account.class);
227                 if ("backup1".equals(restored.getDisplayName())) {
228                     assertTrue(restored.mIsDefault);
229                 } else if ("backup2".equals(restored.getDisplayName())) {
230                     assertFalse(restored.mIsDefault);
231                 } else {
232                     fail("Unexpected restore account name=" + restored.getDisplayName());
233                 }
234                 checkRestoredTransientValues(restored);
235             }
236         } finally {
237             c.close();
238         }
239 
240         // clear out the backups & accounts and try again
241         deleteLegacyAccounts();
242         mMockContext.getContentResolver().delete(EmailContent.Account.CONTENT_URI, null, null);
243 
244         Account backupAccount3 = setupLegacyBackupAccount("backup3");
245         backupAccount3.save(mPreferences);
246         Account backupAccount4 = setupLegacyBackupAccount("backup4");
247         backupAccount4.mBackupFlags |= Account.BACKUP_FLAGS_IS_DEFAULT;
248         backupAccount4.save(mPreferences);
249 
250         // run the restore
251         AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences);
252 
253         // Check the restored accounts
254         // Deep inspection is not performed here - see LegacyConversionsTests for that
255         // We just check for basic identity & flags
256         c = mMockContext.getContentResolver().query(EmailContent.Account.CONTENT_URI,
257                 EmailContent.Account.CONTENT_PROJECTION, null, null, null);
258         try {
259             assertEquals(2, c.getCount());
260             while (c.moveToNext()) {
261                 EmailContent.Account restored =
262                     EmailContent.getContent(c, EmailContent.Account.class);
263                 if ("backup3".equals(restored.getDisplayName())) {
264                     assertFalse(restored.mIsDefault);
265                 } else if ("backup4".equals(restored.getDisplayName())) {
266                     assertTrue(restored.mIsDefault);
267                 } else {
268                     fail("Unexpected restore account name=" + restored.getDisplayName());
269                 }
270                 checkRestoredTransientValues(restored);
271             }
272         } finally {
273             c.close();
274         }
275     }
276 
277     /**
278      * Check a given restored account to make sure that transient (non-backed-up) values
279      * are initialized to reasonable values.
280      */
checkRestoredTransientValues(EmailContent.Account restored)281     private void checkRestoredTransientValues(EmailContent.Account restored) {
282         // sync key == null
283         assertNull(restored.mSyncKey);
284         // hostauth id's are no longer zero or -1
285         assertTrue(restored.mHostAuthKeyRecv > 0);
286         assertTrue(restored.mHostAuthKeySend > 0);
287         // protocol version == null or non-empty string
288         assertTrue(restored.mProtocolVersion == null || restored.mProtocolVersion.length() > 0);
289     }
290 
291     /**
292      * TODO: Test restore EAS accounts, with and without contacts sync
293      *
294      * Blocker:  We need to inject the dependency on account manager to catch the calls to it
295      */
296 
297     /**
298      * Setup a legacy backup account with many fields prefilled.
299      */
setupLegacyBackupAccount(String name)300     private Account setupLegacyBackupAccount(String name) {
301         Account backup = new Account(mMockContext);
302 
303         // fill in useful fields
304         backup.mUuid = "test-uid-" + name;
305         backup.mStoreUri = "store://test/" + name;
306         backup.mLocalStoreUri = "local://localhost/" + name;
307         backup.mSenderUri = "sender://test/" + name;
308         backup.mDescription = name;
309         backup.mName = "name " + name;
310         backup.mEmail = "email " + name;
311         backup.mAutomaticCheckIntervalMinutes = 100;
312         backup.mLastAutomaticCheckTime = 200;
313         backup.mNotifyNewMail = true;
314         backup.mDraftsFolderName = "drafts " + name;
315         backup.mSentFolderName = "sent " + name;
316         backup.mTrashFolderName = "trash " + name;
317         backup.mOutboxFolderName = "outbox " + name;
318         backup.mAccountNumber = 300;
319         backup.mVibrate = true;
320         backup.mVibrateWhenSilent = false;
321         backup.mRingtoneUri = "ringtone://test/" + name;
322         backup.mSyncWindow = 400;
323         backup.mBackupFlags = Account.BACKUP_FLAGS_IS_BACKUP;
324         backup.mProtocolVersion = "proto version" + name;
325         backup.mDeletePolicy = Account.DELETE_POLICY_NEVER;
326         backup.mSecurityFlags = 500;
327         return backup;
328     }
329 }
330