mobile/android/tests/background/junit3/src/sync/TestSyncAccounts.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/tests/background/junit3/src/sync/TestSyncAccounts.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,343 @@
     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.UnsupportedEncodingException;
    1.10 +import java.security.NoSuchAlgorithmException;
    1.11 +import java.util.concurrent.TimeUnit;
    1.12 +
    1.13 +import org.mozilla.gecko.background.common.GlobalConstants;
    1.14 +import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
    1.15 +import org.mozilla.gecko.sync.ExtendedJSONObject;
    1.16 +import org.mozilla.gecko.sync.SyncConfiguration;
    1.17 +import org.mozilla.gecko.sync.SyncConstants;
    1.18 +import org.mozilla.gecko.sync.Utils;
    1.19 +import org.mozilla.gecko.sync.setup.Constants;
    1.20 +import org.mozilla.gecko.sync.setup.SyncAccounts;
    1.21 +import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
    1.22 +
    1.23 +import android.accounts.Account;
    1.24 +import android.accounts.AccountManager;
    1.25 +import android.accounts.AccountManagerCallback;
    1.26 +import android.accounts.AccountManagerFuture;
    1.27 +import android.content.Context;
    1.28 +import android.content.Intent;
    1.29 +import android.content.SharedPreferences;
    1.30 +import android.test.InstrumentationTestCase;
    1.31 +
    1.32 +/**
    1.33 + * We can use <code>performWait</code> and <code>performNotify</code> here if we
    1.34 + * are careful about threading issues with <code>AsyncTask</code>. We need to
    1.35 + * take some care to both create and run certain tasks on the main thread --
    1.36 + * moving the object allocation out of the UI thread causes failures!
    1.37 + * <p>
    1.38 + * @see "<a href='http://stackoverflow.com/questions/2321829/android-asynctask-testing-problem-with-android-test-framework'>
    1.39 + * http://stackoverflow.com/questions/2321829/android-asynctask-testing-problem-with-android-test-framework</a>."
    1.40 + */
    1.41 +public class TestSyncAccounts extends AndroidSyncTestCase {
    1.42 +  private static final String TEST_USERNAME   = "testAccount@mozilla.com";
    1.43 +  private static final String TEST_SYNCKEY    = "testSyncKey";
    1.44 +  private static final String TEST_PASSWORD   = "testPassword";
    1.45 +  private static final String TEST_SERVERURL  = "test.server.url/";
    1.46 +  private static final String TEST_CLUSTERURL = "test.cluster.url/";
    1.47 +
    1.48 +  public static final String TEST_ACCOUNTTYPE = SyncConstants.ACCOUNTTYPE_SYNC;
    1.49 +
    1.50 +  public static final String TEST_PRODUCT = GlobalConstants.BROWSER_INTENT_PACKAGE;
    1.51 +  public static final String TEST_PROFILE = Constants.DEFAULT_PROFILE;
    1.52 +  public static final long TEST_VERSION = SyncConfiguration.CURRENT_PREFS_VERSION;
    1.53 +
    1.54 +  public static final String TEST_PREFERENCE = "testPreference";
    1.55 +  public static final String TEST_SYNC_ID = "testSyncID";
    1.56 +
    1.57 +  private Account account;
    1.58 +  private Context context;
    1.59 +  private AccountManager accountManager;
    1.60 +  private SyncAccountParameters syncAccount;
    1.61 +
    1.62 +  public void setUp() {
    1.63 +    account = null;
    1.64 +    context = getApplicationContext();
    1.65 +    accountManager = AccountManager.get(context);
    1.66 +    syncAccount = new SyncAccountParameters(context, null,
    1.67 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, null);
    1.68 +  }
    1.69 +
    1.70 +  public static void deleteAccount(final InstrumentationTestCase test, final AccountManager accountManager, final Account account) {
    1.71 +    performWait(new Runnable() {
    1.72 +      @Override
    1.73 +      public void run() {
    1.74 +        try {
    1.75 +          test.runTestOnUiThread(new Runnable() {
    1.76 +            final AccountManagerCallback<Boolean> callback = new AccountManagerCallback<Boolean>() {
    1.77 +              @Override
    1.78 +              public void run(AccountManagerFuture<Boolean> future) {
    1.79 +                try {
    1.80 +                  future.getResult(5L, TimeUnit.SECONDS);
    1.81 +                } catch (Exception e) {
    1.82 +                }
    1.83 +                performNotify();
    1.84 +              }
    1.85 +            };
    1.86 +
    1.87 +            @Override
    1.88 +            public void run() {
    1.89 +              accountManager.removeAccount(account, callback, null);
    1.90 +            }
    1.91 +          });
    1.92 +        } catch (Throwable e) {
    1.93 +          performNotify(e);
    1.94 +        }
    1.95 +      }
    1.96 +    });
    1.97 +  }
    1.98 +
    1.99 +  public void tearDown() {
   1.100 +    if (account == null) {
   1.101 +      return;
   1.102 +    }
   1.103 +    deleteAccount(this, accountManager, account);
   1.104 +    account = null;
   1.105 +  }
   1.106 +
   1.107 +  public void testSyncAccountParameters() {
   1.108 +    assertEquals(TEST_USERNAME, syncAccount.username);
   1.109 +    assertNull(syncAccount.accountManager);
   1.110 +    assertNull(syncAccount.serverURL);
   1.111 +
   1.112 +    try {
   1.113 +      syncAccount = new SyncAccountParameters(context, null,
   1.114 +          null, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL);
   1.115 +    } catch (IllegalArgumentException e) {
   1.116 +      return;
   1.117 +    } catch (Exception e) {
   1.118 +      fail("Did not expect exception: " + e);
   1.119 +    }
   1.120 +    fail("Expected IllegalArgumentException.");
   1.121 +  }
   1.122 +
   1.123 +  public void testCreateAccount() {
   1.124 +    int before = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.125 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.126 +    int afterCreate = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.127 +    assertTrue(afterCreate > before);
   1.128 +    deleteAccount(this, accountManager, account);
   1.129 +    account = null;
   1.130 +    int afterDelete = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.131 +    assertEquals(before, afterDelete);
   1.132 +  }
   1.133 +
   1.134 +  public void testCreateSecondAccount() {
   1.135 +    int before = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.136 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.137 +    int afterFirst = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.138 +    assertTrue(afterFirst > before);
   1.139 +
   1.140 +    SyncAccountParameters secondSyncAccount = new SyncAccountParameters(context, null,
   1.141 +        "second@username.com", TEST_SYNCKEY, TEST_PASSWORD, null);
   1.142 +
   1.143 +    Account second = SyncAccounts.createSyncAccount(secondSyncAccount, false);
   1.144 +    assertNotNull(second);
   1.145 +    int afterSecond = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.146 +    assertTrue(afterSecond > afterFirst);
   1.147 +
   1.148 +    deleteAccount(this, accountManager, second);
   1.149 +    deleteAccount(this, accountManager, account);
   1.150 +    account = null;
   1.151 +
   1.152 +    int afterDelete = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.153 +    assertEquals(before, afterDelete);
   1.154 +  }
   1.155 +
   1.156 +  public void testCreateDuplicateAccount() {
   1.157 +    int before = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.158 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.159 +    int afterCreate = accountManager.getAccountsByType(TEST_ACCOUNTTYPE).length;
   1.160 +    assertTrue(afterCreate > before);
   1.161 +
   1.162 +    Account dupe = SyncAccounts.createSyncAccount(syncAccount, false);
   1.163 +    assertNull(dupe);
   1.164 +  }
   1.165 +
   1.166 +  public void testClientRecord() throws NoSuchAlgorithmException, UnsupportedEncodingException {
   1.167 +    final String TEST_NAME = "testName";
   1.168 +    final String TEST_GUID = "testGuid";
   1.169 +    syncAccount = new SyncAccountParameters(context, null,
   1.170 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, null, null, TEST_NAME, TEST_GUID);
   1.171 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.172 +    assertNotNull(account);
   1.173 +
   1.174 +    SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME,
   1.175 +        SyncConstants.DEFAULT_AUTH_SERVER, TEST_PROFILE, TEST_VERSION);
   1.176 +
   1.177 +    // Verify that client record is set.
   1.178 +    assertEquals(TEST_GUID, prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null));
   1.179 +    assertEquals(TEST_NAME, prefs.getString(SyncConfiguration.PREF_CLIENT_NAME, null));
   1.180 +
   1.181 +    // Let's verify that clusterURL is correctly not set.
   1.182 +    String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null);
   1.183 +    assertNull(clusterURL);
   1.184 +  }
   1.185 +
   1.186 +  public void testClusterURL() throws NoSuchAlgorithmException, UnsupportedEncodingException {
   1.187 +    syncAccount = new SyncAccountParameters(context, null,
   1.188 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL, TEST_CLUSTERURL, null, null);
   1.189 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.190 +    assertNotNull(account);
   1.191 +
   1.192 +    SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME,
   1.193 +        TEST_SERVERURL, TEST_PROFILE, TEST_VERSION);
   1.194 +    String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null);
   1.195 +    assertNotNull(clusterURL);
   1.196 +    assertEquals(TEST_CLUSTERURL, clusterURL);
   1.197 +
   1.198 +    // Let's verify that client name and GUID are not set.
   1.199 +    assertNull(prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null));
   1.200 +    assertNull(prefs.getString(SyncConfiguration.PREF_CLIENT_NAME, null));
   1.201 +  }
   1.202 +
   1.203 +  /**
   1.204 +   * Verify that creating an account wipes stale settings in Shared Preferences.
   1.205 +   */
   1.206 +  public void testCreatingWipesSharedPrefs() throws Exception {
   1.207 +    final String TEST_PREFERENCE = "testPreference";
   1.208 +    final String TEST_SYNC_ID = "testSyncID";
   1.209 +
   1.210 +    SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME,
   1.211 +        TEST_SERVERURL, TEST_PROFILE, TEST_VERSION);
   1.212 +    prefs.edit().putString(SyncConfiguration.PREF_SYNC_ID, TEST_SYNC_ID).commit();
   1.213 +    prefs.edit().putString(TEST_PREFERENCE, TEST_SYNC_ID).commit();
   1.214 +
   1.215 +    syncAccount = new SyncAccountParameters(context, null,
   1.216 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL);
   1.217 +    account = SyncAccounts.createSyncAccount(syncAccount, false);
   1.218 +    assertNotNull(account);
   1.219 +
   1.220 +    // All values deleted (known and unknown).
   1.221 +    assertNull(prefs.getString(SyncConfiguration.PREF_SYNC_ID, null));
   1.222 +    assertNull(prefs.getString(TEST_SYNC_ID, null));
   1.223 +  }
   1.224 +
   1.225 +  /**
   1.226 +   * Verify that creating an account preserves settings in Shared Preferences when asked.
   1.227 +   */
   1.228 +  public void testCreateSyncAccountWithExistingPreferences() throws Exception {
   1.229 +
   1.230 +    SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT, TEST_USERNAME,
   1.231 +        TEST_SERVERURL, TEST_PROFILE, TEST_VERSION);
   1.232 +
   1.233 +    prefs.edit().putString(SyncConfiguration.PREF_SYNC_ID, TEST_SYNC_ID).commit();
   1.234 +    prefs.edit().putString(TEST_PREFERENCE, TEST_SYNC_ID).commit();
   1.235 +
   1.236 +    assertNotNull(prefs.getString(TEST_PREFERENCE, null));
   1.237 +    assertNotNull(prefs.getString(SyncConfiguration.PREF_SYNC_ID, null));
   1.238 +
   1.239 +    syncAccount = new SyncAccountParameters(context, null,
   1.240 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL);
   1.241 +    account = SyncAccounts.createSyncAccountPreservingExistingPreferences(syncAccount, false);
   1.242 +    assertNotNull(account);
   1.243 +
   1.244 +    // All values remain (known and unknown).
   1.245 +    assertNotNull(prefs.getString(TEST_PREFERENCE, null));
   1.246 +    assertNotNull(prefs.getString(SyncConfiguration.PREF_SYNC_ID, null));
   1.247 +  }
   1.248 +
   1.249 +  protected void assertParams(final SyncAccountParameters params) throws Exception {
   1.250 +    assertNotNull(params);
   1.251 +    assertEquals(context, params.context);
   1.252 +    assertEquals(Utils.usernameFromAccount(TEST_USERNAME), params.username);
   1.253 +    assertEquals(TEST_PASSWORD, params.password);
   1.254 +    assertEquals(TEST_SERVERURL, params.serverURL);
   1.255 +    assertEquals(TEST_SYNCKEY, params.syncKey);
   1.256 +  }
   1.257 +
   1.258 +  public void testBlockingFromAndroidAccountV0() throws Throwable {
   1.259 +    syncAccount = new SyncAccountParameters(context, null,
   1.260 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL, TEST_CLUSTERURL, null, null);
   1.261 +    try {
   1.262 +      account = SyncAccounts.createSyncAccount(syncAccount);
   1.263 +      assertNotNull(account);
   1.264 +
   1.265 +      // Test fetching parameters multiple times. Historically, we needed to
   1.266 +      // invalidate this token type every fetch; now we don't, but we'd like
   1.267 +      // to ensure multiple fetches work.
   1.268 +      SyncAccountParameters params = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
   1.269 +      assertParams(params);
   1.270 +
   1.271 +      params = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
   1.272 +      assertParams(params);
   1.273 +
   1.274 +      // Test this works on the main thread.
   1.275 +      this.runTestOnUiThread(new Runnable() {
   1.276 +        @Override
   1.277 +        public void run() {
   1.278 +          SyncAccountParameters params;
   1.279 +          try {
   1.280 +            params = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
   1.281 +            assertParams(params);
   1.282 +          } catch (Exception e) {
   1.283 +            fail("Fetching Sync account parameters failed on UI thread.");
   1.284 +          }
   1.285 +        }
   1.286 +      });
   1.287 +    } finally {
   1.288 +      if (account != null) {
   1.289 +        deleteAccount(this, accountManager, account);
   1.290 +        account = null;
   1.291 +      }
   1.292 +    }
   1.293 +  }
   1.294 +
   1.295 +  public void testMakeSyncAccountDeletedIntent() throws Throwable {
   1.296 +    syncAccount = new SyncAccountParameters(context, null,
   1.297 +        TEST_USERNAME, TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL, TEST_CLUSTERURL, null, null);
   1.298 +    try {
   1.299 +      account = SyncAccounts.createSyncAccount(syncAccount);
   1.300 +      assertNotNull(account);
   1.301 +
   1.302 +      Intent intent = SyncAccounts.makeSyncAccountDeletedIntent(context, accountManager, account);
   1.303 +      assertEquals(SyncConstants.SYNC_ACCOUNT_DELETED_ACTION, intent.getAction());
   1.304 +      assertEquals(SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION, intent.getLongExtra(Constants.JSON_KEY_VERSION, 0));
   1.305 +      assertEquals(TEST_USERNAME, intent.getStringExtra(Constants.JSON_KEY_ACCOUNT));
   1.306 +      assertTrue(Math.abs(intent.getLongExtra(Constants.JSON_KEY_TIMESTAMP, 0) - System.currentTimeMillis()) < 1000);
   1.307 +
   1.308 +      String payload = intent.getStringExtra(Constants.JSON_KEY_PAYLOAD);
   1.309 +      assertNotNull(payload);
   1.310 +
   1.311 +      SyncAccountParameters params = new SyncAccountParameters(context, accountManager, ExtendedJSONObject.parseJSONObject(payload));
   1.312 +      // Can't use assertParams because Sync key is deleted.
   1.313 +      assertNotNull(params);
   1.314 +      assertEquals(context, params.context);
   1.315 +      assertEquals(Utils.usernameFromAccount(TEST_USERNAME), params.username);
   1.316 +      assertEquals(TEST_PASSWORD, params.password);
   1.317 +      assertEquals(TEST_SERVERURL, params.serverURL);
   1.318 +      assertEquals("", params.syncKey);
   1.319 +    } finally {
   1.320 +      if (account != null) {
   1.321 +        deleteAccount(this, accountManager, account);
   1.322 +        account = null;
   1.323 +      }
   1.324 +    }
   1.325 +  }
   1.326 +
   1.327 +  public void testBlockingPrefsFromAndroidAccountV0() throws Exception {
   1.328 +    // Create test account with prefs. We use a different username to avoid a
   1.329 +    // timing issue, where the delayed clean-up of the account created by the
   1.330 +    // previous test deletes the preferences for this account.
   1.331 +    SharedPreferences prefs = Utils.getSharedPreferences(context, TEST_PRODUCT,
   1.332 +        TEST_USERNAME + "2", TEST_SERVERURL, TEST_PROFILE, TEST_VERSION);
   1.333 +    prefs.edit().putString(TEST_PREFERENCE, TEST_SYNC_ID).commit();
   1.334 +
   1.335 +    syncAccount = new SyncAccountParameters(context, null,
   1.336 +      TEST_USERNAME + "2", TEST_SYNCKEY, TEST_PASSWORD, TEST_SERVERURL);
   1.337 +    account = SyncAccounts.createSyncAccountPreservingExistingPreferences(syncAccount, false);
   1.338 +    assertNotNull(account);
   1.339 +
   1.340 +    // Fetch account and check prefs.
   1.341 +    SharedPreferences sharedPreferences = SyncAccounts.blockingPrefsFromAndroidAccountV0(context, accountManager,
   1.342 +        account, TEST_PRODUCT, TEST_PROFILE, TEST_VERSION);
   1.343 +    assertNotNull(sharedPreferences);
   1.344 +    assertEquals(TEST_SYNC_ID, sharedPreferences.getString(TEST_PREFERENCE, null));
   1.345 +  }
   1.346 +}

mercurial