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

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 package org.mozilla.gecko.background.sync;
michael@0 5
michael@0 6 import java.io.IOException;
michael@0 7 import java.io.UnsupportedEncodingException;
michael@0 8
michael@0 9 import org.json.simple.parser.ParseException;
michael@0 10 import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
michael@0 11 import org.mozilla.gecko.background.testhelpers.DefaultGlobalSessionCallback;
michael@0 12 import org.mozilla.gecko.background.testhelpers.MockGlobalSession;
michael@0 13 import org.mozilla.gecko.background.testhelpers.MockSharedPreferences;
michael@0 14 import org.mozilla.gecko.db.BrowserContract;
michael@0 15 import org.mozilla.gecko.sync.GlobalSession;
michael@0 16 import org.mozilla.gecko.sync.NonObjectJSONException;
michael@0 17 import org.mozilla.gecko.sync.SyncConfiguration;
michael@0 18 import org.mozilla.gecko.sync.SyncConfigurationException;
michael@0 19 import org.mozilla.gecko.sync.SyncConstants;
michael@0 20 import org.mozilla.gecko.sync.crypto.CryptoException;
michael@0 21 import org.mozilla.gecko.sync.crypto.KeyBundle;
michael@0 22 import org.mozilla.gecko.sync.delegates.GlobalSessionCallback;
michael@0 23 import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
michael@0 24 import org.mozilla.gecko.sync.setup.Constants;
michael@0 25 import org.mozilla.gecko.sync.setup.SyncAccounts;
michael@0 26 import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
michael@0 27 import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
michael@0 28
michael@0 29 import android.accounts.Account;
michael@0 30 import android.accounts.AccountManager;
michael@0 31 import android.content.ContentResolver;
michael@0 32 import android.content.Context;
michael@0 33 import ch.boye.httpclientandroidlib.HttpEntity;
michael@0 34 import ch.boye.httpclientandroidlib.HttpResponse;
michael@0 35 import ch.boye.httpclientandroidlib.ProtocolVersion;
michael@0 36 import ch.boye.httpclientandroidlib.entity.StringEntity;
michael@0 37 import ch.boye.httpclientandroidlib.message.BasicHttpResponse;
michael@0 38
michael@0 39 /**
michael@0 40 * When syncing and a server responds with a 400 "Upgrade Required," Sync
michael@0 41 * accounts should be disabled.
michael@0 42 *
michael@0 43 * (We are not testing for package updating, because MY_PACKAGE_REPLACED
michael@0 44 * broadcasts can only be sent by the system. Testing for package replacement
michael@0 45 * needs to be done manually on a device.)
michael@0 46 *
michael@0 47 * @author liuche
michael@0 48 *
michael@0 49 */
michael@0 50 public class TestUpgradeRequired extends AndroidSyncTestCase {
michael@0 51 private final String TEST_SERVER = "http://test.ser.ver/";
michael@0 52
michael@0 53 private static final String TEST_USERNAME = "user1";
michael@0 54 private static final String TEST_PASSWORD = "pass1";
michael@0 55 private static final String TEST_SYNC_KEY = "abcdeabcdeabcdeabcdeabcdea";
michael@0 56
michael@0 57 private Context context;
michael@0 58
michael@0 59 public static boolean syncsAutomatically(Account a) {
michael@0 60 return ContentResolver.getSyncAutomatically(a, BrowserContract.AUTHORITY);
michael@0 61 }
michael@0 62
michael@0 63 public static boolean isSyncable(Account a) {
michael@0 64 return 1 == ContentResolver.getIsSyncable(a, BrowserContract.AUTHORITY);
michael@0 65 }
michael@0 66
michael@0 67 public static boolean willEnableOnUpgrade(Account a, AccountManager accountManager) {
michael@0 68 return "1".equals(accountManager.getUserData(a, Constants.DATA_ENABLE_ON_UPGRADE));
michael@0 69 }
michael@0 70
michael@0 71 private static Account getTestAccount(AccountManager accountManager) {
michael@0 72 final String type = SyncConstants.ACCOUNTTYPE_SYNC;
michael@0 73 Account[] existing = accountManager.getAccountsByType(type);
michael@0 74 for (Account account : existing) {
michael@0 75 if (account.name.equals(TEST_USERNAME)) {
michael@0 76 return account;
michael@0 77 }
michael@0 78 }
michael@0 79 return null;
michael@0 80 }
michael@0 81
michael@0 82 private void deleteTestAccount() {
michael@0 83 final AccountManager accountManager = AccountManager.get(context);
michael@0 84 final Account found = getTestAccount(accountManager);
michael@0 85 if (found == null) {
michael@0 86 return;
michael@0 87 }
michael@0 88 TestSyncAccounts.deleteAccount(this, accountManager, found);
michael@0 89 }
michael@0 90
michael@0 91 @Override
michael@0 92 public void setUp() {
michael@0 93 context = getApplicationContext();
michael@0 94 final AccountManager accountManager = AccountManager.get(context);
michael@0 95
michael@0 96 deleteTestAccount();
michael@0 97
michael@0 98 // Set up and enable Sync accounts.
michael@0 99 SyncAccountParameters syncAccountParams = new SyncAccountParameters(context, accountManager, TEST_USERNAME, TEST_PASSWORD, TEST_SYNC_KEY, TEST_SERVER, null, null, null);
michael@0 100 final Account account = SyncAccounts.createSyncAccount(syncAccountParams, true);
michael@0 101 assertNotNull(account);
michael@0 102 assertTrue(syncsAutomatically(account));
michael@0 103 assertTrue(isSyncable(account));
michael@0 104 }
michael@0 105
michael@0 106 private static class LeakySyncAdapter extends SyncAdapter {
michael@0 107 public LeakySyncAdapter(Context context, boolean autoInitialize, Account account) {
michael@0 108 super(context, autoInitialize);
michael@0 109 this.localAccount = account;
michael@0 110 }
michael@0 111 }
michael@0 112
michael@0 113 /**
michael@0 114 * Verify that when SyncAdapter is informed of an Upgrade Required
michael@0 115 * response, that it disables the account it's syncing.
michael@0 116 */
michael@0 117 public void testInformUpgradeRequired() {
michael@0 118 final AccountManager accountManager = AccountManager.get(context);
michael@0 119 final Account account = getTestAccount(accountManager);
michael@0 120
michael@0 121 assertNotNull(account);
michael@0 122 assertTrue(syncsAutomatically(account));
michael@0 123 assertTrue(isSyncable(account));
michael@0 124 assertFalse(willEnableOnUpgrade(account, accountManager));
michael@0 125
michael@0 126 LeakySyncAdapter adapter = new LeakySyncAdapter(context, true, account);
michael@0 127 adapter.informUpgradeRequiredResponse(null);
michael@0 128
michael@0 129 // Oh god.
michael@0 130 try {
michael@0 131 Thread.sleep(1000);
michael@0 132 } catch (InterruptedException e) {
michael@0 133 e.printStackTrace();
michael@0 134 }
michael@0 135
michael@0 136 // We have disabled the account, but it's still syncable.
michael@0 137 assertFalse(syncsAutomatically(account));
michael@0 138 assertTrue(isSyncable(account));
michael@0 139 assertTrue(willEnableOnUpgrade(account, accountManager));
michael@0 140 }
michael@0 141
michael@0 142 private class Result {
michael@0 143 public boolean called = false;
michael@0 144 }
michael@0 145
michael@0 146 public static HttpResponse simulate400() {
michael@0 147 HttpResponse response = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), 400, "Bad Request") {
michael@0 148 @Override
michael@0 149 public HttpEntity getEntity() {
michael@0 150 try {
michael@0 151 return new StringEntity("16");
michael@0 152 } catch (UnsupportedEncodingException e) {
michael@0 153 // Never happens.
michael@0 154 return null;
michael@0 155 }
michael@0 156 }
michael@0 157 };
michael@0 158 return response;
michael@0 159 }
michael@0 160
michael@0 161 /**
michael@0 162 * Verify that when a 400 response is received with an
michael@0 163 * "Upgrade Required" response code body, we call
michael@0 164 * informUpgradeRequiredResponse on the delegate.
michael@0 165 */
michael@0 166 public void testUpgradeResponse() throws SyncConfigurationException, IllegalArgumentException, NonObjectJSONException, IOException, ParseException, CryptoException {
michael@0 167 final Result calledUpgradeRequired = new Result();
michael@0 168 final GlobalSessionCallback callback = new DefaultGlobalSessionCallback() {
michael@0 169 @Override
michael@0 170 public void informUpgradeRequiredResponse(final GlobalSession session) {
michael@0 171 calledUpgradeRequired.called = true;
michael@0 172 }
michael@0 173 };
michael@0 174
michael@0 175 MockSharedPreferences prefs = new MockSharedPreferences();
michael@0 176 SyncConfiguration config = new SyncConfiguration(TEST_USERNAME, new BasicAuthHeaderProvider(TEST_USERNAME, TEST_PASSWORD), prefs);
michael@0 177 config.syncKeyBundle = new KeyBundle(TEST_USERNAME, TEST_SYNC_KEY);
michael@0 178 final GlobalSession session = new MockGlobalSession(config, callback);
michael@0 179
michael@0 180 session.interpretHTTPFailure(simulate400());
michael@0 181 assertTrue(calledUpgradeRequired.called);
michael@0 182 }
michael@0 183
michael@0 184 @Override
michael@0 185 public void tearDown() {
michael@0 186 deleteTestAccount();
michael@0 187 }
michael@0 188 }

mercurial