1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/tests/background/junit3/src/sync/TestAccountPickler.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,248 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +package org.mozilla.gecko.background.sync; 1.8 + 1.9 +import java.io.FileInputStream; 1.10 +import java.io.FileNotFoundException; 1.11 +import java.io.FileOutputStream; 1.12 +import java.io.PrintStream; 1.13 +import java.util.ArrayList; 1.14 +import java.util.List; 1.15 + 1.16 +import org.mozilla.gecko.background.common.GlobalConstants; 1.17 +import org.mozilla.gecko.background.helpers.AndroidSyncTestCase; 1.18 +import org.mozilla.gecko.db.BrowserContract; 1.19 +import org.mozilla.gecko.sync.ExtendedJSONObject; 1.20 +import org.mozilla.gecko.sync.SyncConfiguration; 1.21 +import org.mozilla.gecko.sync.SyncConstants; 1.22 +import org.mozilla.gecko.sync.Utils; 1.23 +import org.mozilla.gecko.sync.config.AccountPickler; 1.24 +import org.mozilla.gecko.sync.setup.Constants; 1.25 +import org.mozilla.gecko.sync.setup.SyncAccounts; 1.26 +import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters; 1.27 + 1.28 +import android.accounts.Account; 1.29 +import android.accounts.AccountManager; 1.30 +import android.content.ContentResolver; 1.31 +import android.content.Context; 1.32 +import android.content.SharedPreferences; 1.33 + 1.34 +public class TestAccountPickler extends AndroidSyncTestCase { 1.35 + public static final String TEST_FILENAME = "test.json"; 1.36 + public static final String TEST_ACCOUNTTYPE = SyncConstants.ACCOUNTTYPE_SYNC; 1.37 + 1.38 + // Test account names must start with TEST_USERNAME in order to be recognized 1.39 + // as test accounts and deleted in tearDown. 1.40 + public static final String TEST_USERNAME = "testAccount@mozilla.com"; 1.41 + public static final String TEST_USERNAME2 = TEST_USERNAME + "2"; 1.42 + 1.43 + public static final String TEST_SYNCKEY = "testSyncKey"; 1.44 + public static final String TEST_PASSWORD = "testPassword"; 1.45 + public static final String TEST_SERVER_URL = "test.server.url/"; 1.46 + public static final String TEST_CLUSTER_URL = "test.cluster.url/"; 1.47 + public static final String TEST_CLIENT_NAME = "testClientName"; 1.48 + public static final String TEST_CLIENT_GUID = "testClientGuid"; 1.49 + 1.50 + public static final String TEST_PRODUCT = GlobalConstants.BROWSER_INTENT_PACKAGE; 1.51 + public static final String TEST_PROFILE = "default"; 1.52 + public static final long TEST_VERSION = SyncConfiguration.CURRENT_PREFS_VERSION; 1.53 + 1.54 + protected SyncAccountParameters params; 1.55 + protected Context context; 1.56 + protected AccountManager accountManager; 1.57 + protected int numAccounts; 1.58 + 1.59 + public void setUp() { 1.60 + context = getApplicationContext(); 1.61 + accountManager = AccountManager.get(context); 1.62 + params = new SyncAccountParameters(context, accountManager, 1.63 + TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVER_URL, 1.64 + TEST_CLUSTER_URL, TEST_CLIENT_NAME, TEST_CLIENT_GUID); 1.65 + numAccounts = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length; 1.66 + } 1.67 + 1.68 + public static List<Account> getTestAccounts(final AccountManager accountManager) { 1.69 + final List<Account> testAccounts = new ArrayList<Account>(); 1.70 + 1.71 + final Account[] accounts = accountManager.getAccountsByType(TEST_ACCOUNTTYPE); 1.72 + for (Account account : accounts) { 1.73 + if (account.name.startsWith(TEST_USERNAME)) { 1.74 + testAccounts.add(account); 1.75 + } 1.76 + } 1.77 + 1.78 + return testAccounts; 1.79 + } 1.80 + 1.81 + public void deleteTestAccounts() { 1.82 + for (Account account : getTestAccounts(accountManager)) { 1.83 + TestSyncAccounts.deleteAccount(this, accountManager, account); 1.84 + } 1.85 + } 1.86 + 1.87 + public void tearDown() { 1.88 + deleteTestAccounts(); 1.89 + assertEquals(numAccounts, accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length); 1.90 + } 1.91 + 1.92 + public static void assertFileNotPresent(final Context context, final String filename) throws Exception { 1.93 + // Verify file is not present. 1.94 + FileInputStream fis = null; 1.95 + try { 1.96 + fis = context.openFileInput(TEST_FILENAME); 1.97 + fail("Should get FileNotFoundException."); 1.98 + } catch (FileNotFoundException e) { 1.99 + // Do nothing; file should not exist. 1.100 + } finally { 1.101 + if (fis != null) { 1.102 + fis.close(); 1.103 + } 1.104 + } 1.105 + } 1.106 + 1.107 + public void testPersist() throws Exception { 1.108 + context.deleteFile(TEST_FILENAME); 1.109 + assertFileNotPresent(context, TEST_FILENAME); 1.110 + 1.111 + AccountPickler.pickle(context, TEST_FILENAME, params, true); 1.112 + 1.113 + final String s = Utils.readFile(context, TEST_FILENAME); 1.114 + assertNotNull(s); 1.115 + 1.116 + final ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(s); 1.117 + assertEquals(TEST_USERNAME, o.getString(Constants.JSON_KEY_ACCOUNT)); 1.118 + assertEquals(TEST_PASSWORD, o.getString(Constants.JSON_KEY_PASSWORD)); 1.119 + assertEquals(TEST_SERVER_URL, o.getString(Constants.JSON_KEY_SERVER)); 1.120 + assertEquals(TEST_SYNCKEY, o.getString(Constants.JSON_KEY_SYNCKEY)); 1.121 + assertEquals(TEST_CLUSTER_URL, o.getString(Constants.JSON_KEY_CLUSTER)); 1.122 + assertEquals(TEST_CLIENT_NAME, o.getString(Constants.JSON_KEY_CLIENT_NAME)); 1.123 + assertEquals(TEST_CLIENT_GUID, o.getString(Constants.JSON_KEY_CLIENT_GUID)); 1.124 + assertEquals(Boolean.valueOf(true), o.get(Constants.JSON_KEY_SYNC_AUTOMATICALLY)); 1.125 + assertEquals(Long.valueOf(AccountPickler.VERSION), o.getLong(Constants.JSON_KEY_VERSION)); 1.126 + assertTrue(o.containsKey(Constants.JSON_KEY_TIMESTAMP)); 1.127 + } 1.128 + 1.129 + public void testDeletePickle() throws Exception { 1.130 + AccountPickler.pickle(context, TEST_FILENAME, params, false); 1.131 + 1.132 + // Verify file is present. 1.133 + final String s = Utils.readFile(context, TEST_FILENAME); 1.134 + assertNotNull(s); 1.135 + assertTrue(s.length() > 0); 1.136 + 1.137 + AccountPickler.deletePickle(context, TEST_FILENAME); 1.138 + assertFileNotPresent(context, TEST_FILENAME); 1.139 + } 1.140 + 1.141 + public Account deleteAccountsAndUnpickle(final Context context, final AccountManager accountManager, final String filename) { 1.142 + deleteTestAccounts(); 1.143 + assertEquals(0, getTestAccounts(accountManager).size()); 1.144 + 1.145 + return AccountPickler.unpickle(context, filename); 1.146 + } 1.147 + 1.148 + public void testUnpickleSuccess() throws Exception { 1.149 + AccountPickler.pickle(context, TEST_FILENAME, params, true); 1.150 + 1.151 + // Make sure we have no accounts hanging around. 1.152 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.153 + assertNotNull(account); 1.154 + 1.155 + try { 1.156 + assertEquals(1, getTestAccounts(accountManager).size()); 1.157 + assertTrue(ContentResolver.getSyncAutomatically(account, BrowserContract.AUTHORITY)); 1.158 + assertEquals(account.name, TEST_USERNAME); 1.159 + 1.160 + // Verify Account parameters are in place. Not testing clusterURL since it's stored in 1.161 + // shared prefs and it's less critical. 1.162 + final String password = accountManager.getPassword(account); 1.163 + final String serverURL = accountManager.getUserData(account, Constants.OPTION_SERVER); 1.164 + final String syncKey = accountManager.getUserData(account, Constants.OPTION_SYNCKEY); 1.165 + 1.166 + assertEquals(TEST_PASSWORD, password); 1.167 + assertEquals(TEST_SERVER_URL, serverURL); 1.168 + assertEquals(TEST_SYNCKEY, syncKey); 1.169 + 1.170 + // Verify shared prefs parameters are in place. 1.171 + final SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME, TEST_SERVER_URL, TEST_PROFILE, TEST_VERSION); 1.172 + final String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null); 1.173 + final String clientName = prefs.getString(SyncConfiguration.PREF_CLIENT_NAME, null); 1.174 + final String clientGuid = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null); 1.175 + 1.176 + assertEquals(TEST_CLUSTER_URL, clusterURL); 1.177 + assertEquals(TEST_CLIENT_NAME, clientName); 1.178 + assertEquals(TEST_CLIENT_GUID, clientGuid); 1.179 + } finally { 1.180 + TestSyncAccounts.deleteAccount(this, accountManager, account); 1.181 + } 1.182 + } 1.183 + 1.184 + public void testUnpickleNoAutomatic() throws Exception { 1.185 + AccountPickler.pickle(context, TEST_FILENAME, params, false); 1.186 + 1.187 + // Make sure we have no accounts hanging around. 1.188 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.189 + assertNotNull(account); 1.190 + 1.191 + try { 1.192 + assertEquals(1, getTestAccounts(accountManager).size()); 1.193 + assertFalse(ContentResolver.getSyncAutomatically(account, BrowserContract.AUTHORITY)); 1.194 + } finally { 1.195 + TestSyncAccounts.deleteAccount(this, accountManager, account); 1.196 + } 1.197 + } 1.198 + 1.199 + public void testUnpickleNoFile() { 1.200 + // Just in case file is hanging around. 1.201 + context.deleteFile(TEST_FILENAME); 1.202 + 1.203 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.204 + assertNull(account); 1.205 + } 1.206 + 1.207 + public void testUnpickleIncompleteUserData() throws Exception { 1.208 + final FileOutputStream fos = context.openFileOutput(TEST_FILENAME, Context.MODE_PRIVATE); 1.209 + final PrintStream ps = (new PrintStream(fos)); 1.210 + ps.print("{}"); // Valid JSON, just missing everything. 1.211 + ps.close(); 1.212 + fos.close(); 1.213 + 1.214 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.215 + assertNull(account); 1.216 + } 1.217 + 1.218 + public void testUnpickleMalformedFile() throws Exception { 1.219 + final FileOutputStream fos = context.openFileOutput(TEST_FILENAME, Context.MODE_PRIVATE); 1.220 + final PrintStream ps = (new PrintStream(fos)); 1.221 + ps.print("{1:!}"); // Not valid JSON. 1.222 + ps.close(); 1.223 + fos.close(); 1.224 + 1.225 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.226 + assertNull(account); 1.227 + } 1.228 + 1.229 + public void testUnpickleAccountAlreadyExists() { 1.230 + AccountPickler.pickle(context, TEST_FILENAME, params, false); 1.231 + 1.232 + // Make sure we have no test accounts hanging around. 1.233 + final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME); 1.234 + assertNotNull(account); 1.235 + assertEquals(TEST_USERNAME, account.name); 1.236 + 1.237 + // Now replace file with new username. 1.238 + params = new SyncAccountParameters(context, accountManager, 1.239 + TEST_USERNAME2, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVER_URL, null, TEST_CLIENT_NAME, TEST_CLIENT_GUID); 1.240 + AccountPickler.pickle(context, TEST_FILENAME, params, false); 1.241 + 1.242 + // Checking if sync accounts exist could try to unpickle. That unpickle 1.243 + // would load an account with a different username, so we can check that 1.244 + // nothing was unpickled by verifying that the username has not changed. 1.245 + assertTrue(SyncAccounts.syncAccountsExist(context)); 1.246 + 1.247 + for (Account a : getTestAccounts(accountManager)) { 1.248 + assertEquals(TEST_USERNAME, a.name); 1.249 + } 1.250 + } 1.251 +}