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