ProviderTests.java revision d25d87c7ba8bbbbcad771695a7085f227bac8a1b
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.provider; 18 19import com.android.email.Snippet; 20import com.android.email.provider.EmailContent.Account; 21import com.android.email.provider.EmailContent.AccountColumns; 22import com.android.email.provider.EmailContent.Attachment; 23import com.android.email.provider.EmailContent.AttachmentColumns; 24import com.android.email.provider.EmailContent.Body; 25import com.android.email.provider.EmailContent.BodyColumns; 26import com.android.email.provider.EmailContent.HostAuth; 27import com.android.email.provider.EmailContent.Mailbox; 28import com.android.email.provider.EmailContent.MailboxColumns; 29import com.android.email.provider.EmailContent.Message; 30import com.android.email.provider.EmailContent.MessageColumns; 31 32import android.content.ContentResolver; 33import android.content.ContentUris; 34import android.content.ContentValues; 35import android.content.Context; 36import android.database.Cursor; 37import android.database.sqlite.SQLiteDatabase; 38import android.net.Uri; 39import android.os.Bundle; 40import android.os.Environment; 41import android.os.Parcel; 42import android.test.MoreAsserts; 43import android.test.ProviderTestCase2; 44 45import java.io.File; 46import java.io.IOException; 47import java.util.ArrayList; 48 49/** 50 * Tests of the Email provider. 51 * 52 * You can run this entire test case with: 53 * runtest -c com.android.email.provider.ProviderTests email 54 * 55 * TODO: Add tests for cursor notification mechanism. (setNotificationUri and notifyChange) 56 * We can't test the entire notification mechanism with a mock content resolver, because which URI 57 * to notify when notifyChange() is called is in the actual content resolver. 58 * Implementing the same mechanism in a mock one is pointless. Instead what we could do is check 59 * what notification URI each cursor has, and with which URI is notified when 60 * inserting/updating/deleting. (The former require a new method from AbstractCursor) 61 */ 62public class ProviderTests extends ProviderTestCase2<EmailProvider> { 63 64 EmailProvider mProvider; 65 Context mMockContext; 66 67 public ProviderTests() { 68 super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY); 69 } 70 71 @Override 72 public void setUp() throws Exception { 73 super.setUp(); 74 mMockContext = getMockContext(); 75 } 76 77 @Override 78 public void tearDown() throws Exception { 79 super.tearDown(); 80 } 81 82 /** 83 * TODO: Database upgrade tests 84 */ 85 86 /** 87 * Test simple account save/retrieve 88 */ 89 public void testAccountSave() { 90 Account account1 = ProviderTestUtils.setupAccount("account-save", true, mMockContext); 91 long account1Id = account1.mId; 92 93 Account account2 = EmailContent.Account.restoreAccountWithId(mMockContext, account1Id); 94 95 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account2); 96 } 97 98 /** 99 * Test simple account save/retrieve with predefined hostauth records 100 */ 101 public void testAccountSaveHostAuth() { 102 Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext); 103 // add hostauth data, which should be saved the first time 104 account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false, 105 mMockContext); 106 account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false, 107 mMockContext); 108 account1.save(mMockContext); 109 long account1Id = account1.mId; 110 111 // Confirm account reads back correctly 112 Account account1get = EmailContent.Account.restoreAccountWithId(mMockContext, account1Id); 113 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account1get); 114 115 // Confirm hostauth fields can be accessed & read back correctly 116 HostAuth hostAuth1get = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, 117 account1get.mHostAuthKeyRecv); 118 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-recv", 119 account1.mHostAuthRecv, hostAuth1get); 120 HostAuth hostAuth2get = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, 121 account1get.mHostAuthKeySend); 122 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-send", 123 account1.mHostAuthSend, hostAuth2get); 124 } 125 126 /** 127 * Simple test of account parceling. The rather tortuous path is to ensure that the 128 * account is really flattened all the way down to a parcel and back. 129 */ 130 public void testAccountParcel() { 131 Account account1 = ProviderTestUtils.setupAccount("parcel", false, mMockContext); 132 Bundle b = new Bundle(); 133 b.putParcelable("account", account1); 134 Parcel p = Parcel.obtain(); 135 b.writeToParcel(p, 0); 136 p.setDataPosition(0); // rewind it for reading 137 Bundle b2 = new Bundle(Account.class.getClassLoader()); 138 b2.readFromParcel(p); 139 Account account2 = (Account) b2.getParcelable("account"); 140 p.recycle(); 141 142 ProviderTestUtils.assertAccountEqual("testAccountParcel", account1, account2); 143 } 144 145 /** 146 * Test for {@link Account#getShortcutSafeUri()} and 147 * {@link Account#getAccountIdForShortcutSafeUri}. 148 */ 149 public void testAccountShortcutSafeUri() { 150 final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext); 151 final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext); 152 final long account1Id = account1.mId; 153 final long account2Id = account2.mId; 154 155 final Uri uri1 = account1.getShortcutSafeUri(); 156 final Uri uri2 = account2.getShortcutSafeUri(); 157 158 // Check the path part of the URIs. 159 MoreAsserts.assertEquals(new String[] {"account", account1.mCompatibilityUuid}, 160 uri1.getPathSegments().toArray()); 161 MoreAsserts.assertEquals(new String[] {"account", account2.mCompatibilityUuid}, 162 uri2.getPathSegments().toArray()); 163 164 assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri1)); 165 assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri2)); 166 167 // Test for the Eclair(2.0-2.1) style URI. 168 assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, 169 getEclairStyleShortcutUri(account1))); 170 assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, 171 getEclairStyleShortcutUri(account2))); 172 } 173 174 private static Uri getEclairStyleShortcutUri(Account account) { 175 // We used _id instead of UUID only on Eclair(2.0-2.1). 176 return Account.CONTENT_URI.buildUpon().appendEncodedPath("" + account.mId).build(); 177 } 178 179 public void testGetProtocol() { 180 Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext); 181 // add hostauth data, with protocol 182 account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("eas", "account-hostauth-recv", -1, 183 false, mMockContext); 184 // Note that getProtocol uses the receive host auth, so the protocol here shouldn't matter 185 // to the test result 186 account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("foo", "account-hostauth-send", -1, 187 false, mMockContext); 188 account1.save(mMockContext); 189 assertEquals("eas", Account.getProtocol(mMockContext, account1.mId)); 190 assertEquals("eas", account1.getProtocol(mMockContext)); 191 Account account2 = ProviderTestUtils.setupAccount("account-nohostauth", false, 192 mMockContext); 193 account2.save(mMockContext); 194 // Make sure that we return null when there's no host auth 195 assertNull(Account.getProtocol(mMockContext, account2.mId)); 196 assertNull(account2.getProtocol(mMockContext)); 197 // And when there's no account 198 assertNull(Account.getProtocol(mMockContext, 0)); 199 } 200 201 public void testAccountIsValidId() { 202 final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext); 203 final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext); 204 205 assertTrue(Account.isValidId(mMockContext, account1.mId)); 206 assertTrue(Account.isValidId(mMockContext, account2.mId)); 207 208 assertFalse(Account.isValidId(mMockContext, 1234567)); // Some random ID 209 assertFalse(Account.isValidId(mMockContext, -1)); 210 assertFalse(Account.isValidId(mMockContext, -500)); 211 } 212 213 private final static String[] MAILBOX_UNREAD_COUNT_PROJECTION = new String [] { 214 MailboxColumns.UNREAD_COUNT 215 }; 216 private final static int MAILBOX_UNREAD_COUNT_COLMUN = 0; 217 218 /** 219 * Get the value of the unread count in the mailbox of the account. 220 * This can be different from the actual number of unread messages in that mailbox. 221 * @param accountId 222 * @param mailboxId 223 * @return 224 */ 225 private int getUnreadCount(long mailboxId) { 226 String text = null; 227 Cursor c = null; 228 try { 229 c = mMockContext.getContentResolver().query( 230 Mailbox.CONTENT_URI, 231 MAILBOX_UNREAD_COUNT_PROJECTION, 232 EmailContent.RECORD_ID + "=?", 233 new String[] { String.valueOf(mailboxId) }, 234 null); 235 c.moveToFirst(); 236 text = c.getString(MAILBOX_UNREAD_COUNT_COLMUN); 237 } finally { 238 c.close(); 239 } 240 return Integer.valueOf(text); 241 } 242 243 /** 244 * TODO: HostAuth tests 245 */ 246 247 /** 248 * Test the various combinations of SSL, TLS, and trust-certificates encoded as Uris 249 */ 250 @SuppressWarnings("deprecation") 251 public void testHostAuthSecurityUri() { 252 HostAuth ha = ProviderTestUtils.setupHostAuth("uri-security", 1, false, mMockContext); 253 254 final int MASK = 255 HostAuth.FLAG_SSL | HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 256 257 // Set various URIs and check the resulting flags 258 ha.setStoreUri("protocol://user:password@server:123"); 259 assertEquals(0, ha.mFlags & MASK); 260 ha.setStoreUri("protocol+ssl+://user:password@server:123"); 261 assertEquals(HostAuth.FLAG_SSL, ha.mFlags & MASK); 262 ha.setStoreUri("protocol+ssl+trustallcerts://user:password@server:123"); 263 assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); 264 ha.setStoreUri("protocol+tls+://user:password@server:123"); 265 assertEquals(HostAuth.FLAG_TLS, ha.mFlags & MASK); 266 ha.setStoreUri("protocol+tls+trustallcerts://user:password@server:123"); 267 assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); 268 269 // Now check the retrival method (building URI from flags) 270 ha.mFlags &= ~MASK; 271 String uriString = ha.getStoreUri(); 272 assertTrue(uriString.startsWith("protocol://")); 273 ha.mFlags |= HostAuth.FLAG_SSL; 274 uriString = ha.getStoreUri(); 275 assertTrue(uriString.startsWith("protocol+ssl+://")); 276 ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 277 uriString = ha.getStoreUri(); 278 assertTrue(uriString.startsWith("protocol+ssl+trustallcerts://")); 279 ha.mFlags &= ~MASK; 280 ha.mFlags |= HostAuth.FLAG_TLS; 281 uriString = ha.getStoreUri(); 282 assertTrue(uriString.startsWith("protocol+tls+://")); 283 ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 284 uriString = ha.getStoreUri(); 285 assertTrue(uriString.startsWith("protocol+tls+trustallcerts://")); 286 } 287 288 /** 289 * Test port assignments made from Uris 290 */ 291 @SuppressWarnings("deprecation") 292 public void testHostAuthPortAssignments() { 293 HostAuth ha = ProviderTestUtils.setupHostAuth("uri-port", 1, false, mMockContext); 294 295 // Set various URIs and check the resulting flags 296 // Hardwired port 297 ha.setStoreUri("imap://user:password@server:123"); 298 assertEquals(123, ha.mPort); 299 // Auto-assigned ports 300 ha.setStoreUri("imap://user:password@server"); 301 assertEquals(143, ha.mPort); 302 ha.setStoreUri("imap+ssl://user:password@server"); 303 assertEquals(993, ha.mPort); 304 ha.setStoreUri("imap+ssl+trustallcerts://user:password@server"); 305 assertEquals(993, ha.mPort); 306 ha.setStoreUri("imap+tls://user:password@server"); 307 assertEquals(143, ha.mPort); 308 ha.setStoreUri("imap+tls+trustallcerts://user:password@server"); 309 assertEquals(143, ha.mPort); 310 311 // Hardwired port 312 ha.setStoreUri("pop3://user:password@server:123"); 313 assertEquals(123, ha.mPort); 314 // Auto-assigned ports 315 ha.setStoreUri("pop3://user:password@server"); 316 assertEquals(110, ha.mPort); 317 ha.setStoreUri("pop3+ssl://user:password@server"); 318 assertEquals(995, ha.mPort); 319 ha.setStoreUri("pop3+ssl+trustallcerts://user:password@server"); 320 assertEquals(995, ha.mPort); 321 ha.setStoreUri("pop3+tls://user:password@server"); 322 assertEquals(110, ha.mPort); 323 ha.setStoreUri("pop3+tls+trustallcerts://user:password@server"); 324 assertEquals(110, ha.mPort); 325 326 // Hardwired port 327 ha.setStoreUri("eas://user:password@server:123"); 328 assertEquals(123, ha.mPort); 329 // Auto-assigned ports 330 ha.setStoreUri("eas://user:password@server"); 331 assertEquals(80, ha.mPort); 332 ha.setStoreUri("eas+ssl://user:password@server"); 333 assertEquals(443, ha.mPort); 334 ha.setStoreUri("eas+ssl+trustallcerts://user:password@server"); 335 assertEquals(443, ha.mPort); 336 337 // Hardwired port 338 ha.setStoreUri("smtp://user:password@server:123"); 339 assertEquals(123, ha.mPort); 340 // Auto-assigned ports 341 ha.setStoreUri("smtp://user:password@server"); 342 assertEquals(587, ha.mPort); 343 ha.setStoreUri("smtp+ssl://user:password@server"); 344 assertEquals(465, ha.mPort); 345 ha.setStoreUri("smtp+ssl+trustallcerts://user:password@server"); 346 assertEquals(465, ha.mPort); 347 ha.setStoreUri("smtp+tls://user:password@server"); 348 assertEquals(587, ha.mPort); 349 ha.setStoreUri("smtp+tls+trustallcerts://user:password@server"); 350 assertEquals(587, ha.mPort); 351 } 352 353 /** 354 * Test simple mailbox save/retrieve 355 */ 356 public void testMailboxSave() { 357 Account account1 = ProviderTestUtils.setupAccount("mailbox-save", true, mMockContext); 358 long account1Id = account1.mId; 359 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, 360 mMockContext); 361 long box1Id = box1.mId; 362 363 Mailbox box2 = EmailContent.Mailbox.restoreMailboxWithId(mMockContext, box1Id); 364 365 ProviderTestUtils.assertMailboxEqual("testMailboxSave", box1, box2); 366 } 367 368 private static String[] expectedAttachmentNames = 369 new String[] {"attachment1.doc", "attachment2.xls", "attachment3"}; 370 // The lengths need to be kept in ascending order 371 private static long[] expectedAttachmentSizes = new long[] {31415L, 97701L, 151213L}; 372 373 /* 374 * Returns null if the message has no body. 375 */ 376 private Body loadBodyForMessageId(long messageId) { 377 Cursor c = null; 378 try { 379 c = mMockContext.getContentResolver().query( 380 EmailContent.Body.CONTENT_URI, 381 EmailContent.Body.CONTENT_PROJECTION, 382 EmailContent.Body.MESSAGE_KEY + "=?", 383 new String[] {String.valueOf(messageId)}, 384 null); 385 int numBodies = c.getCount(); 386 assertTrue("at most one body", numBodies < 2); 387 return c.moveToFirst() ? EmailContent.getContent(c, Body.class) : null; 388 } finally { 389 c.close(); 390 } 391 } 392 393 /** 394 * Test simple message save/retrieve 395 * 396 * TODO: serverId vs. serverIntId 397 */ 398 public void testMessageSave() { 399 Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext); 400 long account1Id = account1.mId; 401 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 402 long box1Id = box1.mId; 403 404 // Test a simple message (saved with no body) 405 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 406 true, mMockContext); 407 long message1Id = message1.mId; 408 Message message1get = EmailContent.Message.restoreMessageWithId(mMockContext, message1Id); 409 ProviderTestUtils.assertMessageEqual("testMessageSave", message1, message1get); 410 411 // Test a message saved with a body 412 // Note that it will read back w/o the text & html so we must extract those 413 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 414 true, mMockContext); 415 long message2Id = message2.mId; 416 String text2 = message2.mText; 417 String html2 = message2.mHtml; 418 String textReply2 = message2.mTextReply; 419 String htmlReply2 = message2.mHtmlReply; 420 long sourceKey2 = message2.mSourceKey; 421 String introText2 = message2.mIntroText; 422 message2.mText = null; 423 message2.mHtml = null; 424 message2.mTextReply = null; 425 message2.mHtmlReply = null; 426 message2.mSourceKey = 0; 427 message2.mIntroText = null; 428 Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id); 429 ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get); 430 431 // Now see if there's a body saved with the right stuff 432 Body body2 = loadBodyForMessageId(message2Id); 433 assertEquals("body text", text2, body2.mTextContent); 434 assertEquals("body html", html2, body2.mHtmlContent); 435 assertEquals("reply text", textReply2, body2.mTextReply); 436 assertEquals("reply html", htmlReply2, body2.mHtmlReply); 437 assertEquals("source key", sourceKey2, body2.mSourceKey); 438 assertEquals("intro text", introText2, body2.mIntroText); 439 440 // Message with attachments and body 441 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true, 442 false, mMockContext); 443 ArrayList<Attachment> atts = new ArrayList<Attachment>(); 444 for (int i = 0; i < 3; i++) { 445 atts.add(ProviderTestUtils.setupAttachment( 446 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 447 false, mMockContext)); 448 } 449 message3.mAttachments = atts; 450 message3.save(mMockContext); 451 long message3Id = message3.mId; 452 453 // Now check the attachments; there should be three and they should match name and size 454 Cursor c = null; 455 try { 456 // Note that there is NO guarantee of the order of returned records in the general case, 457 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must 458 // be kept sorted by size (ascending) for this test to work properly 459 c = mMockContext.getContentResolver().query( 460 Attachment.CONTENT_URI, 461 Attachment.CONTENT_PROJECTION, 462 Attachment.MESSAGE_KEY + "=?", 463 new String[] { 464 String.valueOf(message3Id) 465 }, 466 Attachment.SIZE); 467 int numAtts = c.getCount(); 468 assertEquals(3, numAtts); 469 int i = 0; 470 while (c.moveToNext()) { 471 Attachment actual = EmailContent.getContent(c, Attachment.class); 472 ProviderTestUtils.assertAttachmentEqual("save-message3", atts.get(i), actual); 473 i++; 474 } 475 } finally { 476 c.close(); 477 } 478 479 // Message with attachments but no body 480 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, false, 481 false, mMockContext); 482 atts = new ArrayList<Attachment>(); 483 for (int i = 0; i < 3; i++) { 484 atts.add(ProviderTestUtils.setupAttachment( 485 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 486 false, mMockContext)); 487 } 488 message4.mAttachments = atts; 489 message4.save(mMockContext); 490 long message4Id = message4.mId; 491 492 // Now check the attachments; there should be three and they should match name and size 493 c = null; 494 495 try { 496 // Note that there is NO guarantee of the order of returned records in the general case, 497 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must 498 // be kept sorted by size (ascending) for this test to work properly 499 c = mMockContext.getContentResolver().query( 500 Attachment.CONTENT_URI, 501 Attachment.CONTENT_PROJECTION, 502 Attachment.MESSAGE_KEY + "=?", 503 new String[] { 504 String.valueOf(message4Id) 505 }, 506 Attachment.SIZE); 507 int numAtts = c.getCount(); 508 assertEquals(3, numAtts); 509 int i = 0; 510 while (c.moveToNext()) { 511 Attachment actual = EmailContent.getContent(c, Attachment.class); 512 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), actual); 513 i++; 514 } 515 } finally { 516 c.close(); 517 } 518 519 // test EmailContent.restoreAttachmentsWitdMessageId() 520 Attachment[] attachments = 521 Attachment.restoreAttachmentsWithMessageId(mMockContext, message4Id); 522 int size = attachments.length; 523 assertEquals(3, size); 524 for (int i = 0; i < size; ++i) { 525 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), attachments[i]); 526 } 527 } 528 529 /** 530 * Test that saving a message creates the proper snippet for that message 531 */ 532 public void testMessageSaveAddsSnippet() { 533 Account account = ProviderTestUtils.setupAccount("message-snippet", true, mMockContext); 534 Mailbox box = ProviderTestUtils.setupMailbox("box1", account.mId, true, mMockContext); 535 536 // Create a message without a body, unsaved 537 Message message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false, 538 false, mMockContext); 539 message.mText = "This is some text"; 540 message.mHtml = "<html>This is some text</html>"; 541 message.save(mMockContext); 542 Message restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId); 543 // We should have the plain text as the snippet 544 assertEquals(restoredMessage.mSnippet, Snippet.fromPlainText(message.mText)); 545 546 // Start again 547 message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false, 548 false, mMockContext); 549 message.mText = null; 550 message.mHtml = "<html>This is some text</html>"; 551 message.save(mMockContext); 552 restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId); 553 // We should have the plain text as the snippet 554 assertEquals(restoredMessage.mSnippet, Snippet.fromHtmlText(message.mHtml)); 555 } 556 557 /** 558 * TODO: update account 559 */ 560 561 /** 562 * TODO: update mailbox 563 */ 564 565 /** 566 * TODO: update message 567 */ 568 569 /** 570 * Test delete account 571 * TODO: hostauth 572 */ 573 public void testAccountDelete() { 574 Account account1 = ProviderTestUtils.setupAccount("account-delete-1", true, mMockContext); 575 long account1Id = account1.mId; 576 Account account2 = ProviderTestUtils.setupAccount("account-delete-2", true, mMockContext); 577 long account2Id = account2.mId; 578 579 // make sure there are two accounts 580 int numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 581 assertEquals(2, numBoxes); 582 583 // now delete one of them 584 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 585 mMockContext.getContentResolver().delete(uri, null, null); 586 587 // make sure there's only one account now 588 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 589 assertEquals(1, numBoxes); 590 591 // now delete the other one 592 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id); 593 mMockContext.getContentResolver().delete(uri, null, null); 594 595 // make sure there are no accounts now 596 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 597 assertEquals(0, numBoxes); 598 } 599 600 /** 601 * Test for Body.lookupBodyIdWithMessageId() 602 * Verifies that: 603 * - for a message without body, -1 is returned. 604 * - for a mesage with body, the id matches the one from loadBodyForMessageId. 605 */ 606 public void testLookupBodyIdWithMessageId() { 607 final ContentResolver resolver = mMockContext.getContentResolver(); 608 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 609 long account1Id = account1.mId; 610 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 611 long box1Id = box1.mId; 612 613 // 1. create message with no body, check that returned bodyId is -1 614 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 615 true, mMockContext); 616 long message1Id = message1.mId; 617 long bodyId1 = Body.lookupBodyIdWithMessageId(mMockContext, message1Id); 618 assertEquals(bodyId1, -1); 619 620 // 2. create message with body, check that returned bodyId is correct 621 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 622 true, mMockContext); 623 long message2Id = message2.mId; 624 long bodyId2 = Body.lookupBodyIdWithMessageId(mMockContext, message2Id); 625 Body body = loadBodyForMessageId(message2Id); 626 assertNotNull(body); 627 assertEquals(body.mId, bodyId2); 628 } 629 630 /** 631 * Test for Body.updateBodyWithMessageId(). 632 * 1. - create message without body, 633 * - update its body (set TEXT_CONTENT) 634 * - check correct updated body is read back 635 * 636 * 2. - create message with body, 637 * - update body (set TEXT_CONTENT) 638 * - check correct updated body is read back 639 */ 640 public void testUpdateBodyWithMessageId() { 641 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 642 long account1Id = account1.mId; 643 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 644 long box1Id = box1.mId; 645 646 final String textContent = "foobar some odd text"; 647 final String htmlContent = "and some html"; 648 final String textReply = "plain text reply"; 649 final String htmlReply = "or the html reply"; 650 final String introText = "fred wrote:"; 651 652 ContentValues values = new ContentValues(); 653 values.put(BodyColumns.TEXT_CONTENT, textContent); 654 values.put(BodyColumns.HTML_CONTENT, htmlContent); 655 values.put(BodyColumns.TEXT_REPLY, textReply); 656 values.put(BodyColumns.HTML_REPLY, htmlReply); 657 values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17); 658 values.put(BodyColumns.INTRO_TEXT, introText); 659 660 // 1 661 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 662 true, mMockContext); 663 long message1Id = message1.mId; 664 Body body1 = loadBodyForMessageId(message1Id); 665 assertNull(body1); 666 Body.updateBodyWithMessageId(mMockContext, message1Id, values); 667 body1 = loadBodyForMessageId(message1Id); 668 assertNotNull(body1); 669 assertEquals(body1.mTextContent, textContent); 670 assertEquals(body1.mHtmlContent, htmlContent); 671 assertEquals(body1.mTextReply, textReply); 672 assertEquals(body1.mHtmlReply, htmlReply); 673 assertEquals(body1.mSourceKey, 17); 674 assertEquals(body1.mIntroText, introText); 675 676 // 2 677 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 678 true, mMockContext); 679 long message2Id = message2.mId; 680 Body body2 = loadBodyForMessageId(message2Id); 681 assertNotNull(body2); 682 assertTrue(!body2.mTextContent.equals(textContent)); 683 Body.updateBodyWithMessageId(mMockContext, message2Id, values); 684 body2 = loadBodyForMessageId(message1Id); 685 assertNotNull(body2); 686 assertEquals(body2.mTextContent, textContent); 687 assertEquals(body2.mHtmlContent, htmlContent); 688 assertEquals(body2.mTextReply, textReply); 689 assertEquals(body2.mHtmlReply, htmlReply); 690 assertEquals(body2.mSourceKey, 17); 691 assertEquals(body2.mIntroText, introText); 692 } 693 694 /** 695 * Test body retrieve methods 696 */ 697 public void testBodyRetrieve() { 698 // No account needed 699 // No mailbox needed 700 Message message1 = ProviderTestUtils.setupMessage("bodyretrieve", 1, 1, true, 701 true, mMockContext); 702 long messageId = message1.mId; 703 704 assertEquals(message1.mText, 705 Body.restoreBodyTextWithMessageId(mMockContext, messageId)); 706 assertEquals(message1.mHtml, 707 Body.restoreBodyHtmlWithMessageId(mMockContext, messageId)); 708 assertEquals(message1.mTextReply, 709 Body.restoreReplyTextWithMessageId(mMockContext, messageId)); 710 assertEquals(message1.mHtmlReply, 711 Body.restoreReplyHtmlWithMessageId(mMockContext, messageId)); 712 assertEquals(message1.mIntroText, 713 Body.restoreIntroTextWithMessageId(mMockContext, messageId)); 714 assertEquals(message1.mSourceKey, 715 Body.restoreBodySourceKey(mMockContext, messageId)); 716 } 717 718 /** 719 * Test delete body. 720 * 1. create message without body (message id 1) 721 * 2. create message with body (message id 2. The body has _id 1 and messageKey 2). 722 * 3. delete first message. 723 * 4. verify that body for message 2 has not been deleted. 724 * 5. delete message 2, verify body is deleted. 725 */ 726 public void testDeleteBody() { 727 final ContentResolver resolver = mMockContext.getContentResolver(); 728 729 // Create account and mailboxes 730 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 731 long account1Id = account1.mId; 732 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 733 long box1Id = box1.mId; 734 735 // 1. create message without body 736 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 737 true, mMockContext); 738 long message1Id = message1.mId; 739 740 // 2. create message with body 741 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 742 true, mMockContext); 743 long message2Id = message2.mId; 744 // verify body is there 745 assertNotNull(loadBodyForMessageId(message2Id)); 746 747 // 3. delete first message 748 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null); 749 750 // 4. verify body for second message wasn't deleted 751 assertNotNull(loadBodyForMessageId(message2Id)); 752 753 // 5. delete second message, check its body is deleted 754 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message2Id), null, null); 755 assertNull(loadBodyForMessageId(message2Id)); 756 } 757 758 /** 759 * Test delete orphan bodies. 760 * 1. create message without body (message id 1) 761 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2). 762 * 3. delete first message. 763 * 4. delete some other mailbox -- this triggers delete orphan bodies. 764 * 5. verify that body for message 2 has not been deleted. 765 */ 766 public void testDeleteOrphanBodies() { 767 final ContentResolver resolver = mMockContext.getContentResolver(); 768 769 // Create account and two mailboxes 770 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 771 long account1Id = account1.mId; 772 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 773 long box1Id = box1.mId; 774 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext); 775 long box2Id = box2.mId; 776 777 // 1. create message without body 778 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 779 true, mMockContext); 780 long message1Id = message1.mId; 781 782 // 2. create message with body 783 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 784 true, mMockContext); 785 long message2Id = message2.mId; 786 //verify body is there 787 assertNotNull(loadBodyForMessageId(message2Id)); 788 789 // 3. delete first message 790 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null); 791 792 // 4. delete some mailbox (because it triggers "delete orphan bodies") 793 resolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id), null, null); 794 795 // 5. verify body for second message wasn't deleted during "delete orphan bodies" 796 assertNotNull(loadBodyForMessageId(message2Id)); 797 } 798 799 /** 800 * Test delete orphan messages 801 * 1. create message without body (message id 1) 802 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2). 803 * 3. delete first message. 804 * 4. delete some other mailbox -- this triggers delete orphan bodies. 805 * 5. verify that body for message 2 has not been deleted. 806 */ 807 public void testDeleteOrphanMessages() { 808 final ContentResolver resolver = mMockContext.getContentResolver(); 809 final Context context = mMockContext; 810 811 // Create account and two mailboxes 812 Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context); 813 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 814 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context); 815 816 // Create 4 messages in box1 817 Message msg1_1 = 818 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context); 819 Message msg1_2 = 820 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context); 821 Message msg1_3 = 822 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context); 823 Message msg1_4 = 824 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context); 825 826 // Create 4 messages in box2 827 Message msg2_1 = 828 ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context); 829 Message msg2_2 = 830 ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context); 831 Message msg2_3 = 832 ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context); 833 Message msg2_4 = 834 ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context); 835 836 // Delete 2 from each mailbox 837 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_1.mId), 838 null, null); 839 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_2.mId), 840 null, null); 841 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_1.mId), 842 null, null); 843 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_2.mId), 844 null, null); 845 846 // There should be 4 items in the deleted item table 847 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 848 849 // Update 2 from each mailbox 850 ContentValues v = new ContentValues(); 851 v.put(MessageColumns.DISPLAY_NAME, "--updated--"); 852 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_3.mId), 853 v, null, null); 854 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_4.mId), 855 v, null, null); 856 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_3.mId), 857 v, null, null); 858 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_4.mId), 859 v, null, null); 860 861 // There should be 4 items in the updated item table 862 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 863 864 // Manually add 2 messages from a "deleted" mailbox to deleted and updated tables 865 // Use a value > 2 for the deleted box id 866 long delBoxId = 10; 867 // Create 4 messages in the "deleted" mailbox 868 Message msgX_A = 869 ProviderTestUtils.setupMessage("messageA", acct.mId, delBoxId, false, false, context); 870 Message msgX_B = 871 ProviderTestUtils.setupMessage("messageB", acct.mId, delBoxId, false, false, context); 872 Message msgX_C = 873 ProviderTestUtils.setupMessage("messageC", acct.mId, delBoxId, false, false, context); 874 Message msgX_D = 875 ProviderTestUtils.setupMessage("messageD", acct.mId, delBoxId, false, false, context); 876 877 ContentValues cv; 878 // We have to assign id's manually because there are no autoincrement id's for these tables 879 // Start with an id that won't exist, since id's in these tables must be unique 880 long msgId = 10; 881 // It's illegal to manually insert these, so we need to catch the exception 882 // NOTE: The insert succeeds, and then throws the exception 883 try { 884 cv = msgX_A.toContentValues(); 885 cv.put(EmailContent.RECORD_ID, msgId++); 886 resolver.insert(Message.DELETED_CONTENT_URI, cv); 887 } catch (IllegalArgumentException e) { 888 } 889 try { 890 cv = msgX_B.toContentValues(); 891 cv.put(EmailContent.RECORD_ID, msgId++); 892 resolver.insert(Message.DELETED_CONTENT_URI, cv); 893 } catch (IllegalArgumentException e) { 894 } 895 try { 896 cv = msgX_C.toContentValues(); 897 cv.put(EmailContent.RECORD_ID, msgId++); 898 resolver.insert(Message.UPDATED_CONTENT_URI, cv); 899 } catch (IllegalArgumentException e) { 900 } 901 try { 902 cv = msgX_D.toContentValues(); 903 cv.put(EmailContent.RECORD_ID, msgId++); 904 resolver.insert(Message.UPDATED_CONTENT_URI, cv); 905 } catch (IllegalArgumentException e) { 906 } 907 908 // There should be 6 items in the deleted and updated tables 909 assertEquals(6, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 910 assertEquals(6, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 911 912 // Delete the orphans 913 EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context), 914 Message.DELETED_TABLE_NAME); 915 EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context), 916 Message.UPDATED_TABLE_NAME); 917 918 // There should now be 4 messages in each of the deleted and updated tables again 919 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 920 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 921 } 922 923 /** 924 * Test delete mailbox 925 */ 926 public void testMailboxDelete() { 927 Account account1 = ProviderTestUtils.setupAccount("mailbox-delete", true, mMockContext); 928 long account1Id = account1.mId; 929 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 930 long box1Id = box1.mId; 931 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext); 932 long box2Id = box2.mId; 933 934 String selection = EmailContent.MailboxColumns.ACCOUNT_KEY + "=?"; 935 String[] selArgs = new String[] { String.valueOf(account1Id) }; 936 937 // make sure there are two mailboxes 938 int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 939 assertEquals(2, numBoxes); 940 941 // now delete one of them 942 Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id); 943 mMockContext.getContentResolver().delete(uri, null, null); 944 945 // make sure there's only one mailbox now 946 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 947 assertEquals(1, numBoxes); 948 949 // now delete the other one 950 uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id); 951 mMockContext.getContentResolver().delete(uri, null, null); 952 953 // make sure there are no mailboxes now 954 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 955 assertEquals(0, numBoxes); 956 } 957 958 /** 959 * Test delete message 960 * TODO: body 961 * TODO: attachments 962 */ 963 public void testMessageDelete() { 964 Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mMockContext); 965 long account1Id = account1.mId; 966 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 967 long box1Id = box1.mId; 968 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 969 true, mMockContext); 970 long message1Id = message1.mId; 971 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 972 true, mMockContext); 973 long message2Id = message2.mId; 974 975 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " + 976 EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 977 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) }; 978 979 // make sure there are two messages 980 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 981 assertEquals(2, numMessages); 982 983 // now delete one of them 984 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 985 mMockContext.getContentResolver().delete(uri, null, null); 986 987 // make sure there's only one message now 988 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 989 assertEquals(1, numMessages); 990 991 // now delete the other one 992 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 993 mMockContext.getContentResolver().delete(uri, null, null); 994 995 // make sure there are no messages now 996 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 997 assertEquals(0, numMessages); 998 } 999 1000 /** 1001 * Test delete synced message 1002 * TODO: body 1003 * TODO: attachments 1004 */ 1005 public void testSyncedMessageDelete() { 1006 Account account1 = ProviderTestUtils.setupAccount("synced-message-delete", true, 1007 mMockContext); 1008 long account1Id = account1.mId; 1009 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1010 long box1Id = box1.mId; 1011 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 1012 true, mMockContext); 1013 long message1Id = message1.mId; 1014 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 1015 true, mMockContext); 1016 long message2Id = message2.mId; 1017 1018 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " 1019 + EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 1020 String[] selArgs = new String[] { 1021 String.valueOf(account1Id), String.valueOf(box1Id) 1022 }; 1023 1024 // make sure there are two messages 1025 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1026 assertEquals(2, numMessages); 1027 1028 // make sure we start with no synced deletions 1029 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1030 selArgs); 1031 assertEquals(0, numMessages); 1032 1033 // now delete one of them SYNCED 1034 Uri uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1Id); 1035 mMockContext.getContentResolver().delete(uri, null, null); 1036 1037 // make sure there's only one message now 1038 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1039 assertEquals(1, numMessages); 1040 1041 // make sure there's one synced deletion now 1042 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1043 selArgs); 1044 assertEquals(1, numMessages); 1045 1046 // now delete the other one NOT SYNCED 1047 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 1048 mMockContext.getContentResolver().delete(uri, null, null); 1049 1050 // make sure there are no messages now 1051 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1052 assertEquals(0, numMessages); 1053 1054 // make sure there's still one deletion now 1055 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1056 selArgs); 1057 assertEquals(1, numMessages); 1058 } 1059 1060 /** 1061 * Test message update 1062 * TODO: body 1063 * TODO: attachments 1064 */ 1065 public void testMessageUpdate() { 1066 Account account1 = ProviderTestUtils.setupAccount("message-update", true, mMockContext); 1067 long account1Id = account1.mId; 1068 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1069 long box1Id = box1.mId; 1070 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 1071 true, mMockContext); 1072 long message1Id = message1.mId; 1073 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 1074 true, mMockContext); 1075 long message2Id = message2.mId; 1076 ContentResolver cr = mMockContext.getContentResolver(); 1077 1078 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " 1079 + EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 1080 String[] selArgs = new String[] { 1081 String.valueOf(account1Id), String.valueOf(box1Id) 1082 }; 1083 1084 // make sure there are two messages 1085 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1086 assertEquals(2, numMessages); 1087 1088 // change the first one 1089 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 1090 ContentValues cv = new ContentValues(); 1091 cv.put(MessageColumns.FROM_LIST, "from-list"); 1092 cr.update(uri, cv, null, null); 1093 1094 // make sure there's no updated message 1095 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1096 selArgs); 1097 assertEquals(0, numMessages); 1098 1099 // get the message back from the provider, make sure the change "stuck" 1100 Message restoredMessage = Message.restoreMessageWithId(mMockContext, message1Id); 1101 assertEquals("from-list", restoredMessage.mFrom); 1102 1103 // change the second one 1104 uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id); 1105 cv = new ContentValues(); 1106 cv.put(MessageColumns.FROM_LIST, "from-list"); 1107 cr.update(uri, cv, null, null); 1108 1109 // make sure there's one updated message 1110 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1111 selArgs); 1112 assertEquals(1, numMessages); 1113 1114 // get the message back from the provider, make sure the change "stuck", 1115 // as before 1116 restoredMessage = Message.restoreMessageWithId(mMockContext, message2Id); 1117 assertEquals("from-list", restoredMessage.mFrom); 1118 1119 // get the original message back from the provider 1120 Cursor c = cr.query(Message.UPDATED_CONTENT_URI, Message.CONTENT_PROJECTION, null, null, 1121 null); 1122 try { 1123 assertTrue(c.moveToFirst()); 1124 Message originalMessage = EmailContent.getContent(c, Message.class); 1125 // make sure this has the original value 1126 assertEquals("from message2", originalMessage.mFrom); 1127 // Should only be one 1128 assertFalse(c.moveToNext()); 1129 } finally { 1130 c.close(); 1131 } 1132 1133 // delete the second message 1134 cr.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id), null, null); 1135 1136 // hey, presto! the change should be gone 1137 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1138 selArgs); 1139 assertEquals(0, numMessages); 1140 1141 // and there should now be a deleted record 1142 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1143 selArgs); 1144 assertEquals(1, numMessages); 1145 } 1146 1147 /** 1148 * TODO: cascaded delete account 1149 * TODO: hostauth 1150 * TODO: body 1151 * TODO: attachments 1152 * TODO: create other account, mailbox & messages and confirm the right objects were deleted 1153 */ 1154 public void testCascadeDeleteAccount() { 1155 Account account1 = ProviderTestUtils.setupAccount("account-delete-cascade", true, 1156 mMockContext); 1157 long account1Id = account1.mId; 1158 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1159 long box1Id = box1.mId; 1160 /* Message message1 = */ ProviderTestUtils.setupMessage("message1", account1Id, box1Id, 1161 false, true, mMockContext); 1162 /* Message message2 = */ ProviderTestUtils.setupMessage("message2", account1Id, box1Id, 1163 false, true, mMockContext); 1164 1165 // make sure there is one account, one mailbox, and two messages 1166 int numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 1167 assertEquals(1, numAccounts); 1168 int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null); 1169 assertEquals(1, numBoxes); 1170 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1171 assertEquals(2, numMessages); 1172 1173 // delete the account 1174 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 1175 mMockContext.getContentResolver().delete(uri, null, null); 1176 1177 // make sure there are no accounts, mailboxes, or messages 1178 numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 1179 assertEquals(0, numAccounts); 1180 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null); 1181 assertEquals(0, numBoxes); 1182 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1183 assertEquals(0, numMessages); 1184 } 1185 1186 /** 1187 * Test cascaded delete mailbox 1188 * TODO: body 1189 * TODO: attachments 1190 * TODO: create other mailbox & messages and confirm the right objects were deleted 1191 */ 1192 public void testCascadeDeleteMailbox() { 1193 Account account1 = ProviderTestUtils.setupAccount("mailbox-delete-cascade", true, 1194 mMockContext); 1195 long account1Id = account1.mId; 1196 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1197 long box1Id = box1.mId; 1198 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, 1199 false, true, mMockContext); 1200 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, 1201 false, true, mMockContext); 1202 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, 1203 false, true, mMockContext); 1204 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, 1205 false, true, mMockContext); 1206 ProviderTestUtils.setupMessage("message5", account1Id, box1Id, false, true, mMockContext); 1207 ProviderTestUtils.setupMessage("message6", account1Id, box1Id, false, true, mMockContext); 1208 1209 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " + 1210 EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 1211 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) }; 1212 1213 // make sure there are six messages 1214 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1215 assertEquals(6, numMessages); 1216 1217 ContentValues cv = new ContentValues(); 1218 cv.put(Message.SERVER_ID, "SERVER_ID"); 1219 ContentResolver resolver = mMockContext.getContentResolver(); 1220 1221 // Update two messages 1222 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1.mId), 1223 cv, null, null); 1224 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2.mId), 1225 cv, null, null); 1226 // Delete two messages 1227 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message3.mId), 1228 null, null); 1229 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message4.mId), 1230 null, null); 1231 1232 // There should now be two messages in updated/deleted, and 4 in messages 1233 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1234 assertEquals(4, numMessages); 1235 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1236 selArgs); 1237 assertEquals(2, numMessages); 1238 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1239 selArgs); 1240 assertEquals(2, numMessages); 1241 1242 // now delete the mailbox 1243 Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id); 1244 resolver.delete(uri, null, null); 1245 1246 // there should now be zero messages in all three tables 1247 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1248 assertEquals(0, numMessages); 1249 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1250 selArgs); 1251 assertEquals(0, numMessages); 1252 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1253 selArgs); 1254 assertEquals(0, numMessages); 1255 } 1256 1257 /** 1258 * Test cascaded delete message 1259 * Confirms that deleting a message will also delete its body & attachments 1260 */ 1261 public void testCascadeMessageDelete() { 1262 Account account1 = ProviderTestUtils.setupAccount("message-cascade", true, mMockContext); 1263 long account1Id = account1.mId; 1264 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1265 long box1Id = box1.mId; 1266 1267 // Each message has a body, and also give each 2 attachments 1268 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 1269 false, mMockContext); 1270 ArrayList<Attachment> atts = new ArrayList<Attachment>(); 1271 for (int i = 0; i < 2; i++) { 1272 atts.add(ProviderTestUtils.setupAttachment( 1273 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 1274 false, mMockContext)); 1275 } 1276 message1.mAttachments = atts; 1277 message1.save(mMockContext); 1278 long message1Id = message1.mId; 1279 1280 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, true, 1281 false, mMockContext); 1282 atts = new ArrayList<Attachment>(); 1283 for (int i = 0; i < 2; i++) { 1284 atts.add(ProviderTestUtils.setupAttachment( 1285 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 1286 false, mMockContext)); 1287 } 1288 message2.mAttachments = atts; 1289 message2.save(mMockContext); 1290 long message2Id = message2.mId; 1291 1292 // Set up to test total counts of bodies & attachments for our test messages 1293 String bodySelection = BodyColumns.MESSAGE_KEY + " IN (?,?)"; 1294 String attachmentSelection = AttachmentColumns.MESSAGE_KEY + " IN (?,?)"; 1295 String[] selArgs = new String[] { String.valueOf(message1Id), String.valueOf(message2Id) }; 1296 1297 // make sure there are two bodies 1298 int numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1299 assertEquals(2, numBodies); 1300 1301 // make sure there are four attachments 1302 int numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1303 attachmentSelection, selArgs); 1304 assertEquals(4, numAttachments); 1305 1306 // now delete one of the messages 1307 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 1308 mMockContext.getContentResolver().delete(uri, null, null); 1309 1310 // there should be one body and two attachments 1311 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1312 assertEquals(1, numBodies); 1313 1314 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1315 attachmentSelection, selArgs); 1316 assertEquals(2, numAttachments); 1317 1318 // now delete the other message 1319 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 1320 mMockContext.getContentResolver().delete(uri, null, null); 1321 1322 // make sure there are no bodies or attachments 1323 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1324 assertEquals(0, numBodies); 1325 1326 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1327 attachmentSelection, selArgs); 1328 assertEquals(0, numAttachments); 1329 } 1330 1331 /** 1332 * Test that our unique file name algorithm works as expected. Since this test requires an 1333 * SD card, we check the environment first, and return immediately if none is mounted. 1334 * @throws IOException 1335 */ 1336 public void testCreateUniqueFile() throws IOException { 1337 // Delete existing files, if they exist 1338 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 1339 return; 1340 } 1341 try { 1342 String fileName = "A11achm3n1.doc"; 1343 File uniqueFile = Attachment.createUniqueFile(fileName); 1344 assertEquals(fileName, uniqueFile.getName()); 1345 if (uniqueFile.createNewFile()) { 1346 uniqueFile = Attachment.createUniqueFile(fileName); 1347 assertEquals("A11achm3n1-2.doc", uniqueFile.getName()); 1348 if (uniqueFile.createNewFile()) { 1349 uniqueFile = Attachment.createUniqueFile(fileName); 1350 assertEquals("A11achm3n1-3.doc", uniqueFile.getName()); 1351 } 1352 } 1353 fileName = "A11achm3n1"; 1354 uniqueFile = Attachment.createUniqueFile(fileName); 1355 assertEquals(fileName, uniqueFile.getName()); 1356 if (uniqueFile.createNewFile()) { 1357 uniqueFile = Attachment.createUniqueFile(fileName); 1358 assertEquals("A11achm3n1-2", uniqueFile.getName()); 1359 } 1360 } finally { 1361 File directory = Environment.getExternalStorageDirectory(); 1362 // These are the files that should be created earlier in the test. Make sure 1363 // they are deleted for the next go-around 1364 String[] fileNames = new String[] {"A11achm3n1.doc", "A11achm3n1-2.doc", "A11achm3n1"}; 1365 int length = fileNames.length; 1366 for (int i = 0; i < length; i++) { 1367 File file = new File(directory, fileNames[i]); 1368 if (file.exists()) { 1369 file.delete(); 1370 } 1371 } 1372 } 1373 } 1374 1375 /** 1376 * Test retrieving attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI) 1377 */ 1378 public void testGetAttachmentByMessageIdUri() { 1379 1380 // Note, we don't strictly need accounts, mailboxes or messages to run this test. 1381 Attachment a1 = ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext); 1382 Attachment a2 = ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext); 1383 ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext); 1384 ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext); 1385 1386 // Now ask for the attachments of message id=1 1387 // Note: Using the "sort by size" trick to bring them back in expected order 1388 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1); 1389 Cursor c = mMockContext.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION, 1390 null, null, Attachment.SIZE); 1391 assertEquals(2, c.getCount()); 1392 1393 try { 1394 c.moveToFirst(); 1395 Attachment a1Get = EmailContent.getContent(c, Attachment.class); 1396 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-1", a1, a1Get); 1397 c.moveToNext(); 1398 Attachment a2Get = EmailContent.getContent(c, Attachment.class); 1399 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-2", a2, a2Get); 1400 } finally { 1401 c.close(); 1402 } 1403 } 1404 1405 /** 1406 * Test deleting attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI) 1407 */ 1408 public void testDeleteAttachmentByMessageIdUri() { 1409 ContentResolver mockResolver = mMockContext.getContentResolver(); 1410 1411 // Note, we don't strictly need accounts, mailboxes or messages to run this test. 1412 ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext); 1413 ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext); 1414 Attachment a3 = ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext); 1415 Attachment a4 = ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext); 1416 1417 // Delete all attachments for message id=1 1418 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1); 1419 mockResolver.delete(uri, null, null); 1420 1421 // Read back all attachments and confirm that we have the expected remaining attachments 1422 // (the attachments that are set for message id=2). Note order-by size to simplify test. 1423 Cursor c = mockResolver.query(Attachment.CONTENT_URI, Attachment.CONTENT_PROJECTION, 1424 null, null, Attachment.SIZE); 1425 assertEquals(2, c.getCount()); 1426 1427 try { 1428 c.moveToFirst(); 1429 Attachment a3Get = EmailContent.getContent(c, Attachment.class); 1430 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-3", a3, a3Get); 1431 c.moveToNext(); 1432 Attachment a4Get = EmailContent.getContent(c, Attachment.class); 1433 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-4", a4, a4Get); 1434 } finally { 1435 c.close(); 1436 } 1437 } 1438 1439 /** 1440 * Tests of default account behavior 1441 * 1442 * 1. Simple set/get 1443 * 2. Moving default between 3 accounts 1444 * 3. Delete default, make sure another becomes default 1445 */ 1446 public void testSetGetDefaultAccount() { 1447 // There should be no default account if there are no accounts 1448 long defaultAccountId = Account.getDefaultAccountId(mMockContext); 1449 assertEquals(-1, defaultAccountId); 1450 1451 Account account1 = ProviderTestUtils.setupAccount("account-default-1", true, mMockContext); 1452 long account1Id = account1.mId; 1453 Account account2 = ProviderTestUtils.setupAccount("account-default-2", true, mMockContext); 1454 long account2Id = account2.mId; 1455 Account account3 = ProviderTestUtils.setupAccount("account-default-3", true, mMockContext); 1456 long account3Id = account3.mId; 1457 1458 // With three accounts, but none marked default, confirm that some default account 1459 // is returned. Which one is undefined here. 1460 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1461 assertTrue(defaultAccountId == account1Id 1462 || defaultAccountId == account2Id 1463 || defaultAccountId == account3Id); 1464 1465 updateIsDefault(account1, true); 1466 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1467 assertEquals(account1Id, defaultAccountId); 1468 1469 updateIsDefault(account2, true); 1470 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1471 assertEquals(account2Id, defaultAccountId); 1472 1473 updateIsDefault(account3, true); 1474 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1475 assertEquals(account3Id, defaultAccountId); 1476 1477 // Now delete a non-default account and confirm no change 1478 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 1479 mMockContext.getContentResolver().delete(uri, null, null); 1480 1481 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1482 assertEquals(account3Id, defaultAccountId); 1483 1484 // Now confirm deleting the default account and it switches to another one 1485 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account3Id); 1486 mMockContext.getContentResolver().delete(uri, null, null); 1487 1488 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1489 assertEquals(account2Id, defaultAccountId); 1490 1491 // Now delete the final account and confirm there are no default accounts again 1492 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id); 1493 mMockContext.getContentResolver().delete(uri, null, null); 1494 1495 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1496 assertEquals(-1, defaultAccountId); 1497 } 1498 1499 private void updateIsDefault(Account account, boolean newState) { 1500 account.setDefaultAccount(newState); 1501 ContentValues cv = new ContentValues(); 1502 cv.put(AccountColumns.IS_DEFAULT, account.mIsDefault); 1503 account.update(mMockContext, cv); 1504 } 1505 1506 public static Message setupUnreadMessage(String name, long accountId, long mailboxId, 1507 boolean addBody, boolean saveIt, Context context) { 1508 Message msg = 1509 ProviderTestUtils.setupMessage(name, accountId, mailboxId, addBody, false, context); 1510 msg.mFlagRead = false; 1511 if (saveIt) { 1512 msg.save(context); 1513 } 1514 return msg; 1515 } 1516 1517 public void testUnreadCountTriggers() { 1518 // Start with one account and three mailboxes 1519 Account account = ProviderTestUtils.setupAccount("triggers", true, mMockContext); 1520 Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext); 1521 Mailbox boxB = ProviderTestUtils.setupMailbox("boxB", account.mId, true, mMockContext); 1522 Mailbox boxC = ProviderTestUtils.setupMailbox("boxC", account.mId, true, mMockContext); 1523 1524 // Make sure there are no unreads 1525 assertEquals(0, getUnreadCount(boxA.mId)); 1526 assertEquals(0, getUnreadCount(boxB.mId)); 1527 assertEquals(0, getUnreadCount(boxC.mId)); 1528 1529 // Create 4 unread messages (only 3 named) in boxA 1530 Message message1 = setupUnreadMessage("message1", account.mId, boxA.mId, 1531 false, true, mMockContext); 1532 Message message2= setupUnreadMessage("message2", account.mId, boxA.mId, 1533 false, true, mMockContext); 1534 Message message3 = setupUnreadMessage("message3", account.mId, boxA.mId, 1535 false, true, mMockContext); 1536 setupUnreadMessage("message4", account.mId, boxC.mId, false, true, mMockContext); 1537 1538 // Make sure the unreads are where we expect them 1539 assertEquals(3, getUnreadCount(boxA.mId)); 1540 assertEquals(0, getUnreadCount(boxB.mId)); 1541 assertEquals(1, getUnreadCount(boxC.mId)); 1542 1543 // After deleting message 1, the count in box A should be decremented (to 2) 1544 ContentResolver cr = mMockContext.getContentResolver(); 1545 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1.mId); 1546 cr.delete(uri, null, null); 1547 assertEquals(2, getUnreadCount(boxA.mId)); 1548 assertEquals(0, getUnreadCount(boxB.mId)); 1549 assertEquals(1, getUnreadCount(boxC.mId)); 1550 1551 // Move message 2 to box B, leaving 1 in box A and 1 in box B 1552 message2.mMailboxKey = boxB.mId; 1553 ContentValues cv = new ContentValues(); 1554 cv.put(MessageColumns.MAILBOX_KEY, boxB.mId); 1555 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message2.mId), cv, null, null); 1556 assertEquals(1, getUnreadCount(boxA.mId)); 1557 assertEquals(1, getUnreadCount(boxB.mId)); 1558 assertEquals(1, getUnreadCount(boxC.mId)); 1559 1560 // Mark message 3 (from box A) read, leaving 0 in box A 1561 cv.clear(); 1562 cv.put(MessageColumns.FLAG_READ, 1); 1563 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1564 assertEquals(0, getUnreadCount(boxA.mId)); 1565 assertEquals(1, getUnreadCount(boxB.mId)); 1566 assertEquals(1, getUnreadCount(boxC.mId)); 1567 1568 // Move message 3 to box C; should be no change (it's read) 1569 message3.mMailboxKey = boxC.mId; 1570 cv.clear(); 1571 cv.put(MessageColumns.MAILBOX_KEY, boxC.mId); 1572 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1573 assertEquals(0, getUnreadCount(boxA.mId)); 1574 assertEquals(1, getUnreadCount(boxB.mId)); 1575 assertEquals(1, getUnreadCount(boxC.mId)); 1576 1577 // Mark message 3 unread; it's now in box C, so that box's count should go up to 3 1578 cv.clear(); 1579 cv.put(MessageColumns.FLAG_READ, 0); 1580 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1581 assertEquals(0, getUnreadCount(boxA.mId)); 1582 assertEquals(1, getUnreadCount(boxB.mId)); 1583 assertEquals(2, getUnreadCount(boxC.mId)); 1584 } 1585 1586 /** 1587 * Test for EmailProvider.createIndex(). 1588 * Check that it returns exacly the same string as the one used previously for index creation. 1589 */ 1590 public void testCreateIndex() { 1591 String oldStr = "create index message_" + MessageColumns.TIMESTAMP 1592 + " on " + Message.TABLE_NAME + " (" + MessageColumns.TIMESTAMP + ");"; 1593 String newStr = EmailProvider.createIndex(Message.TABLE_NAME, MessageColumns.TIMESTAMP); 1594 assertEquals(newStr, oldStr); 1595 } 1596 1597 public void testIdAddToField() { 1598 ContentResolver cr = mMockContext.getContentResolver(); 1599 ContentValues cv = new ContentValues(); 1600 1601 // Try changing the newMessageCount of an account 1602 Account account = ProviderTestUtils.setupAccount("field-add", true, mMockContext); 1603 int startCount = account.mNewMessageCount; 1604 // "field" and "add" are the two required elements 1605 cv.put(EmailContent.FIELD_COLUMN_NAME, AccountColumns.NEW_MESSAGE_COUNT); 1606 cv.put(EmailContent.ADD_COLUMN_NAME, 17); 1607 cr.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, account.mId), 1608 cv, null, null); 1609 Account restoredAccount = Account.restoreAccountWithId(mMockContext, account.mId); 1610 assertEquals(17 + startCount, restoredAccount.mNewMessageCount); 1611 cv.put(EmailContent.ADD_COLUMN_NAME, -11); 1612 cr.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, account.mId), 1613 cv, null, null); 1614 restoredAccount = Account.restoreAccountWithId(mMockContext, account.mId); 1615 assertEquals(17 - 11 + startCount, restoredAccount.mNewMessageCount); 1616 1617 // Now try with a mailbox 1618 Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext); 1619 assertEquals(0, boxA.mUnreadCount); 1620 cv.put(EmailContent.FIELD_COLUMN_NAME, MailboxColumns.UNREAD_COUNT); 1621 cv.put(EmailContent.ADD_COLUMN_NAME, 11); 1622 cr.update(ContentUris.withAppendedId(Mailbox.ADD_TO_FIELD_URI, boxA.mId), cv, null, null); 1623 Mailbox restoredBoxA = Mailbox.restoreMailboxWithId(mMockContext, boxA.mId); 1624 assertEquals(11, restoredBoxA.mUnreadCount); 1625 } 1626 1627 public void testDatabaseCorruptionRecovery() { 1628 final ContentResolver resolver = mMockContext.getContentResolver(); 1629 final Context context = mMockContext; 1630 1631 // Create account and two mailboxes 1632 Account acct = ProviderTestUtils.setupAccount("acct1", true, context); 1633 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 1634 1635 // Create 4 messages in box1 with bodies 1636 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context); 1637 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context); 1638 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context); 1639 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context); 1640 1641 // Confirm there are four messages 1642 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1643 assertEquals(4, count); 1644 // Confirm there are four bodies 1645 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1646 assertEquals(4, count); 1647 1648 // Find the EmailProvider.db file 1649 File dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME); 1650 // The EmailProvider.db database should exist (the provider creates it automatically) 1651 assertTrue(dbFile != null); 1652 assertTrue(dbFile.exists()); 1653 // Delete it, and confirm it is gone 1654 assertTrue(dbFile.delete()); 1655 assertFalse(dbFile.exists()); 1656 1657 // Find the EmailProviderBody.db file 1658 dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME); 1659 // The EmailProviderBody.db database should still exist 1660 assertTrue(dbFile != null); 1661 assertTrue(dbFile.exists()); 1662 1663 // URI to uncache the databases 1664 // This simulates the Provider starting up again (otherwise, it will still be pointing to 1665 // the already opened files) 1666 // Note that we only have access to the EmailProvider via the ContentResolver; therefore, 1667 // we cannot directly call into the provider and use a URI for this 1668 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null); 1669 1670 // TODO We should check for the deletion of attachment files once this is implemented in 1671 // the provider 1672 1673 // Explanation for what happens below... 1674 // The next time the database is created by the provider, it will notice that there's 1675 // already a EmailProviderBody.db file. In this case, it will delete that database to 1676 // ensure that both are in sync (and empty) 1677 1678 // Confirm there are no bodies 1679 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1680 assertEquals(0, count); 1681 1682 // Confirm there are no messages 1683 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1684 assertEquals(0, count); 1685 } 1686 1687 public void testBodyDatabaseCorruptionRecovery() { 1688 final ContentResolver resolver = mMockContext.getContentResolver(); 1689 final Context context = mMockContext; 1690 1691 // Create account and two mailboxes 1692 Account acct = ProviderTestUtils.setupAccount("acct1", true, context); 1693 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 1694 1695 // Create 4 messages in box1 with bodies 1696 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context); 1697 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context); 1698 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context); 1699 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context); 1700 1701 // Confirm there are four messages 1702 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1703 assertEquals(4, count); 1704 // Confirm there are four bodies 1705 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1706 assertEquals(4, count); 1707 1708 // Find the EmailProviderBody.db file 1709 File dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME); 1710 // The EmailProviderBody.db database should exist (the provider creates it automatically) 1711 assertTrue(dbFile != null); 1712 assertTrue(dbFile.exists()); 1713 // Delete it, and confirm it is gone 1714 assertTrue(dbFile.delete()); 1715 assertFalse(dbFile.exists()); 1716 1717 // Find the EmailProvider.db file 1718 dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME); 1719 // The EmailProviderBody.db database should still exist 1720 assertTrue(dbFile != null); 1721 assertTrue(dbFile.exists()); 1722 1723 // URI to uncache the databases 1724 // This simulates the Provider starting up again (otherwise, it will still be pointing to 1725 // the already opened files) 1726 // Note that we only have access to the EmailProvider via the ContentResolver; therefore, 1727 // we cannot directly call into the provider and use a URI for this 1728 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null); 1729 1730 // TODO We should check for the deletion of attachment files once this is implemented in 1731 // the provider 1732 1733 // Explanation for what happens below... 1734 // The next time the body database is created by the provider, it will notice that there's 1735 // already a populated EmailProvider.db file. In this case, it will delete that database to 1736 // ensure that both are in sync (and empty) 1737 1738 // Confirm there are no messages 1739 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1740 assertEquals(0, count); 1741 1742 // Confirm there are no bodies 1743 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1744 assertEquals(0, count); 1745 } 1746 1747 public void testFindMailboxOfType() { 1748 final Context context = mMockContext; 1749 1750 // Create two accounts and a variety of mailbox types 1751 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context); 1752 Mailbox acct1Inbox = 1753 ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX); 1754 Mailbox acct1Calendar 1755 = ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR); 1756 Mailbox acct1Contacts = 1757 ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS); 1758 Account acct2 = ProviderTestUtils.setupAccount("acct1", true, context); 1759 Mailbox acct2Inbox = 1760 ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX); 1761 Mailbox acct2Calendar = 1762 ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR); 1763 Mailbox acct2Contacts = 1764 ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS); 1765 1766 // Check that we can find them by type 1767 assertEquals(acct1Inbox.mId, 1768 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX)); 1769 assertEquals(acct2Inbox.mId, 1770 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX)); 1771 assertEquals(acct1Calendar.mId, 1772 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR)); 1773 assertEquals(acct2Calendar.mId, 1774 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR)); 1775 assertEquals(acct1Contacts.mId, 1776 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS)); 1777 assertEquals(acct2Contacts.mId, 1778 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS)); 1779 } 1780 1781 public void testRestoreMailboxOfType() { 1782 final Context context = mMockContext; 1783 1784 // Create two accounts and a variety of mailbox types 1785 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context); 1786 Mailbox acct1Inbox = 1787 ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX); 1788 Mailbox acct1Calendar 1789 = ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR); 1790 Mailbox acct1Contacts = 1791 ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS); 1792 Account acct2 = ProviderTestUtils.setupAccount("acct1", true, context); 1793 Mailbox acct2Inbox = 1794 ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX); 1795 Mailbox acct2Calendar = 1796 ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR); 1797 Mailbox acct2Contacts = 1798 ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS); 1799 1800 // Check that we can find them by type 1801 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Inbox, 1802 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX)); 1803 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Inbox, 1804 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX)); 1805 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Calendar, 1806 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR)); 1807 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Calendar, 1808 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR)); 1809 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Contacts, 1810 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS)); 1811 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Contacts, 1812 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS)); 1813 } 1814 1815 public void testAccountIsSecurityHold() { 1816 final Context context = mMockContext; 1817 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context); 1818 1819 Account acct2 = ProviderTestUtils.setupAccount("acct2", false, context); 1820 acct2.mFlags |= Account.FLAGS_SECURITY_HOLD; 1821 acct2.save(context); 1822 1823 assertFalse(Account.isSecurityHold(context, acct1.mId)); 1824 assertTrue(Account.isSecurityHold(context, acct2.mId)); 1825 assertFalse(Account.isSecurityHold(context, 9999999)); // No such account 1826 } 1827 1828 public void testClearAccountHoldFlags() { 1829 Account a1 = ProviderTestUtils.setupAccount("holdflag-1", false, mMockContext); 1830 a1.mFlags = Account.FLAGS_NOTIFY_NEW_MAIL; 1831 a1.save(mMockContext); 1832 Account a2 = ProviderTestUtils.setupAccount("holdflag-2", false, mMockContext); 1833 a2.mFlags = Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_SECURITY_HOLD; 1834 a2.save(mMockContext); 1835 1836 // bulk clear 1837 Account.clearSecurityHoldOnAllAccounts(mMockContext); 1838 1839 // confirm new values as expected - no hold flags; other flags unmolested 1840 Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId); 1841 assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL, a1a.mFlags); 1842 Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId); 1843 assertEquals(Account.FLAGS_VIBRATE_ALWAYS, a2a.mFlags); 1844 } 1845 1846 /** 1847 * @return the number of messages in a mailbox. 1848 */ 1849 private int getMessageCount(long mailboxId) { 1850 Mailbox b = Mailbox.restoreMailboxWithId(mMockContext, mailboxId); 1851 return b.mMessageCount; 1852 } 1853 1854 /** Set -1 to the message count of all mailboxes for the recalculateMessageCount test. */ 1855 private void setMinusOneToMessageCounts() { 1856 ContentValues values = new ContentValues(); 1857 values.put(MailboxColumns.MESSAGE_COUNT, -1); 1858 1859 // EmailProvider.update() doesn't allow updating messageCount, so directly use the DB. 1860 SQLiteDatabase db = getProvider().getDatabase(mMockContext); 1861 db.update(Mailbox.TABLE_NAME, values, null, null); 1862 } 1863 1864 /** 1865 * Test for the message count triggers (insert/delete/move mailbox), and also 1866 * {@link EmailProvider#recalculateMessageCount}. 1867 * 1868 * It also covers: 1869 * - {@link Mailbox#getMessageCountByMailboxType(Context, int)} 1870 * - {@link Mailbox#getUnreadCountByMailboxType(Context, int)} 1871 * - {@link Message#getFavoriteMessageCount(Context)} 1872 */ 1873 public void testMessageCount() { 1874 final Context c = mMockContext; 1875 1876 // Create 2 accounts 1877 Account a1 = ProviderTestUtils.setupAccount("holdflag-1", true, c); 1878 Account a2 = ProviderTestUtils.setupAccount("holdflag-2", true, c); 1879 1880 // Create 2 mailboxes for each account 1881 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_INBOX); 1882 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a1.mId, true, c, Mailbox.TYPE_OUTBOX); 1883 Mailbox b3 = ProviderTestUtils.setupMailbox("box3", a2.mId, true, c, Mailbox.TYPE_INBOX); 1884 Mailbox b4 = ProviderTestUtils.setupMailbox("box4", a2.mId, true, c, Mailbox.TYPE_OUTBOX); 1885 1886 // 0. Check the initial values, just in case. 1887 1888 assertEquals(0, getMessageCount(b1.mId)); 1889 assertEquals(0, getMessageCount(b2.mId)); 1890 assertEquals(0, getMessageCount(b3.mId)); 1891 assertEquals(0, getMessageCount(b4.mId)); 1892 1893 assertEquals(0, Message.getFavoriteMessageCount(c)); 1894 assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_INBOX)); 1895 assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_OUTBOX)); 1896 assertEquals(0, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_INBOX)); 1897 assertEquals(0, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_OUTBOX)); 1898 1899 // 1. Test for insert triggers. 1900 1901 // Create some messages 1902 // b1: 1 message 1903 Message m11 = createMessage(c, b1, true, false); 1904 1905 // b2: 2 message 1906 Message m21 = createMessage(c, b2, false, false); 1907 Message m22 = createMessage(c, b2, true, true); 1908 1909 // b3: 3 message 1910 Message m31 = createMessage(c, b3, false, false); 1911 Message m32 = createMessage(c, b3, false, false); 1912 Message m33 = createMessage(c, b3, true, true); 1913 1914 // b4 has no messages. 1915 1916 // Check message counts 1917 assertEquals(1, getMessageCount(b1.mId)); 1918 assertEquals(2, getMessageCount(b2.mId)); 1919 assertEquals(3, getMessageCount(b3.mId)); 1920 assertEquals(0, getMessageCount(b4.mId)); 1921 1922 // Check the simple counting methods. 1923 assertEquals(3, Message.getFavoriteMessageCount(c)); 1924 assertEquals(3, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_INBOX)); 1925 assertEquals(1, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_OUTBOX)); 1926 assertEquals(4, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_INBOX)); 1927 assertEquals(2, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_OUTBOX)); 1928 1929 // 2. test for recalculateMessageCount. 1930 1931 // First, invalidate the message counts. 1932 setMinusOneToMessageCounts(); 1933 assertEquals(-1, getMessageCount(b1.mId)); 1934 assertEquals(-1, getMessageCount(b2.mId)); 1935 assertEquals(-1, getMessageCount(b3.mId)); 1936 assertEquals(-1, getMessageCount(b4.mId)); 1937 1938 // Batch update. 1939 SQLiteDatabase db = getProvider().getDatabase(mMockContext); 1940 EmailProvider.recalculateMessageCount(db); 1941 1942 // Check message counts 1943 assertEquals(1, getMessageCount(b1.mId)); 1944 assertEquals(2, getMessageCount(b2.mId)); 1945 assertEquals(3, getMessageCount(b3.mId)); 1946 assertEquals(0, getMessageCount(b4.mId)); 1947 1948 // 3. Check the "move mailbox" trigger. 1949 1950 // Move m32 (in mailbox 3) to mailbox 4. 1951 ContentValues values = new ContentValues(); 1952 values.put(MessageColumns.MAILBOX_KEY, b4.mId); 1953 1954 getProvider().update(Message.CONTENT_URI, values, EmailContent.ID_SELECTION, 1955 new String[] {"" + m32.mId}); 1956 1957 // Check message counts 1958 assertEquals(1, getMessageCount(b1.mId)); 1959 assertEquals(2, getMessageCount(b2.mId)); 1960 assertEquals(2, getMessageCount(b3.mId)); 1961 assertEquals(1, getMessageCount(b4.mId)); 1962 1963 // 4. Check the delete trigger. 1964 1965 // Delete m11 (in mailbox 1) 1966 getProvider().delete(Message.CONTENT_URI, EmailContent.ID_SELECTION, 1967 new String[] {"" + m11.mId}); 1968 // Delete m21 (in mailbox 2) 1969 getProvider().delete(Message.CONTENT_URI, EmailContent.ID_SELECTION, 1970 new String[] {"" + m21.mId}); 1971 1972 // Check message counts 1973 assertEquals(0, getMessageCount(b1.mId)); 1974 assertEquals(1, getMessageCount(b2.mId)); 1975 assertEquals(2, getMessageCount(b3.mId)); 1976 assertEquals(1, getMessageCount(b4.mId)); 1977 1978 // No such mailbox type. 1979 assertEquals(0, Mailbox.getMessageCountByMailboxType(c, 99999)); 1980 assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, 99999)); 1981 } 1982 1983 private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read) { 1984 return ProviderTestUtils.setupMessage("1", b.mAccountKey, b.mId, true, true, c, starred, 1985 read); 1986 } 1987 1988 public void testAccountIsEasAccount() { 1989 Account account = new Account(); 1990 // No hostauth 1991 assertFalse(account.isEasAccount(mMockContext)); 1992 1993 checkAccountIsEasAccount(null, false); 1994 checkAccountIsEasAccount("", false); 1995 checkAccountIsEasAccount("x", false); 1996 checkAccountIsEasAccount("eas", true); 1997 } 1998 1999 private void checkAccountIsEasAccount(String protocol, boolean expected) { 2000 Account account = ProviderTestUtils.setupAccount("account", false, mMockContext); 2001 account.mHostAuthRecv = ProviderTestUtils.setupHostAuth(protocol, "account-hostauth-recv", 2002 account.mId, false, mMockContext); 2003 account.save(mMockContext); 2004 assertEquals(expected, account.isEasAccount(mMockContext)); 2005 } 2006 2007 public void testGetKeyColumnLong() { 2008 final Context c = mMockContext; 2009 Account a = ProviderTestUtils.setupAccount("acct", true, c); 2010 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a.mId, true, c, Mailbox.TYPE_MAIL); 2011 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a.mId, true, c, Mailbox.TYPE_MAIL); 2012 Message m1 = createMessage(c, b1, false, false); 2013 Message m2 = createMessage(c, b2, false, false); 2014 assertEquals(a.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.ACCOUNT_KEY)); 2015 assertEquals(a.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.ACCOUNT_KEY)); 2016 assertEquals(b1.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.MAILBOX_KEY)); 2017 assertEquals(b2.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.MAILBOX_KEY)); 2018 } 2019 2020 public void testGetAccountMailboxFromMessageId() { 2021 final Context c = mMockContext; 2022 Account a = ProviderTestUtils.setupAccount("acct", true, c); 2023 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a.mId, true, c, Mailbox.TYPE_MAIL); 2024 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a.mId, true, c, Mailbox.TYPE_MAIL); 2025 Message m1 = createMessage(c, b1, false, false); 2026 Message m2 = createMessage(c, b2, false, false); 2027 ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m1.mId)); 2028 ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m2.mId)); 2029 // Restore the mailboxes, since the unread & total counts will have changed 2030 b1 = Mailbox.restoreMailboxWithId(c, b1.mId); 2031 b2 = Mailbox.restoreMailboxWithId(c, b2.mId); 2032 ProviderTestUtils.assertMailboxEqual("x", b1, Mailbox.getMailboxForMessageId(c, m1.mId)); 2033 ProviderTestUtils.assertMailboxEqual("x", b2, Mailbox.getMailboxForMessageId(c, m2.mId)); 2034 } 2035 2036 public void testGetAccountGetInboxIdTest() { 2037 final Context c = mMockContext; 2038 2039 // Prepare some data with red-herrings. 2040 Account a1 = ProviderTestUtils.setupAccount("acct1", true, c); 2041 Account a2 = ProviderTestUtils.setupAccount("acct2", true, c); 2042 Mailbox b1i = ProviderTestUtils.setupMailbox("b1i", a1.mId, true, c, Mailbox.TYPE_INBOX); 2043 Mailbox b2a = ProviderTestUtils.setupMailbox("b2a", a2.mId, true, c, Mailbox.TYPE_MAIL); 2044 Mailbox b2i = ProviderTestUtils.setupMailbox("b2b", a2.mId, true, c, Mailbox.TYPE_INBOX); 2045 2046 assertEquals(b2i.mId, Account.getInboxId(c, a2.mId)); 2047 2048 // No account found. 2049 assertEquals(-1, Account.getInboxId(c, 999999)); 2050 } 2051 2052 public void testGetMailboxType() { 2053 final Context c = mMockContext; 2054 2055 Account a = ProviderTestUtils.setupAccount("acct1", true, c); 2056 Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX); 2057 Mailbox bm = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_MAIL); 2058 2059 assertEquals(Mailbox.TYPE_INBOX, Mailbox.getMailboxType(c, bi.mId)); 2060 assertEquals(Mailbox.TYPE_MAIL, Mailbox.getMailboxType(c, bm.mId)); 2061 assertEquals(-1, Mailbox.getMailboxType(c, 999999)); // mailbox not found 2062 } 2063 2064 public void testMailboxIsRefreshable() { 2065 final Context c = mMockContext; 2066 2067 Account a = ProviderTestUtils.setupAccount("acct1", true, c); 2068 Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX); 2069 Mailbox bm = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_MAIL); 2070 Mailbox bd = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_DRAFTS); 2071 Mailbox bo = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_OUTBOX); 2072 2073 assertTrue(Mailbox.isRefreshable(c, bi.mId)); 2074 assertTrue(Mailbox.isRefreshable(c, bm.mId)); 2075 assertFalse(Mailbox.isRefreshable(c, bd.mId)); 2076 assertFalse(Mailbox.isRefreshable(c, bo.mId)); 2077 2078 // No such mailbox 2079 assertFalse(Mailbox.isRefreshable(c, 9999999)); 2080 2081 // Magic mailboxes can't be refreshed. 2082 assertFalse(Mailbox.isRefreshable(c, Mailbox.QUERY_ALL_DRAFTS)); 2083 assertFalse(Mailbox.isRefreshable(c, Mailbox.QUERY_ALL_INBOXES)); 2084 } 2085 2086 public void testMailboxCanMoveFrom() { 2087 final Context c = mMockContext; 2088 2089 Account a = ProviderTestUtils.setupAccount("acct1", true, c); 2090 Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX); 2091 Mailbox bm = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_MAIL); 2092 Mailbox bd = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_DRAFTS); 2093 Mailbox bo = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_OUTBOX); 2094 2095 assertTrue(Mailbox.canMoveFrom(c, bi.mId)); 2096 assertTrue(Mailbox.canMoveFrom(c, bm.mId)); 2097 assertFalse(Mailbox.canMoveFrom(c, bd.mId)); 2098 assertFalse(Mailbox.canMoveFrom(c, bo.mId)); 2099 } 2100 2101 /** 2102 * Check if update to {@link Account#RESET_NEW_MESSAGE_COUNT_URI} resets the new message count. 2103 */ 2104 public void testResetNewMessageCount() { 2105 final Context c = mMockContext; 2106 final ContentResolver cr = c.getContentResolver(); 2107 2108 // Prepare test data 2109 Account a1 = ProviderTestUtils.setupAccount("acct1", false, c); 2110 a1.mNewMessageCount = 1; 2111 a1.save(c); 2112 Account a2 = ProviderTestUtils.setupAccount("acct2", false, c); 2113 a2.mNewMessageCount = 2; 2114 a2.save(c); 2115 Account a3 = ProviderTestUtils.setupAccount("acct3", false, c); 2116 a3.mNewMessageCount = 3; 2117 a3.save(c); 2118 Account a4 = ProviderTestUtils.setupAccount("acct4", false, c); 2119 a4.mNewMessageCount = 4; 2120 a4.save(c); 2121 Account a5 = ProviderTestUtils.setupAccount("acct5", false, c); 2122 a5.mNewMessageCount = 5; 2123 a5.save(c); 2124 2125 // With ID in URI, no selection 2126 cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a1.mId), 2127 null, null, null); 2128 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount); 2129 assertEquals(2, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount); 2130 assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount); 2131 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount); 2132 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount); 2133 2134 // No ID in URI, with selection 2135 cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, 2136 EmailContent.ID_SELECTION, new String[] {Long.toString(a2.mId)}); 2137 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount); 2138 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount); 2139 assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount); 2140 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount); 2141 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount); 2142 2143 // With ID, with selection 2144 cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a3.mId), null, 2145 EmailContent.ID_SELECTION, new String[] {Long.toString(a3.mId)}); 2146 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount); 2147 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount); 2148 assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount); 2149 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount); 2150 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount); 2151 2152 // No ID in URI, no selection 2153 cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, null, null); 2154 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount); 2155 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount); 2156 assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount); 2157 assertEquals(0, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount); 2158 assertEquals(0, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount); 2159 } 2160} 2161