| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.email; |
| |
| import com.android.email.provider.EmailContent; |
| import com.android.email.provider.EmailProvider; |
| import com.android.email.provider.ProviderTestUtils; |
| |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.test.ProviderTestCase2; |
| import android.test.suitebuilder.annotation.MediumTest; |
| |
| /** |
| * This is a series of unit tests for backup/restore of the Account class. |
| * |
| * Technically these are functional because they use the underlying preferences framework. |
| * |
| * NOTE: These tests are destructive of any "legacy" accounts that might be lying around. |
| */ |
| @MediumTest |
| public class AccountBackupRestoreTests extends ProviderTestCase2<EmailProvider> { |
| |
| private Preferences mPreferences; |
| private Context mMockContext; |
| |
| public AccountBackupRestoreTests() { |
| super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| |
| mMockContext = getMockContext(); |
| // Note: preferences are not supported by this mock context, so we must |
| // explicitly use (and clean out) the real ones for now. |
| mPreferences = Preferences.getPreferences(mContext); |
| } |
| |
| /** |
| * Delete any dummy accounts we set up for this test |
| */ |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| deleteLegacyAccounts(); |
| } |
| |
| /** |
| * Delete *all* legacy accounts |
| */ |
| private void deleteLegacyAccounts() { |
| Account[] oldAccounts = mPreferences.getAccounts(); |
| for (Account oldAccount : oldAccounts) { |
| oldAccount.delete(mPreferences); |
| } |
| } |
| |
| /** |
| * Test backup with no accounts |
| */ |
| public void testNoAccountBackup() { |
| // create some "old" backups or legacy accounts |
| Account backupAccount = new Account(mMockContext); |
| backupAccount.save(mPreferences); |
| // confirm they are there |
| Account[] oldBackups = mPreferences.getAccounts(); |
| assertTrue(oldBackups.length >= 1); |
| // make sure there are no accounts in the provider |
| int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI, |
| null, null); |
| assertEquals(0, numAccounts); |
| // run backups |
| AccountBackupRestore.doBackupAccounts(mMockContext, mPreferences); |
| // confirm there are no backups made |
| Account[] backups = mPreferences.getAccounts(); |
| assertEquals(0, backups.length); |
| } |
| |
| /** |
| * Test backup with accounts |
| */ |
| public void testBackup() { |
| // Clear the decks |
| deleteLegacyAccounts(); |
| |
| // Create real accounts in need of backup |
| EmailContent.Account liveAccount1 = |
| ProviderTestUtils.setupAccount("testBackup1", false, mMockContext); |
| liveAccount1.mHostAuthRecv = |
| ProviderTestUtils.setupHostAuth("legacy-recv", 0, false, mMockContext); |
| liveAccount1.mHostAuthSend = |
| ProviderTestUtils.setupHostAuth("legacy-send", 0, false, mMockContext); |
| liveAccount1.setDefaultAccount(true); |
| liveAccount1.save(mMockContext); |
| EmailContent.Account liveAccount2 = |
| ProviderTestUtils.setupAccount("testBackup2", false, mMockContext); |
| liveAccount2.mHostAuthRecv = |
| ProviderTestUtils.setupHostAuth("legacy-recv", 0, false, mMockContext); |
| liveAccount2.mHostAuthSend = |
| ProviderTestUtils.setupHostAuth("legacy-send", 0, false, mMockContext); |
| liveAccount2.setDefaultAccount(false); |
| liveAccount2.save(mMockContext); |
| |
| // run backups |
| AccountBackupRestore.doBackupAccounts(mMockContext, mPreferences); |
| |
| // Confirm we have two backups now |
| // Deep inspection is not performed here - see LegacyConversionsTests |
| // We just check for basic identity & flags |
| Account[] backups = mPreferences.getAccounts(); |
| assertEquals(2, backups.length); |
| for (Account backup : backups) { |
| if ("testBackup1".equals(backup.getDescription())) { |
| assertTrue(0 != (backup.mBackupFlags & Account.BACKUP_FLAGS_IS_DEFAULT)); |
| } else if ("testBackup2".equals(backup.getDescription())) { |
| assertFalse(0 != (backup.mBackupFlags & Account.BACKUP_FLAGS_IS_DEFAULT)); |
| } else { |
| fail("unexpected backup name=" + backup.getDescription()); |
| } |
| } |
| Account backup1 = backups[0]; |
| assertTrue(0 != (backup1.mBackupFlags & Account.BACKUP_FLAGS_IS_BACKUP)); |
| assertEquals(liveAccount1.getDisplayName(), backup1.getDescription()); |
| } |
| |
| /** |
| * TODO: Test backup EAS accounts, with and without contacts sync |
| * |
| * Blocker: We need to inject the dependency on ContentResolver.getSyncAutomatically() |
| * so we can make our fake accounts appear to be syncable or non-syncable |
| */ |
| |
| /** |
| * Test no-restore with accounts found |
| */ |
| public void testNoAccountRestore1() { |
| // make sure there are no real backups |
| deleteLegacyAccounts(); |
| |
| // make sure there are test backups available |
| Account backupAccount1 = setupLegacyBackupAccount("backup1"); |
| backupAccount1.save(mPreferences); |
| Account backupAccount2 = setupLegacyBackupAccount("backup2"); |
| backupAccount2.save(mPreferences); |
| |
| // make sure there are accounts |
| EmailContent.Account existing = |
| ProviderTestUtils.setupAccount("existing", true, mMockContext); |
| |
| // run the restore |
| boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences); |
| assertFalse(anyRestored); |
| |
| // make sure accounts still there |
| int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI, |
| null, null); |
| assertEquals(1, numAccounts); |
| } |
| |
| /** |
| * Test no-restore with no accounts & no backups |
| */ |
| public void testNoAccountRestore2() { |
| // make sure there are no real backups |
| deleteLegacyAccounts(); |
| |
| // make sure there are no accounts |
| int numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI, |
| null, null); |
| assertEquals(0, numAccounts); |
| |
| // run the restore |
| boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences); |
| assertFalse(anyRestored); |
| |
| // make sure accounts still there |
| numAccounts = EmailContent.count(mMockContext, EmailContent.Account.CONTENT_URI, |
| null, null); |
| assertEquals(0, numAccounts); |
| } |
| |
| /** |
| * Test restore with 2 accounts. |
| * Repeats test to verify restore of default account |
| */ |
| public void testAccountRestore() { |
| // make sure there are no real backups |
| deleteLegacyAccounts(); |
| |
| // create test backups |
| Account backupAccount1 = setupLegacyBackupAccount("backup1"); |
| backupAccount1.mBackupFlags |= Account.BACKUP_FLAGS_IS_DEFAULT; |
| backupAccount1.save(mPreferences); |
| Account backupAccount2 = setupLegacyBackupAccount("backup2"); |
| backupAccount2.save(mPreferences); |
| |
| // run the restore |
| boolean anyRestored = AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences); |
| assertTrue(anyRestored); |
| |
| // Check the restored accounts |
| // Deep inspection is not performed here - see LegacyConversionsTests for that |
| // We just check for basic identity & flags |
| Cursor c = mMockContext.getContentResolver().query(EmailContent.Account.CONTENT_URI, |
| EmailContent.Account.CONTENT_PROJECTION, null, null, null); |
| try { |
| assertEquals(2, c.getCount()); |
| while (c.moveToNext()) { |
| EmailContent.Account restored = |
| EmailContent.getContent(c, EmailContent.Account.class); |
| if ("backup1".equals(restored.getDisplayName())) { |
| assertTrue(restored.mIsDefault); |
| } else if ("backup2".equals(restored.getDisplayName())) { |
| assertFalse(restored.mIsDefault); |
| } else { |
| fail("Unexpected restore account name=" + restored.getDisplayName()); |
| } |
| checkRestoredTransientValues(restored); |
| } |
| } finally { |
| c.close(); |
| } |
| |
| // clear out the backups & accounts and try again |
| deleteLegacyAccounts(); |
| mMockContext.getContentResolver().delete(EmailContent.Account.CONTENT_URI, null, null); |
| |
| Account backupAccount3 = setupLegacyBackupAccount("backup3"); |
| backupAccount3.save(mPreferences); |
| Account backupAccount4 = setupLegacyBackupAccount("backup4"); |
| backupAccount4.mBackupFlags |= Account.BACKUP_FLAGS_IS_DEFAULT; |
| backupAccount4.save(mPreferences); |
| |
| // run the restore |
| AccountBackupRestore.doRestoreAccounts(mMockContext, mPreferences); |
| |
| // Check the restored accounts |
| // Deep inspection is not performed here - see LegacyConversionsTests for that |
| // We just check for basic identity & flags |
| c = mMockContext.getContentResolver().query(EmailContent.Account.CONTENT_URI, |
| EmailContent.Account.CONTENT_PROJECTION, null, null, null); |
| try { |
| assertEquals(2, c.getCount()); |
| while (c.moveToNext()) { |
| EmailContent.Account restored = |
| EmailContent.getContent(c, EmailContent.Account.class); |
| if ("backup3".equals(restored.getDisplayName())) { |
| assertFalse(restored.mIsDefault); |
| } else if ("backup4".equals(restored.getDisplayName())) { |
| assertTrue(restored.mIsDefault); |
| } else { |
| fail("Unexpected restore account name=" + restored.getDisplayName()); |
| } |
| checkRestoredTransientValues(restored); |
| } |
| } finally { |
| c.close(); |
| } |
| } |
| |
| /** |
| * Check a given restored account to make sure that transient (non-backed-up) values |
| * are initialized to reasonable values. |
| */ |
| private void checkRestoredTransientValues(EmailContent.Account restored) { |
| // sync key == null |
| assertNull(restored.mSyncKey); |
| // hostauth id's are no longer zero or -1 |
| assertTrue(restored.mHostAuthKeyRecv > 0); |
| assertTrue(restored.mHostAuthKeySend > 0); |
| // protocol version == null or non-empty string |
| assertTrue(restored.mProtocolVersion == null || restored.mProtocolVersion.length() > 0); |
| } |
| |
| /** |
| * TODO: Test restore EAS accounts, with and without contacts sync |
| * |
| * Blocker: We need to inject the dependency on account manager to catch the calls to it |
| */ |
| |
| /** |
| * Setup a legacy backup account with many fields prefilled. |
| */ |
| private Account setupLegacyBackupAccount(String name) { |
| Account backup = new Account(mMockContext); |
| |
| // fill in useful fields |
| backup.mUuid = "test-uid-" + name; |
| backup.mStoreUri = "store://test/" + name; |
| backup.mLocalStoreUri = "local://localhost/" + name; |
| backup.mSenderUri = "sender://test/" + name; |
| backup.mDescription = name; |
| backup.mName = "name " + name; |
| backup.mEmail = "email " + name; |
| backup.mAutomaticCheckIntervalMinutes = 100; |
| backup.mLastAutomaticCheckTime = 200; |
| backup.mNotifyNewMail = true; |
| backup.mDraftsFolderName = "drafts " + name; |
| backup.mSentFolderName = "sent " + name; |
| backup.mTrashFolderName = "trash " + name; |
| backup.mOutboxFolderName = "outbox " + name; |
| backup.mAccountNumber = 300; |
| backup.mVibrate = true; |
| backup.mRingtoneUri = "ringtone://test/" + name; |
| backup.mSyncWindow = 400; |
| backup.mBackupFlags = Account.BACKUP_FLAGS_IS_BACKUP; |
| backup.mProtocolVersion = "proto version" + name; |
| backup.mDeletePolicy = Account.DELETE_POLICY_NEVER; |
| return backup; |
| } |
| } |