Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 package org.mozilla.gecko.background.sync;
6 import java.io.FileInputStream;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.PrintStream;
10 import java.util.ArrayList;
11 import java.util.List;
13 import org.mozilla.gecko.background.common.GlobalConstants;
14 import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
15 import org.mozilla.gecko.db.BrowserContract;
16 import org.mozilla.gecko.sync.ExtendedJSONObject;
17 import org.mozilla.gecko.sync.SyncConfiguration;
18 import org.mozilla.gecko.sync.SyncConstants;
19 import org.mozilla.gecko.sync.Utils;
20 import org.mozilla.gecko.sync.config.AccountPickler;
21 import org.mozilla.gecko.sync.setup.Constants;
22 import org.mozilla.gecko.sync.setup.SyncAccounts;
23 import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
25 import android.accounts.Account;
26 import android.accounts.AccountManager;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.SharedPreferences;
31 public class TestAccountPickler extends AndroidSyncTestCase {
32 public static final String TEST_FILENAME = "test.json";
33 public static final String TEST_ACCOUNTTYPE = SyncConstants.ACCOUNTTYPE_SYNC;
35 // Test account names must start with TEST_USERNAME in order to be recognized
36 // as test accounts and deleted in tearDown.
37 public static final String TEST_USERNAME = "testAccount@mozilla.com";
38 public static final String TEST_USERNAME2 = TEST_USERNAME + "2";
40 public static final String TEST_SYNCKEY = "testSyncKey";
41 public static final String TEST_PASSWORD = "testPassword";
42 public static final String TEST_SERVER_URL = "test.server.url/";
43 public static final String TEST_CLUSTER_URL = "test.cluster.url/";
44 public static final String TEST_CLIENT_NAME = "testClientName";
45 public static final String TEST_CLIENT_GUID = "testClientGuid";
47 public static final String TEST_PRODUCT = GlobalConstants.BROWSER_INTENT_PACKAGE;
48 public static final String TEST_PROFILE = "default";
49 public static final long TEST_VERSION = SyncConfiguration.CURRENT_PREFS_VERSION;
51 protected SyncAccountParameters params;
52 protected Context context;
53 protected AccountManager accountManager;
54 protected int numAccounts;
56 public void setUp() {
57 context = getApplicationContext();
58 accountManager = AccountManager.get(context);
59 params = new SyncAccountParameters(context, accountManager,
60 TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVER_URL,
61 TEST_CLUSTER_URL, TEST_CLIENT_NAME, TEST_CLIENT_GUID);
62 numAccounts = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
63 }
65 public static List<Account> getTestAccounts(final AccountManager accountManager) {
66 final List<Account> testAccounts = new ArrayList<Account>();
68 final Account[] accounts = accountManager.getAccountsByType(TEST_ACCOUNTTYPE);
69 for (Account account : accounts) {
70 if (account.name.startsWith(TEST_USERNAME)) {
71 testAccounts.add(account);
72 }
73 }
75 return testAccounts;
76 }
78 public void deleteTestAccounts() {
79 for (Account account : getTestAccounts(accountManager)) {
80 TestSyncAccounts.deleteAccount(this, accountManager, account);
81 }
82 }
84 public void tearDown() {
85 deleteTestAccounts();
86 assertEquals(numAccounts, accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length);
87 }
89 public static void assertFileNotPresent(final Context context, final String filename) throws Exception {
90 // Verify file is not present.
91 FileInputStream fis = null;
92 try {
93 fis = context.openFileInput(TEST_FILENAME);
94 fail("Should get FileNotFoundException.");
95 } catch (FileNotFoundException e) {
96 // Do nothing; file should not exist.
97 } finally {
98 if (fis != null) {
99 fis.close();
100 }
101 }
102 }
104 public void testPersist() throws Exception {
105 context.deleteFile(TEST_FILENAME);
106 assertFileNotPresent(context, TEST_FILENAME);
108 AccountPickler.pickle(context, TEST_FILENAME, params, true);
110 final String s = Utils.readFile(context, TEST_FILENAME);
111 assertNotNull(s);
113 final ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(s);
114 assertEquals(TEST_USERNAME, o.getString(Constants.JSON_KEY_ACCOUNT));
115 assertEquals(TEST_PASSWORD, o.getString(Constants.JSON_KEY_PASSWORD));
116 assertEquals(TEST_SERVER_URL, o.getString(Constants.JSON_KEY_SERVER));
117 assertEquals(TEST_SYNCKEY, o.getString(Constants.JSON_KEY_SYNCKEY));
118 assertEquals(TEST_CLUSTER_URL, o.getString(Constants.JSON_KEY_CLUSTER));
119 assertEquals(TEST_CLIENT_NAME, o.getString(Constants.JSON_KEY_CLIENT_NAME));
120 assertEquals(TEST_CLIENT_GUID, o.getString(Constants.JSON_KEY_CLIENT_GUID));
121 assertEquals(Boolean.valueOf(true), o.get(Constants.JSON_KEY_SYNC_AUTOMATICALLY));
122 assertEquals(Long.valueOf(AccountPickler.VERSION), o.getLong(Constants.JSON_KEY_VERSION));
123 assertTrue(o.containsKey(Constants.JSON_KEY_TIMESTAMP));
124 }
126 public void testDeletePickle() throws Exception {
127 AccountPickler.pickle(context, TEST_FILENAME, params, false);
129 // Verify file is present.
130 final String s = Utils.readFile(context, TEST_FILENAME);
131 assertNotNull(s);
132 assertTrue(s.length() > 0);
134 AccountPickler.deletePickle(context, TEST_FILENAME);
135 assertFileNotPresent(context, TEST_FILENAME);
136 }
138 public Account deleteAccountsAndUnpickle(final Context context, final AccountManager accountManager, final String filename) {
139 deleteTestAccounts();
140 assertEquals(0, getTestAccounts(accountManager).size());
142 return AccountPickler.unpickle(context, filename);
143 }
145 public void testUnpickleSuccess() throws Exception {
146 AccountPickler.pickle(context, TEST_FILENAME, params, true);
148 // Make sure we have no accounts hanging around.
149 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
150 assertNotNull(account);
152 try {
153 assertEquals(1, getTestAccounts(accountManager).size());
154 assertTrue(ContentResolver.getSyncAutomatically(account, BrowserContract.AUTHORITY));
155 assertEquals(account.name, TEST_USERNAME);
157 // Verify Account parameters are in place. Not testing clusterURL since it's stored in
158 // shared prefs and it's less critical.
159 final String password = accountManager.getPassword(account);
160 final String serverURL = accountManager.getUserData(account, Constants.OPTION_SERVER);
161 final String syncKey = accountManager.getUserData(account, Constants.OPTION_SYNCKEY);
163 assertEquals(TEST_PASSWORD, password);
164 assertEquals(TEST_SERVER_URL, serverURL);
165 assertEquals(TEST_SYNCKEY, syncKey);
167 // Verify shared prefs parameters are in place.
168 final SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME, TEST_SERVER_URL, TEST_PROFILE, TEST_VERSION);
169 final String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null);
170 final String clientName = prefs.getString(SyncConfiguration.PREF_CLIENT_NAME, null);
171 final String clientGuid = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
173 assertEquals(TEST_CLUSTER_URL, clusterURL);
174 assertEquals(TEST_CLIENT_NAME, clientName);
175 assertEquals(TEST_CLIENT_GUID, clientGuid);
176 } finally {
177 TestSyncAccounts.deleteAccount(this, accountManager, account);
178 }
179 }
181 public void testUnpickleNoAutomatic() throws Exception {
182 AccountPickler.pickle(context, TEST_FILENAME, params, false);
184 // Make sure we have no accounts hanging around.
185 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
186 assertNotNull(account);
188 try {
189 assertEquals(1, getTestAccounts(accountManager).size());
190 assertFalse(ContentResolver.getSyncAutomatically(account, BrowserContract.AUTHORITY));
191 } finally {
192 TestSyncAccounts.deleteAccount(this, accountManager, account);
193 }
194 }
196 public void testUnpickleNoFile() {
197 // Just in case file is hanging around.
198 context.deleteFile(TEST_FILENAME);
200 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
201 assertNull(account);
202 }
204 public void testUnpickleIncompleteUserData() throws Exception {
205 final FileOutputStream fos = context.openFileOutput(TEST_FILENAME, Context.MODE_PRIVATE);
206 final PrintStream ps = (new PrintStream(fos));
207 ps.print("{}"); // Valid JSON, just missing everything.
208 ps.close();
209 fos.close();
211 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
212 assertNull(account);
213 }
215 public void testUnpickleMalformedFile() throws Exception {
216 final FileOutputStream fos = context.openFileOutput(TEST_FILENAME, Context.MODE_PRIVATE);
217 final PrintStream ps = (new PrintStream(fos));
218 ps.print("{1:!}"); // Not valid JSON.
219 ps.close();
220 fos.close();
222 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
223 assertNull(account);
224 }
226 public void testUnpickleAccountAlreadyExists() {
227 AccountPickler.pickle(context, TEST_FILENAME, params, false);
229 // Make sure we have no test accounts hanging around.
230 final Account account = deleteAccountsAndUnpickle(context, accountManager, TEST_FILENAME);
231 assertNotNull(account);
232 assertEquals(TEST_USERNAME, account.name);
234 // Now replace file with new username.
235 params = new SyncAccountParameters(context, accountManager,
236 TEST_USERNAME2, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVER_URL, null, TEST_CLIENT_NAME, TEST_CLIENT_GUID);
237 AccountPickler.pickle(context, TEST_FILENAME, params, false);
239 // Checking if sync accounts exist could try to unpickle. That unpickle
240 // would load an account with a different username, so we can check that
241 // nothing was unpickled by verifying that the username has not changed.
242 assertTrue(SyncAccounts.syncAccountsExist(context));
244 for (Account a : getTestAccounts(accountManager)) {
245 assertEquals(TEST_USERNAME, a.name);
246 }
247 }
248 }