RefreshManagerTest.java revision cbdd9f78b2605e87e45e4f6761b0a8c444a8cd4c
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email; 18 19import com.android.email.mail.MessagingException; 20import com.android.email.provider.EmailContent.Account; 21import com.android.email.provider.ProviderTestUtils; 22 23import android.content.Context; 24import android.test.InstrumentationTestCase; 25import android.test.suitebuilder.annotation.LargeTest; 26import android.util.Log; 27 28import junit.framework.Assert; 29 30@LargeTest 31public class RefreshManagerTest extends InstrumentationTestCase { 32 private static final int WAIT_UNTIL_TIMEOUT_SECONDS = 15; 33 private MockClock mClock; 34 private MockController mController; 35 private RefreshManager mTarget; 36 private RefreshListener mListener; 37 38 private Context mContext; 39 40 // Isolated Context for providers. 41 private Context mProviderContext; 42 43 private static final MessagingException EXCEPTION = new MessagingException("test"); 44 45 // Looks silly, but it'll make it more readable. 46 private static final long ACCOUNT_1 = 1; 47 private static final long ACCOUNT_2 = 2; 48 private static final long MAILBOX_1 = 3; 49 private static final long MAILBOX_2 = 4; 50 51 @Override 52 protected void setUp() throws Exception { 53 super.setUp(); 54 55 mClock = new MockClock(); 56 mContext = getInstrumentation().getTargetContext(); 57 mController = new MockController(mContext); 58 mListener = new RefreshListener(); 59 mProviderContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(mContext); 60 mTarget = new RefreshManager(mProviderContext, mController, mClock, null); 61 mTarget.registerListener(mListener); 62 } 63 64 @Override 65 protected void tearDown() throws Exception { 66 super.tearDown(); 67 mController.cleanupForTest(); 68 } 69 70 public void testRegisterUnregisterListener() { 71 // mListener is already registered 72 assertEquals(1, mTarget.getListenersForTest().size()); 73 74 mTarget.unregisterListener(mListener); 75 assertEquals(0, mTarget.getListenersForTest().size()); 76 } 77 78 public void testRefreshStatus() { 79 RefreshManager.Status s = new RefreshManager.Status(); 80 assertFalse(s.isRefreshing()); 81 assertTrue(s.canRefresh()); 82 assertEquals(0, s.getLastRefreshTime()); 83 84 // Request refresh 85 s.onRefreshRequested(); 86 assertTrue(s.isRefreshing()); 87 assertFalse(s.canRefresh()); 88 assertEquals(0, s.getLastRefreshTime()); 89 90 // Refresh start 91 s.onCallback(null, 0, mClock); 92 assertTrue(s.isRefreshing()); 93 assertFalse(s.canRefresh()); 94 assertEquals(0, s.getLastRefreshTime()); 95 96 // Refresh 50% done -- nothing changes 97 s.onCallback(null, 50, mClock); 98 assertTrue(s.isRefreshing()); 99 assertFalse(s.canRefresh()); 100 assertEquals(0, s.getLastRefreshTime()); 101 102 // Refresh finish 103 s.onCallback(null, 100, mClock); 104 assertFalse(s.isRefreshing()); 105 assertTrue(s.canRefresh()); 106 assertEquals(mClock.mTime, s.getLastRefreshTime()); 107 108 // Refresh start without request 109 s.onCallback(null, 0, mClock); 110 assertTrue(s.isRefreshing()); 111 assertFalse(s.canRefresh()); 112 assertEquals(mClock.mTime, s.getLastRefreshTime()); 113 114 mClock.advance(); 115 116 // Refresh finish with error. 117 s.onCallback(EXCEPTION, 0, mClock); 118 assertFalse(s.isRefreshing()); 119 assertTrue(s.canRefresh()); 120 assertEquals(mClock.mTime, s.getLastRefreshTime()); 121 } 122 123 public void testRefreshMailboxList() { 124 // request refresh for account 1 125 assertTrue(mTarget.refreshMailboxList(ACCOUNT_1)); 126 127 assertTrue(mListener.mCalledOnRefreshStatusChanged); 128 assertFalse(mListener.mCalledOnConnectionError); 129 assertEquals(ACCOUNT_1, mListener.mAccountId); 130 assertEquals(-1, mListener.mMailboxId); 131 mListener.reset(); 132 assertTrue(mController.mCalledUpdateMailboxList); 133 assertEquals(ACCOUNT_1, mController.mAccountId); 134 assertEquals(-1, mController.mMailboxId); 135 mController.reset(); 136 assertTrue(mTarget.isMailboxListRefreshing(ACCOUNT_1)); 137 assertTrue(mTarget.isRefreshingAnyMailboxListForTest()); 138 139 // Request again -- shouldn't be accepted. 140 assertFalse(mTarget.refreshMailboxList(ACCOUNT_1)); 141 142 assertFalse(mListener.mCalledOnRefreshStatusChanged); 143 assertFalse(mListener.mCalledOnConnectionError); 144 mListener.reset(); 145 assertFalse(mController.mCalledUpdateMailboxList); 146 mController.reset(); 147 148 // request refresh for account 2 149 assertTrue(mTarget.refreshMailboxList(ACCOUNT_2)); 150 151 assertTrue(mListener.mCalledOnRefreshStatusChanged); 152 assertFalse(mListener.mCalledOnConnectionError); 153 assertEquals(ACCOUNT_2, mListener.mAccountId); 154 assertEquals(-1, mListener.mMailboxId); 155 mListener.reset(); 156 assertTrue(mController.mCalledUpdateMailboxList); 157 assertEquals(ACCOUNT_2, mController.mAccountId); 158 assertEquals(-1, mController.mMailboxId); 159 mController.reset(); 160 assertTrue(mTarget.isMailboxListRefreshing(ACCOUNT_2)); 161 assertTrue(mTarget.isRefreshingAnyMailboxListForTest()); 162 163 // Refreshing for account 1... 164 mController.mListener.updateMailboxListCallback(null, ACCOUNT_1, 0); 165 166 assertTrue(mListener.mCalledOnRefreshStatusChanged); 167 assertFalse(mListener.mCalledOnConnectionError); 168 assertEquals(ACCOUNT_1, mListener.mAccountId); 169 assertEquals(-1, mListener.mMailboxId); 170 mListener.reset(); 171 assertTrue(mTarget.isMailboxListRefreshing(ACCOUNT_1)); 172 assertEquals(0, mTarget.getMailboxListStatusForTest(ACCOUNT_1).getLastRefreshTime()); 173 174 // Done. 175 Log.w(Email.LOG_TAG, "" + mController.mListener.getClass()); 176 mController.mListener.updateMailboxListCallback(null, ACCOUNT_1, 100); 177 178 assertTrue(mListener.mCalledOnRefreshStatusChanged); 179 assertFalse(mListener.mCalledOnConnectionError); 180 assertEquals(ACCOUNT_1, mListener.mAccountId); 181 assertEquals(-1, mListener.mMailboxId); 182 mListener.reset(); 183 assertFalse(mTarget.isMailboxListRefreshing(ACCOUNT_1)); 184 assertEquals(mClock.mTime, mTarget.getMailboxListStatusForTest(ACCOUNT_1) 185 .getLastRefreshTime()); 186 187 // Check "any" method. 188 assertTrue(mTarget.isRefreshingAnyMailboxListForTest()); // still refreshing account 2 189 190 // Refreshing for account 2... 191 mClock.advance(); 192 193 mController.mListener.updateMailboxListCallback(null, ACCOUNT_2, 0); 194 195 assertTrue(mListener.mCalledOnRefreshStatusChanged); 196 assertFalse(mListener.mCalledOnConnectionError); 197 assertEquals(ACCOUNT_2, mListener.mAccountId); 198 assertEquals(-1, mListener.mMailboxId); 199 mListener.reset(); 200 assertTrue(mTarget.isMailboxListRefreshing(ACCOUNT_2)); 201 assertEquals(0, mTarget.getMailboxListStatusForTest(ACCOUNT_2).getLastRefreshTime()); 202 203 // Done with exception. 204 mController.mListener.updateMailboxListCallback(EXCEPTION, ACCOUNT_2, 0); 205 206 assertTrue(mListener.mCalledOnRefreshStatusChanged); 207 assertTrue(mListener.mCalledOnConnectionError); 208 assertEquals(ACCOUNT_2, mListener.mAccountId); 209 assertEquals(-1, mListener.mMailboxId); 210 assertEquals(EXCEPTION.getUiErrorMessage(mContext), mListener.mMessage); 211 mListener.reset(); 212 assertFalse(mTarget.isMailboxListRefreshing(ACCOUNT_2)); 213 assertEquals(mClock.mTime, mTarget.getMailboxListStatusForTest(ACCOUNT_2) 214 .getLastRefreshTime()); 215 216 // Check "any" method. 217 assertFalse(mTarget.isRefreshingAnyMailboxListForTest()); 218 } 219 220 public void testRefreshMessageList() { 221 // request refresh mailbox 1 222 assertTrue(mTarget.refreshMessageList(ACCOUNT_1, MAILBOX_1, false)); 223 224 assertTrue(mListener.mCalledOnRefreshStatusChanged); 225 assertFalse(mListener.mCalledOnConnectionError); 226 assertEquals(ACCOUNT_1, mListener.mAccountId); 227 assertEquals(MAILBOX_1, mListener.mMailboxId); 228 mListener.reset(); 229 assertTrue(mController.mCalledUpdateMailbox); 230 assertEquals(ACCOUNT_1, mController.mAccountId); 231 assertEquals(MAILBOX_1, mController.mMailboxId); 232 mController.reset(); 233 assertTrue(mTarget.isMessageListRefreshing(MAILBOX_1)); 234 assertTrue(mTarget.isRefreshingAnyMessageListForTest()); 235 236 // Request again -- shouldn't be accepted. 237 assertFalse(mTarget.refreshMessageList(ACCOUNT_1, MAILBOX_1, false)); 238 239 assertFalse(mListener.mCalledOnRefreshStatusChanged); 240 assertFalse(mListener.mCalledOnConnectionError); 241 mListener.reset(); 242 assertFalse(mController.mCalledUpdateMailbox); 243 mController.reset(); 244 245 // request refresh mailbox 2 246 assertTrue(mTarget.refreshMessageList(ACCOUNT_2, MAILBOX_2, false)); 247 248 assertTrue(mListener.mCalledOnRefreshStatusChanged); 249 assertFalse(mListener.mCalledOnConnectionError); 250 assertEquals(ACCOUNT_2, mListener.mAccountId); 251 assertEquals(MAILBOX_2, mListener.mMailboxId); 252 mListener.reset(); 253 assertTrue(mController.mCalledUpdateMailbox); 254 assertEquals(ACCOUNT_2, mController.mAccountId); 255 assertEquals(MAILBOX_2, mController.mMailboxId); 256 mController.reset(); 257 assertTrue(mTarget.isMessageListRefreshing(MAILBOX_2)); 258 assertTrue(mTarget.isRefreshingAnyMessageListForTest()); 259 260 // Refreshing mailbox 1... 261 mController.mListener.updateMailboxCallback(null, ACCOUNT_1, MAILBOX_1, 0, 0); 262 263 assertTrue(mListener.mCalledOnRefreshStatusChanged); 264 assertFalse(mListener.mCalledOnConnectionError); 265 assertEquals(ACCOUNT_1, mListener.mAccountId); 266 assertEquals(MAILBOX_1, mListener.mMailboxId); 267 mListener.reset(); 268 assertTrue(mTarget.isMessageListRefreshing(MAILBOX_1)); 269 assertEquals(0, mTarget.getMessageListStatusForTest(MAILBOX_1).getLastRefreshTime()); 270 271 // Done. 272 Log.w(Email.LOG_TAG, "" + mController.mListener.getClass()); 273 mController.mListener.updateMailboxCallback(null, ACCOUNT_1, MAILBOX_1, 100, 0); 274 275 assertTrue(mListener.mCalledOnRefreshStatusChanged); 276 assertFalse(mListener.mCalledOnConnectionError); 277 assertEquals(ACCOUNT_1, mListener.mAccountId); 278 assertEquals(MAILBOX_1, mListener.mMailboxId); 279 mListener.reset(); 280 assertFalse(mTarget.isMessageListRefreshing(MAILBOX_1)); 281 assertEquals(mClock.mTime, mTarget.getMessageListStatusForTest(MAILBOX_1) 282 .getLastRefreshTime()); 283 284 // Check "any" method. 285 assertTrue(mTarget.isRefreshingAnyMessageListForTest()); // still refreshing mailbox 2 286 287 // Refreshing mailbox 2... 288 mClock.advance(); 289 290 mController.mListener.updateMailboxCallback(null, ACCOUNT_2, MAILBOX_2, 0, 0); 291 292 assertTrue(mListener.mCalledOnRefreshStatusChanged); 293 assertFalse(mListener.mCalledOnConnectionError); 294 assertEquals(ACCOUNT_2, mListener.mAccountId); 295 assertEquals(MAILBOX_2, mListener.mMailboxId); 296 mListener.reset(); 297 assertTrue(mTarget.isMessageListRefreshing(MAILBOX_2)); 298 assertEquals(0, mTarget.getMessageListStatusForTest(MAILBOX_2).getLastRefreshTime()); 299 300 // Done with exception. 301 mController.mListener.updateMailboxCallback(EXCEPTION, ACCOUNT_2, MAILBOX_2, 0, 0); 302 303 assertTrue(mListener.mCalledOnRefreshStatusChanged); 304 assertTrue(mListener.mCalledOnConnectionError); 305 assertEquals(ACCOUNT_2, mListener.mAccountId); 306 assertEquals(MAILBOX_2, mListener.mMailboxId); 307 assertEquals(EXCEPTION.getUiErrorMessage(mContext), mListener.mMessage); 308 mListener.reset(); 309 assertFalse(mTarget.isMessageListRefreshing(MAILBOX_2)); 310 assertEquals(mClock.mTime, mTarget.getMessageListStatusForTest(MAILBOX_2) 311 .getLastRefreshTime()); 312 313 // Check "any" method. 314 assertFalse(mTarget.isRefreshingAnyMessageListForTest()); 315 } 316 317 public void testSendPendingMessages() { 318 // request sending for account 1 319 assertTrue(mTarget.sendPendingMessages(ACCOUNT_1)); 320 321 assertTrue(mListener.mCalledOnRefreshStatusChanged); 322 assertFalse(mListener.mCalledOnConnectionError); 323 assertEquals(ACCOUNT_1, mListener.mAccountId); 324 assertEquals(-1, mListener.mMailboxId); 325 mListener.reset(); 326 assertTrue(mController.mCalledSendPendingMessages); 327 assertEquals(ACCOUNT_1, mController.mAccountId); 328 assertEquals(-1, mController.mMailboxId); 329 mController.reset(); 330 331 // request sending for account 2 332 assertTrue(mTarget.sendPendingMessages(ACCOUNT_2)); 333 334 assertFalse(mListener.mCalledOnConnectionError); 335 assertEquals(ACCOUNT_2, mListener.mAccountId); 336 assertEquals(-1, mListener.mMailboxId); 337 mListener.reset(); 338 assertTrue(mController.mCalledSendPendingMessages); 339 assertEquals(ACCOUNT_2, mController.mAccountId); 340 assertEquals(-1, mController.mMailboxId); 341 mController.reset(); 342 343 // Sending start for account 1... 344 // batch send start. (message id == -1, progress == 0) 345 mController.mListener.sendMailCallback(null, ACCOUNT_1, -1, 0); 346 347 assertFalse(mListener.mCalledOnConnectionError); 348 mListener.reset(); 349 350 // Per message callback 351 mController.mListener.sendMailCallback(null, ACCOUNT_1, 100, 0); 352 mController.mListener.sendMailCallback(null, ACCOUNT_1, 101, 0); 353 354 assertFalse(mListener.mCalledOnConnectionError); 355 mListener.reset(); 356 357 // Exception -- first error will be reported. 358 mController.mListener.sendMailCallback(EXCEPTION, ACCOUNT_1, 102, 0); 359 360 assertTrue(mListener.mCalledOnConnectionError); 361 assertEquals(EXCEPTION.getUiErrorMessage(mContext), mListener.mMessage); 362 mListener.reset(); 363 364 // Exception again -- no more error callbacks 365 mController.mListener.sendMailCallback(null, ACCOUNT_1, 103, 0); 366 mController.mListener.sendMailCallback(EXCEPTION, ACCOUNT_1, 104, 0); 367 368 assertFalse(mListener.mCalledOnConnectionError); 369 mListener.reset(); 370 371 // Done. 372 Log.w(Email.LOG_TAG, "" + mController.mListener.getClass()); 373 mController.mListener.sendMailCallback(null, ACCOUNT_1, -1, 100); 374 375 assertFalse(mListener.mCalledOnConnectionError); 376 mListener.reset(); 377 } 378 379 public void testSendPendingMessagesForAllAccounts() throws Throwable { 380 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, mProviderContext); 381 Account acct2 = ProviderTestUtils.setupAccount("acct2", true, mProviderContext); 382 383 // AsyncTask needs to be created on the UI thread. 384 runTestOnUiThread(new Runnable() { 385 @Override 386 public void run() { 387 mTarget.sendPendingMessagesForAllAccounts(); 388 } 389 }); 390 391 // sendPendingMessagesForAllAccounts uses Utility.ForEachAccount, which has it's own test, 392 // so we don't really have to check everything. 393 // Here, we just check if sendPendingMessages() has been called at least for once, 394 // which is a enough check. 395 TestUtils.waitUntil(new TestUtils.Condition() { 396 @Override 397 public boolean isMet() { 398 // The write to this is done on the UI thread, but we're checking it here 399 // on the test thread, so mCalledSendPendingMessages needs to be volatile. 400 return mController.mCalledSendPendingMessages; 401 } 402 }, WAIT_UNTIL_TIMEOUT_SECONDS); 403 } 404 405 // volatile is necessary for testSendPendingMessagesForAllAccounts(). 406 // (Not all of them are actually necessary, but added for consistency.) 407 private static class MockController extends Controller { 408 public volatile long mAccountId = -1; 409 public volatile long mMailboxId = -1; 410 public volatile boolean mCalledSendPendingMessages; 411 public volatile boolean mCalledUpdateMailbox; 412 public volatile boolean mCalledUpdateMailboxList; 413 public volatile Result mListener; 414 415 protected MockController(Context context) { 416 super(context); 417 } 418 419 public void reset() { 420 mAccountId = -1; 421 mMailboxId = -1; 422 mCalledSendPendingMessages = false; 423 mCalledUpdateMailbox = false; 424 mCalledUpdateMailboxList = false; 425 } 426 427 @Override 428 public void sendPendingMessages(long accountId) { 429 mCalledSendPendingMessages = true; 430 mAccountId = accountId; 431 } 432 433 @Override 434 public void updateMailbox(long accountId, long mailboxId, boolean userRequest) { 435 mCalledUpdateMailbox = true; 436 mAccountId = accountId; 437 mMailboxId = mailboxId; 438 } 439 440 @Override 441 public void updateMailboxList(long accountId) { 442 mCalledUpdateMailboxList = true; 443 mAccountId = accountId; 444 } 445 446 @Override 447 public void addResultCallback(Result listener) { 448 Assert.assertTrue(mListener == null); 449 mListener = listener; 450 451 // Let it call listener.setRegistered(). Otherwise callbacks won't fire. 452 super.addResultCallback(listener); 453 } 454 } 455 456 private static class RefreshListener implements RefreshManager.Listener { 457 public long mAccountId = -1; 458 public long mMailboxId = -1; 459 public String mMessage; 460 public boolean mCalledOnConnectionError; 461 public boolean mCalledOnRefreshStatusChanged; 462 463 public void reset() { 464 mAccountId = -1; 465 mMailboxId = -1; 466 mMessage = null; 467 mCalledOnConnectionError = false; 468 mCalledOnRefreshStatusChanged = false; 469 } 470 471 @Override 472 public void onRefreshStatusChanged(long accountId, long mailboxId) { 473 mAccountId = accountId; 474 mMailboxId = mailboxId; 475 mCalledOnRefreshStatusChanged = true; 476 } 477 478 @Override 479 public void onMessagingError(long accountId, long mailboxId, String message) { 480 mAccountId = accountId; 481 mMailboxId = mailboxId; 482 mMessage = message; 483 mCalledOnConnectionError = true; 484 } 485 } 486} 487