ControllerProviderOpsTests.java revision 12b82d9374947c9268217f45befe8a74bd9b60d7
1/* 2 * Copyright (C) 2009 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.provider.ContentCache; 20import com.android.email.provider.EmailProvider; 21import com.android.email.provider.ProviderTestUtils; 22import com.android.emailcommon.provider.EmailContent; 23import com.android.emailcommon.provider.EmailContent.Account; 24import com.android.emailcommon.provider.EmailContent.Body; 25import com.android.emailcommon.provider.EmailContent.Message; 26import com.android.emailcommon.provider.HostAuth; 27import com.android.emailcommon.provider.Mailbox; 28 29import android.content.Context; 30import android.net.Uri; 31import android.test.ProviderTestCase2; 32 33import java.util.Locale; 34import java.util.concurrent.ExecutionException; 35 36/** 37 * Tests of the Controller class that depend on the underlying provider. 38 * 39 * NOTE: It would probably make sense to rewrite this using a MockProvider, instead of the 40 * ProviderTestCase (which is a real provider running on a temp database). This would be more of 41 * a true "unit test". 42 * 43 * You can run this entire test case with: 44 * runtest -c com.android.email.ControllerProviderOpsTests email 45 */ 46public class ControllerProviderOpsTests extends ProviderTestCase2<EmailProvider> { 47 48 private Context mProviderContext; 49 private Context mContext; 50 private TestController mTestController; 51 52 53 public ControllerProviderOpsTests() { 54 super(EmailProvider.class, EmailContent.AUTHORITY); 55 } 56 57 @Override 58 public void setUp() throws Exception { 59 super.setUp(); 60 mProviderContext = getMockContext(); 61 mContext = getContext(); 62 mTestController = new TestController(mProviderContext, mContext); 63 // Invalidate all caches, since we reset the database for each test 64 ContentCache.invalidateAllCachesForTest(); 65 } 66 67 @Override 68 public void tearDown() throws Exception { 69 super.tearDown(); 70 mTestController.cleanupForTest(); 71 } 72 73 /** 74 * Lightweight subclass of the Controller class allows injection of mock context 75 */ 76 public static class TestController extends Controller { 77 78 protected TestController(Context providerContext, Context systemContext) { 79 super(systemContext); 80 setProviderContext(providerContext); 81 } 82 } 83 84 /** 85 * These are strings that should not change per locale. 86 */ 87 public void testGetMailboxServerName() { 88 assertEquals("", mTestController.getMailboxServerName(-1)); 89 90 assertEquals("Inbox", mTestController.getMailboxServerName(Mailbox.TYPE_INBOX)); 91 assertEquals("Outbox", mTestController.getMailboxServerName(Mailbox.TYPE_OUTBOX)); 92 assertEquals("Trash", mTestController.getMailboxServerName(Mailbox.TYPE_TRASH)); 93 assertEquals("Sent", mTestController.getMailboxServerName(Mailbox.TYPE_SENT)); 94 assertEquals("Junk", mTestController.getMailboxServerName(Mailbox.TYPE_JUNK)); 95 96 // Now try again with translation 97 Locale savedLocale = Locale.getDefault(); 98 Locale.setDefault(Locale.FRANCE); 99 assertEquals("Inbox", mTestController.getMailboxServerName(Mailbox.TYPE_INBOX)); 100 assertEquals("Outbox", mTestController.getMailboxServerName(Mailbox.TYPE_OUTBOX)); 101 assertEquals("Trash", mTestController.getMailboxServerName(Mailbox.TYPE_TRASH)); 102 assertEquals("Sent", mTestController.getMailboxServerName(Mailbox.TYPE_SENT)); 103 assertEquals("Junk", mTestController.getMailboxServerName(Mailbox.TYPE_JUNK)); 104 Locale.setDefault(savedLocale); 105 } 106 107 /** 108 * Test of Controller.createMailbox(). 109 * Sunny day test only - creates a mailbox that does not exist. 110 * Does not test duplication, bad accountID, or any other bad input. 111 */ 112 public void testCreateMailbox() { 113 Account account = ProviderTestUtils.setupAccount("mailboxid", true, mProviderContext); 114 long accountId = account.mId; 115 116 long oldBoxId = Mailbox.findMailboxOfType(mProviderContext, accountId, Mailbox.TYPE_DRAFTS); 117 assertEquals(Mailbox.NO_MAILBOX, oldBoxId); 118 119 mTestController.createMailbox(accountId, Mailbox.TYPE_DRAFTS); 120 long boxId = Mailbox.findMailboxOfType(mProviderContext, accountId, Mailbox.TYPE_DRAFTS); 121 122 // check that the drafts mailbox exists 123 assertTrue("mailbox exists", boxId != Mailbox.NO_MAILBOX); 124 } 125 126 /** 127 * Test of Controller.findOrCreateMailboxOfType(). 128 * Checks: 129 * - finds correctly the ID of existing mailbox 130 * - creates non-existing mailbox 131 * - creates only once a new mailbox 132 * - when accountId or mailboxType are -1, returns NO_MAILBOX 133 */ 134 public void testFindOrCreateMailboxOfType() { 135 Account account = ProviderTestUtils.setupAccount("mailboxid", true, mProviderContext); 136 long accountId = account.mId; 137 Mailbox box = ProviderTestUtils.setupMailbox("box", accountId, false, mProviderContext); 138 final int boxType = Mailbox.TYPE_TRASH; 139 box.mType = boxType; 140 box.save(mProviderContext); 141 long boxId = box.mId; 142 143 long testBoxId = mTestController.findOrCreateMailboxOfType(accountId, boxType); 144 145 // check it found the right mailbox id 146 assertEquals(boxId, testBoxId); 147 148 long boxId2 = mTestController.findOrCreateMailboxOfType(accountId, Mailbox.TYPE_DRAFTS); 149 assertTrue("mailbox created", boxId2 != Mailbox.NO_MAILBOX); 150 assertTrue("with different id", testBoxId != boxId2); 151 152 // check it doesn't create twice when existing 153 long boxId3 = mTestController.findOrCreateMailboxOfType(accountId, Mailbox.TYPE_DRAFTS); 154 assertEquals("don't create if exists", boxId3, boxId2); 155 156 // check invalid aruments 157 assertEquals(Mailbox.NO_MAILBOX, 158 mTestController.findOrCreateMailboxOfType(-1, Mailbox.TYPE_DRAFTS)); 159 assertEquals(Mailbox.NO_MAILBOX, mTestController.findOrCreateMailboxOfType(accountId, -1)); 160 } 161 162 /** 163 * Test the "move message" function. 164 */ 165 public void testMoveMessage() throws InterruptedException, ExecutionException { 166 Account account1 = ProviderTestUtils.setupAccount("message-move", true, mProviderContext); 167 long account1Id = account1.mId; 168 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext); 169 long box1Id = box1.mId; 170 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mProviderContext); 171 long box2Id = box2.mId; 172 Mailbox boxDest = ProviderTestUtils.setupMailbox("d", account1Id, true, mProviderContext); 173 long boxDestId = boxDest.mId; 174 175 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 176 true, mProviderContext); 177 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box2Id, false, 178 true, mProviderContext); 179 long message1Id = message1.mId; 180 long message2Id = message2.mId; 181 182 // Because moveMessage runs asynchronously, call get() to force it to complete 183 mTestController.moveMessages(new long[] { message1Id, message2Id }, boxDestId).get(); 184 185 // now read back a fresh copy and confirm it's in the trash 186 assertEquals(boxDestId, EmailContent.Message.restoreMessageWithId(mProviderContext, 187 message1Id).mMailboxKey); 188 assertEquals(boxDestId, EmailContent.Message.restoreMessageWithId(mProviderContext, 189 message2Id).mMailboxKey); 190 } 191 192 /** 193 * Test the "delete message" function. Sunny day: 194 * - message/mailbox/account all exist 195 * - trash mailbox exists 196 */ 197 public void testDeleteMessage() { 198 Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mProviderContext); 199 long account1Id = account1.mId; 200 Mailbox box = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext); 201 long boxId = box.mId; 202 203 Mailbox trashBox = ProviderTestUtils.setupMailbox("box2", account1Id, false, 204 mProviderContext); 205 trashBox.mType = Mailbox.TYPE_TRASH; 206 trashBox.save(mProviderContext); 207 long trashBoxId = trashBox.mId; 208 209 Mailbox draftBox = ProviderTestUtils.setupMailbox("box3", account1Id, false, 210 mProviderContext); 211 draftBox.mType = Mailbox.TYPE_DRAFTS; 212 draftBox.save(mProviderContext); 213 long draftBoxId = draftBox.mId; 214 215 { 216 // Case 1: Message in a regular mailbox, account known. 217 Message message = ProviderTestUtils.setupMessage("message1", account1Id, boxId, false, 218 true, mProviderContext); 219 long messageId = message.mId; 220 221 mTestController.deleteMessageSync(messageId, account1Id); 222 223 // now read back a fresh copy and confirm it's in the trash 224 Message restored = EmailContent.Message.restoreMessageWithId(mProviderContext, 225 messageId); 226 assertEquals(trashBoxId, restored.mMailboxKey); 227 } 228 229 { 230 // Case 2: Message in a regular mailbox, account *un*known. 231 Message message = ProviderTestUtils.setupMessage("message2", account1Id, boxId, false, 232 true, mProviderContext); 233 long messageId = message.mId; 234 235 mTestController.deleteMessageSync(messageId, -1); 236 237 // now read back a fresh copy and confirm it's in the trash 238 Message restored = EmailContent.Message.restoreMessageWithId(mProviderContext, 239 messageId); 240 assertEquals(trashBoxId, restored.mMailboxKey); 241 } 242 243 { 244 // Case 3: Already in trash 245 Message message = ProviderTestUtils.setupMessage("message3", account1Id, trashBoxId, 246 false, true, mProviderContext); 247 long messageId = message.mId; 248 249 mTestController.deleteMessageSync(messageId, account1Id); 250 251 // Message should be deleted. 252 assertNull(EmailContent.Message.restoreMessageWithId(mProviderContext, messageId)); 253 } 254 255 { 256 // Case 4: Draft 257 Message message = ProviderTestUtils.setupMessage("message3", account1Id, draftBoxId, 258 false, true, mProviderContext); 259 long messageId = message.mId; 260 261 mTestController.deleteMessageSync(messageId, account1Id); 262 263 // Message should be deleted. 264 assertNull(EmailContent.Message.restoreMessageWithId(mProviderContext, messageId)); 265 } 266 } 267 268 /** 269 * Test deleting message when there is no trash mailbox 270 */ 271 public void testDeleteMessageNoTrash() { 272 Account account1 = 273 ProviderTestUtils.setupAccount("message-delete-notrash", true, mProviderContext); 274 long account1Id = account1.mId; 275 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext); 276 long box1Id = box1.mId; 277 278 Message message1 = 279 ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true, 280 mProviderContext); 281 long message1Id = message1.mId; 282 283 mTestController.deleteMessageSync(message1Id, account1Id); 284 285 // now read back a fresh copy and confirm it's in the trash 286 Message message1get = 287 EmailContent.Message.restoreMessageWithId(mProviderContext, message1Id); 288 289 // check the new mailbox and see if it looks right 290 assertFalse(-1 == message1get.mMailboxKey); 291 assertFalse(box1Id == message1get.mMailboxKey); 292 Mailbox mailbox2get = Mailbox.restoreMailboxWithId(mProviderContext, 293 message1get.mMailboxKey); 294 assertEquals(Mailbox.TYPE_TRASH, mailbox2get.mType); 295 } 296 297 /** 298 * Test read/unread flag 299 */ 300 public void testReadUnread() throws InterruptedException, ExecutionException { 301 Account account1 = ProviderTestUtils.setupAccount("read-unread", false, mProviderContext); 302 account1.mHostAuthRecv 303 = ProviderTestUtils.setupHostAuth("read-unread", 0, false, mProviderContext); 304 account1.save(mProviderContext); 305 long account1Id = account1.mId; 306 long box1Id = 2; 307 308 Message message1 = 309 ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true, 310 mProviderContext); 311 long message1Id = message1.mId; 312 313 // test setting to "read" 314 mTestController.setMessageRead(message1Id, true).get(); 315 Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 316 assertTrue(message1get.mFlagRead); 317 318 // test setting to "unread" 319 mTestController.setMessageRead(message1Id, false).get(); 320 message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 321 assertFalse(message1get.mFlagRead); 322 323 // test setting to "read" 324 mTestController.setMessageRead(message1Id, true).get(); 325 message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 326 assertTrue(message1get.mFlagRead); 327 } 328 329 /** 330 * Test favorites flag 331 */ 332 public void testFavorites() throws InterruptedException, ExecutionException { 333 Account account1 = ProviderTestUtils.setupAccount("favorites", false, mProviderContext); 334 account1.mHostAuthRecv 335 = ProviderTestUtils.setupHostAuth("favorites", 0, false, mProviderContext); 336 account1.save(mProviderContext); 337 long account1Id = account1.mId; 338 long box1Id = 2; 339 340 Message message1 = 341 ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true, 342 mProviderContext); 343 long message1Id = message1.mId; 344 345 // test setting to "favorite" 346 mTestController.setMessageFavorite(message1Id, true).get(); 347 Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 348 assertTrue(message1get.mFlagFavorite); 349 350 // test setting to "not favorite" 351 mTestController.setMessageFavorite(message1Id, false).get(); 352 message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 353 assertFalse(message1get.mFlagFavorite); 354 355 // test setting to "favorite" 356 mTestController.setMessageFavorite(message1Id, true).get(); 357 message1get = Message.restoreMessageWithId(mProviderContext, message1Id); 358 assertTrue(message1get.mFlagFavorite); 359 } 360 361 public void testGetAndDeleteAttachmentMailbox() { 362 Mailbox box = mTestController.getAttachmentMailbox(); 363 assertNotNull(box); 364 Mailbox anotherBox = mTestController.getAttachmentMailbox(); 365 assertNotNull(anotherBox); 366 // We should always get back the same Mailbox row 367 assertEquals(box.mId, anotherBox.mId); 368 // Add two messages to this mailbox 369 ProviderTestUtils.setupMessage("message1", 0, box.mId, false, true, 370 mProviderContext); 371 ProviderTestUtils.setupMessage("message2", 0, box.mId, false, true, 372 mProviderContext); 373 // Make sure we can find them where they are expected 374 assertEquals(2, EmailContent.count(mProviderContext, Message.CONTENT_URI, 375 Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)})); 376 // Delete them 377 mTestController.deleteAttachmentMessages(); 378 // Make sure they're gone 379 assertEquals(0, EmailContent.count(mProviderContext, Message.CONTENT_URI, 380 Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)})); 381 } 382 383 /** 384 * Test wiping an account's synced data. Everything should go, but account & empty inbox. 385 * Also ensures that the remaining account and the remaining inbox have cleared their 386 * server sync keys, to force refresh eventually. 387 */ 388 public void testWipeSyncedData() { 389 Account account1 = ProviderTestUtils.setupAccount("wipe-synced-1", false, mProviderContext); 390 account1.mSyncKey = "account-1-sync-key"; 391 account1.save(mProviderContext); 392 long account1Id = account1.mId; 393 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, false, mProviderContext); 394 box1.mType = Mailbox.TYPE_INBOX; 395 box1.mSyncKey = "box-1-sync-key"; 396 box1.save(mProviderContext); 397 long box1Id = box1.mId; 398 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mProviderContext); 399 long box2Id = box2.mId; 400 // An EAS account mailbox 401 Mailbox eas = ProviderTestUtils.setupMailbox("eas", account1Id, false, mProviderContext); 402 eas.mType = Mailbox.TYPE_EAS_ACCOUNT_MAILBOX; 403 eas.save(mProviderContext); 404 405 Account account2 = ProviderTestUtils.setupAccount("wipe-synced-2", false, mProviderContext); 406 account2.mSyncKey = "account-2-sync-key"; 407 account2.save(mProviderContext); 408 long account2Id = account2.mId; 409 Mailbox box3 = ProviderTestUtils.setupMailbox("box3", account2Id, false, mProviderContext); 410 box3.mSyncKey = "box-3-sync-key"; 411 box3.mType = Mailbox.TYPE_INBOX; 412 box3.save(mProviderContext); 413 long box3Id = box3.mId; 414 Mailbox box4 = ProviderTestUtils.setupMailbox("box4", account2Id, true, mProviderContext); 415 long box4Id = box4.mId; 416 417 // Now populate the 4 non-account boxes with messages 418 Message message = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 419 true, mProviderContext); 420 long message1Id = message.mId; 421 message = ProviderTestUtils.setupMessage("message2", account1Id, box2Id, false, 422 true, mProviderContext); 423 long message2Id = message.mId; 424 message = ProviderTestUtils.setupMessage("message3", account2Id, box3Id, false, 425 true, mProviderContext); 426 long message3Id = message.mId; 427 message = ProviderTestUtils.setupMessage("message4", account2Id, box4Id, false, 428 true, mProviderContext); 429 long message4Id = message.mId; 430 431 // Now wipe account 1's data 432 mTestController.deleteSyncedDataSync(account1Id); 433 434 // Confirm: Mailboxes gone (except account box), all messages gone, account survives 435 assertNull(Mailbox.restoreMailboxWithId(mProviderContext, box1Id)); 436 assertNull(Mailbox.restoreMailboxWithId(mProviderContext, box2Id)); 437 assertNotNull(Mailbox.restoreMailboxWithId(mProviderContext, eas.mId)); 438 assertNull(Message.restoreMessageWithId(mProviderContext, message1Id)); 439 assertNull(Message.restoreMessageWithId(mProviderContext, message2Id)); 440 account1 = Account.restoreAccountWithId(mProviderContext, account1Id); 441 assertNotNull(account1); 442 assertNull(account1.mSyncKey); 443 444 // Confirm: Other account survived 445 assertNotNull(Mailbox.restoreMailboxWithId(mProviderContext, box3Id)); 446 assertNotNull(Mailbox.restoreMailboxWithId(mProviderContext, box4Id)); 447 assertNotNull(Message.restoreMessageWithId(mProviderContext, message3Id)); 448 assertNotNull(Message.restoreMessageWithId(mProviderContext, message4Id)); 449 assertNotNull(Account.restoreAccountWithId(mProviderContext, account2Id)); 450 } 451 452 public void testLoadMessageFromUri() throws Exception { 453 // Create a simple message 454 Message msg = new Message(); 455 String text = "This is some text"; 456 msg.mText = text; 457 String sender = "sender@host.com"; 458 msg.mFrom = sender; 459 // Save this away 460 msg.save(mProviderContext); 461 462 Uri fileUri = ProviderTestUtils.createTempEmlFile(mProviderContext, msg, 463 mContext.getFilesDir()); 464 465 // Load the message via Controller and a Uri 466 Message loadedMsg = mTestController.loadMessageFromUri(fileUri); 467 468 // Check server id, mailbox key, account key, and from 469 assertNotNull(loadedMsg); 470 assertTrue(loadedMsg.mServerId.startsWith(Controller.ATTACHMENT_MESSAGE_UID_PREFIX)); 471 Mailbox box = mTestController.getAttachmentMailbox(); 472 assertNotNull(box); 473 assertEquals(box.mId, loadedMsg.mMailboxKey); 474 assertEquals(0, loadedMsg.mAccountKey); 475 assertEquals(loadedMsg.mFrom, sender); 476 // Check body text 477 String loadedMsgText = Body.restoreBodyTextWithMessageId(mProviderContext, loadedMsg.mId); 478 assertEquals(text, loadedMsgText); 479 } 480 481 /** 482 * Create a simple HostAuth with protocol 483 */ 484 private HostAuth setupSimpleHostAuth(String protocol) { 485 HostAuth hostAuth = new HostAuth(); 486 hostAuth.mProtocol = protocol; 487 return hostAuth; 488 } 489 490 public void testIsMessagingController() { 491 Account account1 = ProviderTestUtils.setupAccount("account1", false, 492 mProviderContext); 493 account1.mHostAuthRecv = setupSimpleHostAuth("eas"); 494 account1.save(mProviderContext); 495 assertFalse(mTestController.isMessagingController(account1)); 496 Account account2 = ProviderTestUtils.setupAccount("account2", false, 497 mProviderContext); 498 account2.mHostAuthRecv = setupSimpleHostAuth("imap"); 499 account2.save(mProviderContext); 500 assertTrue(mTestController.isMessagingController(account2)); 501 Account account3 = ProviderTestUtils.setupAccount("account3", false, 502 mProviderContext); 503 account3.mHostAuthRecv = setupSimpleHostAuth("pop3"); 504 account3.save(mProviderContext); 505 assertTrue(mTestController.isMessagingController(account3)); 506 Account account4 = ProviderTestUtils.setupAccount("account4", false, 507 mProviderContext); 508 account4.mHostAuthRecv = setupSimpleHostAuth("smtp"); 509 account4.save(mProviderContext); 510 assertFalse(mTestController.isMessagingController(account4)); 511 // There should be values for all of these accounts in the legacy map 512 assertNotNull(mTestController.mLegacyControllerMap.get(account1.mId)); 513 assertNotNull(mTestController.mLegacyControllerMap.get(account2.mId)); 514 assertNotNull(mTestController.mLegacyControllerMap.get(account3.mId)); 515 assertNotNull(mTestController.mLegacyControllerMap.get(account4.mId)); 516 // The map should have the expected values 517 assertFalse(mTestController.mLegacyControllerMap.get(account1.mId)); 518 assertTrue(mTestController.mLegacyControllerMap.get(account2.mId)); 519 assertTrue(mTestController.mLegacyControllerMap.get(account3.mId)); 520 assertFalse(mTestController.mLegacyControllerMap.get(account4.mId)); 521 // This second pass should pull values from the cache 522 assertFalse(mTestController.isMessagingController(account1)); 523 assertTrue(mTestController.isMessagingController(account2)); 524 assertTrue(mTestController.isMessagingController(account3)); 525 assertFalse(mTestController.isMessagingController(account4)); 526 } 527 528 /** 529 * TODO: releasing associated data (e.g. attachments, embedded images) 530 */ 531} 532