ProviderTests.java revision 1575e7860d2259f1aed201ab23d526cddf787365
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.provider.EmailContent.Account; 20import com.android.email.provider.EmailContent.AccountColumns; 21import com.android.email.provider.EmailContent.Attachment; 22import com.android.email.provider.EmailContent.AttachmentColumns; 23import com.android.email.provider.EmailContent.Body; 24import com.android.email.provider.EmailContent.BodyColumns; 25import com.android.email.provider.EmailContent.HostAuth; 26import com.android.email.provider.EmailContent.Mailbox; 27import com.android.email.provider.EmailContent.MailboxColumns; 28import com.android.email.provider.EmailContent.Message; 29import com.android.email.provider.EmailContent.MessageColumns; 30 31import android.content.ContentResolver; 32import android.content.ContentUris; 33import android.content.ContentValues; 34import android.content.Context; 35import android.database.Cursor; 36import android.net.Uri; 37import android.os.Bundle; 38import android.os.Environment; 39import android.os.Parcel; 40import android.test.ProviderTestCase2; 41 42import java.io.File; 43import java.io.IOException; 44import java.util.ArrayList; 45 46/** 47 * Tests of the Email provider. 48 * 49 * You can run this entire test case with: 50 * runtest -c com.android.email.provider.ProviderTests email 51 */ 52public class ProviderTests extends ProviderTestCase2<EmailProvider> { 53 54 EmailProvider mProvider; 55 Context mMockContext; 56 57 public ProviderTests() { 58 super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY); 59 } 60 61 @Override 62 public void setUp() throws Exception { 63 super.setUp(); 64 mMockContext = getMockContext(); 65 } 66 67 @Override 68 public void tearDown() throws Exception { 69 super.tearDown(); 70 } 71 72 /** 73 * TODO: Database upgrade tests 74 */ 75 76 /** 77 * Test simple account save/retrieve 78 */ 79 public void testAccountSave() { 80 Account account1 = ProviderTestUtils.setupAccount("account-save", true, mMockContext); 81 long account1Id = account1.mId; 82 83 Account account2 = EmailContent.Account.restoreAccountWithId(mMockContext, account1Id); 84 85 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account2); 86 } 87 88 /** 89 * Test simple account save/retrieve with predefined hostauth records 90 */ 91 public void testAccountSaveHostAuth() { 92 Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext); 93 // add hostauth data, which should be saved the first time 94 account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false, 95 mMockContext); 96 account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false, 97 mMockContext); 98 account1.save(mMockContext); 99 long account1Id = account1.mId; 100 101 // Confirm account reads back correctly 102 Account account1get = EmailContent.Account.restoreAccountWithId(mMockContext, account1Id); 103 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account1get); 104 105 // Confirm hostauth fields can be accessed & read back correctly 106 HostAuth hostAuth1get = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, 107 account1get.mHostAuthKeyRecv); 108 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-recv", 109 account1.mHostAuthRecv, hostAuth1get); 110 HostAuth hostAuth2get = EmailContent.HostAuth.restoreHostAuthWithId(mMockContext, 111 account1get.mHostAuthKeySend); 112 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-send", 113 account1.mHostAuthSend, hostAuth2get); 114 } 115 116 /** 117 * Simple test of account parceling. The rather tortuous path is to ensure that the 118 * account is really flattened all the way down to a parcel and back. 119 */ 120 public void testAccountParcel() { 121 Account account1 = ProviderTestUtils.setupAccount("parcel", false, mMockContext); 122 Bundle b = new Bundle(); 123 b.putParcelable("account", account1); 124 Parcel p = Parcel.obtain(); 125 b.writeToParcel(p, 0); 126 p.setDataPosition(0); // rewind it for reading 127 Bundle b2 = new Bundle(Account.class.getClassLoader()); 128 b2.readFromParcel(p); 129 Account account2 = (Account) b2.getParcelable("account"); 130 p.recycle(); 131 132 ProviderTestUtils.assertAccountEqual("testAccountParcel", account1, account2); 133 } 134 135 private final static String[] MAILBOX_UNREAD_COUNT_PROJECTION = new String [] { 136 MailboxColumns.UNREAD_COUNT 137 }; 138 private final static int MAILBOX_UNREAD_COUNT_COLMUN = 0; 139 140 /** 141 * Get the value of the unread count in the mailbox of the account. 142 * This can be different from the actual number of unread messages in that mailbox. 143 * @param accountId 144 * @param mailboxId 145 * @return 146 */ 147 private int getUnreadCount(long mailboxId) { 148 String text = null; 149 Cursor c = null; 150 try { 151 c = mMockContext.getContentResolver().query( 152 Mailbox.CONTENT_URI, 153 MAILBOX_UNREAD_COUNT_PROJECTION, 154 EmailContent.RECORD_ID + "=?", 155 new String[] { String.valueOf(mailboxId) }, 156 null); 157 c.moveToFirst(); 158 text = c.getString(MAILBOX_UNREAD_COUNT_COLMUN); 159 } finally { 160 c.close(); 161 } 162 return Integer.valueOf(text); 163 } 164 165 /** 166 * TODO: HostAuth tests 167 */ 168 169 /** 170 * Test the various combinations of SSL, TLS, and trust-certificates encoded as Uris 171 */ 172 @SuppressWarnings("deprecation") 173 public void testHostAuthSecurityUri() { 174 HostAuth ha = ProviderTestUtils.setupHostAuth("uri-security", 1, false, mMockContext); 175 176 final int MASK = 177 HostAuth.FLAG_SSL | HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 178 179 // Set various URIs and check the resulting flags 180 ha.setStoreUri("protocol://user:password@server:123"); 181 assertEquals(0, ha.mFlags & MASK); 182 ha.setStoreUri("protocol+ssl+://user:password@server:123"); 183 assertEquals(HostAuth.FLAG_SSL, ha.mFlags & MASK); 184 ha.setStoreUri("protocol+ssl+trustallcerts://user:password@server:123"); 185 assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); 186 ha.setStoreUri("protocol+tls+://user:password@server:123"); 187 assertEquals(HostAuth.FLAG_TLS, ha.mFlags & MASK); 188 ha.setStoreUri("protocol+tls+trustallcerts://user:password@server:123"); 189 assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL_CERTIFICATES, ha.mFlags & MASK); 190 191 // Now check the retrival method (building URI from flags) 192 ha.mFlags &= ~MASK; 193 String uriString = ha.getStoreUri(); 194 assertTrue(uriString.startsWith("protocol://")); 195 ha.mFlags |= HostAuth.FLAG_SSL; 196 uriString = ha.getStoreUri(); 197 assertTrue(uriString.startsWith("protocol+ssl+://")); 198 ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 199 uriString = ha.getStoreUri(); 200 assertTrue(uriString.startsWith("protocol+ssl+trustallcerts://")); 201 ha.mFlags &= ~MASK; 202 ha.mFlags |= HostAuth.FLAG_TLS; 203 uriString = ha.getStoreUri(); 204 assertTrue(uriString.startsWith("protocol+tls+://")); 205 ha.mFlags |= HostAuth.FLAG_TRUST_ALL_CERTIFICATES; 206 uriString = ha.getStoreUri(); 207 assertTrue(uriString.startsWith("protocol+tls+trustallcerts://")); 208 } 209 210 /** 211 * Test port assignments made from Uris 212 */ 213 @SuppressWarnings("deprecation") 214 public void testHostAuthPortAssignments() { 215 HostAuth ha = ProviderTestUtils.setupHostAuth("uri-port", 1, false, mMockContext); 216 217 // Set various URIs and check the resulting flags 218 // Hardwired port 219 ha.setStoreUri("imap://user:password@server:123"); 220 assertEquals(123, ha.mPort); 221 // Auto-assigned ports 222 ha.setStoreUri("imap://user:password@server"); 223 assertEquals(143, ha.mPort); 224 ha.setStoreUri("imap+ssl://user:password@server"); 225 assertEquals(993, ha.mPort); 226 ha.setStoreUri("imap+ssl+trustallcerts://user:password@server"); 227 assertEquals(993, ha.mPort); 228 ha.setStoreUri("imap+tls://user:password@server"); 229 assertEquals(143, ha.mPort); 230 ha.setStoreUri("imap+tls+trustallcerts://user:password@server"); 231 assertEquals(143, ha.mPort); 232 233 // Hardwired port 234 ha.setStoreUri("pop3://user:password@server:123"); 235 assertEquals(123, ha.mPort); 236 // Auto-assigned ports 237 ha.setStoreUri("pop3://user:password@server"); 238 assertEquals(110, ha.mPort); 239 ha.setStoreUri("pop3+ssl://user:password@server"); 240 assertEquals(995, ha.mPort); 241 ha.setStoreUri("pop3+ssl+trustallcerts://user:password@server"); 242 assertEquals(995, ha.mPort); 243 ha.setStoreUri("pop3+tls://user:password@server"); 244 assertEquals(110, ha.mPort); 245 ha.setStoreUri("pop3+tls+trustallcerts://user:password@server"); 246 assertEquals(110, ha.mPort); 247 248 // Hardwired port 249 ha.setStoreUri("eas://user:password@server:123"); 250 assertEquals(123, ha.mPort); 251 // Auto-assigned ports 252 ha.setStoreUri("eas://user:password@server"); 253 assertEquals(80, ha.mPort); 254 ha.setStoreUri("eas+ssl://user:password@server"); 255 assertEquals(443, ha.mPort); 256 ha.setStoreUri("eas+ssl+trustallcerts://user:password@server"); 257 assertEquals(443, ha.mPort); 258 259 // Hardwired port 260 ha.setStoreUri("smtp://user:password@server:123"); 261 assertEquals(123, ha.mPort); 262 // Auto-assigned ports 263 ha.setStoreUri("smtp://user:password@server"); 264 assertEquals(587, ha.mPort); 265 ha.setStoreUri("smtp+ssl://user:password@server"); 266 assertEquals(465, ha.mPort); 267 ha.setStoreUri("smtp+ssl+trustallcerts://user:password@server"); 268 assertEquals(465, ha.mPort); 269 ha.setStoreUri("smtp+tls://user:password@server"); 270 assertEquals(587, ha.mPort); 271 ha.setStoreUri("smtp+tls+trustallcerts://user:password@server"); 272 assertEquals(587, ha.mPort); 273 } 274 275 /** 276 * Test simple mailbox save/retrieve 277 */ 278 public void testMailboxSave() { 279 Account account1 = ProviderTestUtils.setupAccount("mailbox-save", true, mMockContext); 280 long account1Id = account1.mId; 281 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, 282 mMockContext); 283 long box1Id = box1.mId; 284 285 Mailbox box2 = EmailContent.Mailbox.restoreMailboxWithId(mMockContext, box1Id); 286 287 ProviderTestUtils.assertMailboxEqual("testMailboxSave", box1, box2); 288 } 289 290 private static String[] expectedAttachmentNames = 291 new String[] {"attachment1.doc", "attachment2.xls", "attachment3"}; 292 // The lengths need to be kept in ascending order 293 private static long[] expectedAttachmentSizes = new long[] {31415L, 97701L, 151213L}; 294 295 /* 296 * Returns null if the message has no body. 297 */ 298 private Body loadBodyForMessageId(long messageId) { 299 Cursor c = null; 300 try { 301 c = mMockContext.getContentResolver().query( 302 EmailContent.Body.CONTENT_URI, 303 EmailContent.Body.CONTENT_PROJECTION, 304 EmailContent.Body.MESSAGE_KEY + "=?", 305 new String[] {String.valueOf(messageId)}, 306 null); 307 int numBodies = c.getCount(); 308 assertTrue("at most one body", numBodies < 2); 309 return c.moveToFirst() ? EmailContent.getContent(c, Body.class) : null; 310 } finally { 311 c.close(); 312 } 313 } 314 315 /** 316 * Test simple message save/retrieve 317 * 318 * TODO: serverId vs. serverIntId 319 */ 320 public void testMessageSave() { 321 Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext); 322 long account1Id = account1.mId; 323 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 324 long box1Id = box1.mId; 325 326 // Test a simple message (saved with no body) 327 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 328 true, mMockContext); 329 long message1Id = message1.mId; 330 Message message1get = EmailContent.Message.restoreMessageWithId(mMockContext, message1Id); 331 ProviderTestUtils.assertMessageEqual("testMessageSave", message1, message1get); 332 333 // Test a message saved with a body 334 // Note that it will read back w/o the text & html so we must extract those 335 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 336 true, mMockContext); 337 long message2Id = message2.mId; 338 String text2 = message2.mText; 339 String html2 = message2.mHtml; 340 String textReply2 = message2.mTextReply; 341 String htmlReply2 = message2.mHtmlReply; 342 long sourceKey2 = message2.mSourceKey; 343 String introText2 = message2.mIntroText; 344 message2.mText = null; 345 message2.mHtml = null; 346 message2.mTextReply = null; 347 message2.mHtmlReply = null; 348 message2.mSourceKey = 0; 349 message2.mIntroText = null; 350 Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id); 351 ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get); 352 353 // Now see if there's a body saved with the right stuff 354 Body body2 = loadBodyForMessageId(message2Id); 355 assertEquals("body text", text2, body2.mTextContent); 356 assertEquals("body html", html2, body2.mHtmlContent); 357 assertEquals("reply text", textReply2, body2.mTextReply); 358 assertEquals("reply html", htmlReply2, body2.mHtmlReply); 359 assertEquals("source key", sourceKey2, body2.mSourceKey); 360 assertEquals("intro text", introText2, body2.mIntroText); 361 362 // Message with attachments and body 363 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true, 364 false, mMockContext); 365 ArrayList<Attachment> atts = new ArrayList<Attachment>(); 366 for (int i = 0; i < 3; i++) { 367 atts.add(ProviderTestUtils.setupAttachment( 368 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 369 false, mMockContext)); 370 } 371 message3.mAttachments = atts; 372 message3.save(mMockContext); 373 long message3Id = message3.mId; 374 375 // Now check the attachments; there should be three and they should match name and size 376 Cursor c = null; 377 try { 378 // Note that there is NO guarantee of the order of returned records in the general case, 379 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must 380 // be kept sorted by size (ascending) for this test to work properly 381 c = mMockContext.getContentResolver().query( 382 Attachment.CONTENT_URI, 383 Attachment.CONTENT_PROJECTION, 384 Attachment.MESSAGE_KEY + "=?", 385 new String[] { 386 String.valueOf(message3Id) 387 }, 388 Attachment.SIZE); 389 int numAtts = c.getCount(); 390 assertEquals(3, numAtts); 391 int i = 0; 392 while (c.moveToNext()) { 393 Attachment actual = EmailContent.getContent(c, Attachment.class); 394 ProviderTestUtils.assertAttachmentEqual("save-message3", atts.get(i), actual); 395 i++; 396 } 397 } finally { 398 c.close(); 399 } 400 401 // Message with attachments but no body 402 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, false, 403 false, mMockContext); 404 atts = new ArrayList<Attachment>(); 405 for (int i = 0; i < 3; i++) { 406 atts.add(ProviderTestUtils.setupAttachment( 407 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 408 false, mMockContext)); 409 } 410 message4.mAttachments = atts; 411 message4.save(mMockContext); 412 long message4Id = message4.mId; 413 414 // Now check the attachments; there should be three and they should match name and size 415 c = null; 416 417 try { 418 // Note that there is NO guarantee of the order of returned records in the general case, 419 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must 420 // be kept sorted by size (ascending) for this test to work properly 421 c = mMockContext.getContentResolver().query( 422 Attachment.CONTENT_URI, 423 Attachment.CONTENT_PROJECTION, 424 Attachment.MESSAGE_KEY + "=?", 425 new String[] { 426 String.valueOf(message4Id) 427 }, 428 Attachment.SIZE); 429 int numAtts = c.getCount(); 430 assertEquals(3, numAtts); 431 int i = 0; 432 while (c.moveToNext()) { 433 Attachment actual = EmailContent.getContent(c, Attachment.class); 434 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), actual); 435 i++; 436 } 437 } finally { 438 c.close(); 439 } 440 441 // test EmailContent.restoreAttachmentsWitdMessageId() 442 Attachment[] attachments = 443 Attachment.restoreAttachmentsWithMessageId(mMockContext, message4Id); 444 int size = attachments.length; 445 assertEquals(3, size); 446 for (int i = 0; i < size; ++i) { 447 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), attachments[i]); 448 } 449 } 450 451 /** 452 * TODO: update account 453 */ 454 455 /** 456 * TODO: update mailbox 457 */ 458 459 /** 460 * TODO: update message 461 */ 462 463 /** 464 * Test delete account 465 * TODO: hostauth 466 */ 467 public void testAccountDelete() { 468 Account account1 = ProviderTestUtils.setupAccount("account-delete-1", true, mMockContext); 469 long account1Id = account1.mId; 470 Account account2 = ProviderTestUtils.setupAccount("account-delete-2", true, mMockContext); 471 long account2Id = account2.mId; 472 473 // make sure there are two accounts 474 int numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 475 assertEquals(2, numBoxes); 476 477 // now delete one of them 478 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 479 mMockContext.getContentResolver().delete(uri, null, null); 480 481 // make sure there's only one account now 482 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 483 assertEquals(1, numBoxes); 484 485 // now delete the other one 486 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id); 487 mMockContext.getContentResolver().delete(uri, null, null); 488 489 // make sure there are no accounts now 490 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 491 assertEquals(0, numBoxes); 492 } 493 494 /** 495 * Test for Body.lookupBodyIdWithMessageId() 496 * Verifies that: 497 * - for a message without body, -1 is returned. 498 * - for a mesage with body, the id matches the one from loadBodyForMessageId. 499 */ 500 public void testLookupBodyIdWithMessageId() { 501 final ContentResolver resolver = mMockContext.getContentResolver(); 502 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 503 long account1Id = account1.mId; 504 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 505 long box1Id = box1.mId; 506 507 // 1. create message with no body, check that returned bodyId is -1 508 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 509 true, mMockContext); 510 long message1Id = message1.mId; 511 long bodyId1 = Body.lookupBodyIdWithMessageId(resolver, message1Id); 512 assertEquals(bodyId1, -1); 513 514 // 2. create message with body, check that returned bodyId is correct 515 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 516 true, mMockContext); 517 long message2Id = message2.mId; 518 long bodyId2 = Body.lookupBodyIdWithMessageId(resolver, message2Id); 519 Body body = loadBodyForMessageId(message2Id); 520 assertNotNull(body); 521 assertEquals(body.mId, bodyId2); 522 } 523 524 /** 525 * Test for Body.updateBodyWithMessageId(). 526 * 1. - create message without body, 527 * - update its body (set TEXT_CONTENT) 528 * - check correct updated body is read back 529 * 530 * 2. - create message with body, 531 * - update body (set TEXT_CONTENT) 532 * - check correct updated body is read back 533 */ 534 public void testUpdateBodyWithMessageId() { 535 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 536 long account1Id = account1.mId; 537 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 538 long box1Id = box1.mId; 539 540 final String textContent = "foobar some odd text"; 541 final String htmlContent = "and some html"; 542 final String textReply = "plain text reply"; 543 final String htmlReply = "or the html reply"; 544 final String introText = "fred wrote:"; 545 546 ContentValues values = new ContentValues(); 547 values.put(BodyColumns.TEXT_CONTENT, textContent); 548 values.put(BodyColumns.HTML_CONTENT, htmlContent); 549 values.put(BodyColumns.TEXT_REPLY, textReply); 550 values.put(BodyColumns.HTML_REPLY, htmlReply); 551 values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17); 552 values.put(BodyColumns.INTRO_TEXT, introText); 553 554 // 1 555 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 556 true, mMockContext); 557 long message1Id = message1.mId; 558 Body body1 = loadBodyForMessageId(message1Id); 559 assertNull(body1); 560 Body.updateBodyWithMessageId(mMockContext, message1Id, values); 561 body1 = loadBodyForMessageId(message1Id); 562 assertNotNull(body1); 563 assertEquals(body1.mTextContent, textContent); 564 assertEquals(body1.mHtmlContent, htmlContent); 565 assertEquals(body1.mTextReply, textReply); 566 assertEquals(body1.mHtmlReply, htmlReply); 567 assertEquals(body1.mSourceKey, 17); 568 assertEquals(body1.mIntroText, introText); 569 570 // 2 571 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 572 true, mMockContext); 573 long message2Id = message2.mId; 574 Body body2 = loadBodyForMessageId(message2Id); 575 assertNotNull(body2); 576 assertTrue(!body2.mTextContent.equals(textContent)); 577 Body.updateBodyWithMessageId(mMockContext, message2Id, values); 578 body2 = loadBodyForMessageId(message1Id); 579 assertNotNull(body2); 580 assertEquals(body2.mTextContent, textContent); 581 assertEquals(body2.mHtmlContent, htmlContent); 582 assertEquals(body2.mTextReply, textReply); 583 assertEquals(body2.mHtmlReply, htmlReply); 584 assertEquals(body2.mSourceKey, 17); 585 assertEquals(body2.mIntroText, introText); 586 } 587 588 /** 589 * Test body retrieve methods 590 */ 591 public void testBodyRetrieve() { 592 // No account needed 593 // No mailbox needed 594 Message message1 = ProviderTestUtils.setupMessage("bodyretrieve", 1, 1, true, 595 true, mMockContext); 596 long messageId = message1.mId; 597 598 assertEquals(message1.mText, 599 Body.restoreBodyTextWithMessageId(mMockContext, messageId)); 600 assertEquals(message1.mHtml, 601 Body.restoreBodyHtmlWithMessageId(mMockContext, messageId)); 602 assertEquals(message1.mTextReply, 603 Body.restoreReplyTextWithMessageId(mMockContext, messageId)); 604 assertEquals(message1.mHtmlReply, 605 Body.restoreReplyHtmlWithMessageId(mMockContext, messageId)); 606 assertEquals(message1.mIntroText, 607 Body.restoreIntroTextWithMessageId(mMockContext, messageId)); 608 assertEquals(message1.mSourceKey, 609 Body.restoreBodySourceKey(mMockContext, messageId)); 610 } 611 612 /** 613 * Test delete body. 614 * 1. create message without body (message id 1) 615 * 2. create message with body (message id 2. The body has _id 1 and messageKey 2). 616 * 3. delete first message. 617 * 4. verify that body for message 2 has not been deleted. 618 * 5. delete message 2, verify body is deleted. 619 */ 620 public void testDeleteBody() { 621 final ContentResolver resolver = mMockContext.getContentResolver(); 622 623 // Create account and mailboxes 624 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 625 long account1Id = account1.mId; 626 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 627 long box1Id = box1.mId; 628 629 // 1. create message without body 630 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 631 true, mMockContext); 632 long message1Id = message1.mId; 633 634 // 2. create message with body 635 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 636 true, mMockContext); 637 long message2Id = message2.mId; 638 // verify body is there 639 assertNotNull(loadBodyForMessageId(message2Id)); 640 641 // 3. delete first message 642 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null); 643 644 // 4. verify body for second message wasn't deleted 645 assertNotNull(loadBodyForMessageId(message2Id)); 646 647 // 5. delete second message, check its body is deleted 648 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message2Id), null, null); 649 assertNull(loadBodyForMessageId(message2Id)); 650 } 651 652 /** 653 * Test delete orphan bodies. 654 * 1. create message without body (message id 1) 655 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2). 656 * 3. delete first message. 657 * 4. delete some other mailbox -- this triggers delete orphan bodies. 658 * 5. verify that body for message 2 has not been deleted. 659 */ 660 public void testDeleteOrphanBodies() { 661 final ContentResolver resolver = mMockContext.getContentResolver(); 662 663 // Create account and two mailboxes 664 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext); 665 long account1Id = account1.mId; 666 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 667 long box1Id = box1.mId; 668 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext); 669 long box2Id = box2.mId; 670 671 // 1. create message without body 672 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 673 true, mMockContext); 674 long message1Id = message1.mId; 675 676 // 2. create message with body 677 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 678 true, mMockContext); 679 long message2Id = message2.mId; 680 //verify body is there 681 assertNotNull(loadBodyForMessageId(message2Id)); 682 683 // 3. delete first message 684 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null); 685 686 // 4. delete some mailbox (because it triggers "delete orphan bodies") 687 resolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id), null, null); 688 689 // 5. verify body for second message wasn't deleted during "delete orphan bodies" 690 assertNotNull(loadBodyForMessageId(message2Id)); 691 } 692 693 /** 694 * Test delete orphan messages 695 * 1. create message without body (message id 1) 696 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2). 697 * 3. delete first message. 698 * 4. delete some other mailbox -- this triggers delete orphan bodies. 699 * 5. verify that body for message 2 has not been deleted. 700 */ 701 public void testDeleteOrphanMessages() { 702 final ContentResolver resolver = mMockContext.getContentResolver(); 703 final Context context = mMockContext; 704 705 // Create account and two mailboxes 706 Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context); 707 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 708 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context); 709 710 // Create 4 messages in box1 711 Message msg1_1 = 712 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context); 713 Message msg1_2 = 714 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context); 715 Message msg1_3 = 716 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context); 717 Message msg1_4 = 718 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context); 719 720 // Create 4 messages in box2 721 Message msg2_1 = 722 ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context); 723 Message msg2_2 = 724 ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context); 725 Message msg2_3 = 726 ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context); 727 Message msg2_4 = 728 ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context); 729 730 // Delete 2 from each mailbox 731 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_1.mId), 732 null, null); 733 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_2.mId), 734 null, null); 735 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_1.mId), 736 null, null); 737 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_2.mId), 738 null, null); 739 740 // There should be 4 items in the deleted item table 741 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 742 743 // Update 2 from each mailbox 744 ContentValues v = new ContentValues(); 745 v.put(MessageColumns.DISPLAY_NAME, "--updated--"); 746 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_3.mId), 747 v, null, null); 748 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_4.mId), 749 v, null, null); 750 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_3.mId), 751 v, null, null); 752 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_4.mId), 753 v, null, null); 754 755 // There should be 4 items in the updated item table 756 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 757 758 // Manually add 2 messages from a "deleted" mailbox to deleted and updated tables 759 // Use a value > 2 for the deleted box id 760 long delBoxId = 10; 761 // Create 4 messages in the "deleted" mailbox 762 Message msgX_A = 763 ProviderTestUtils.setupMessage("messageA", acct.mId, delBoxId, false, false, context); 764 Message msgX_B = 765 ProviderTestUtils.setupMessage("messageB", acct.mId, delBoxId, false, false, context); 766 Message msgX_C = 767 ProviderTestUtils.setupMessage("messageC", acct.mId, delBoxId, false, false, context); 768 Message msgX_D = 769 ProviderTestUtils.setupMessage("messageD", acct.mId, delBoxId, false, false, context); 770 771 ContentValues cv; 772 // We have to assign id's manually because there are no autoincrement id's for these tables 773 // Start with an id that won't exist, since id's in these tables must be unique 774 long msgId = 10; 775 // It's illegal to manually insert these, so we need to catch the exception 776 // NOTE: The insert succeeds, and then throws the exception 777 try { 778 cv = msgX_A.toContentValues(); 779 cv.put(EmailContent.RECORD_ID, msgId++); 780 resolver.insert(Message.DELETED_CONTENT_URI, cv); 781 } catch (IllegalArgumentException e) { 782 } 783 try { 784 cv = msgX_B.toContentValues(); 785 cv.put(EmailContent.RECORD_ID, msgId++); 786 resolver.insert(Message.DELETED_CONTENT_URI, cv); 787 } catch (IllegalArgumentException e) { 788 } 789 try { 790 cv = msgX_C.toContentValues(); 791 cv.put(EmailContent.RECORD_ID, msgId++); 792 resolver.insert(Message.UPDATED_CONTENT_URI, cv); 793 } catch (IllegalArgumentException e) { 794 } 795 try { 796 cv = msgX_D.toContentValues(); 797 cv.put(EmailContent.RECORD_ID, msgId++); 798 resolver.insert(Message.UPDATED_CONTENT_URI, cv); 799 } catch (IllegalArgumentException e) { 800 } 801 802 // There should be 6 items in the deleted and updated tables 803 assertEquals(6, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 804 assertEquals(6, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 805 806 // Delete the orphans 807 EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context), 808 Message.DELETED_TABLE_NAME); 809 EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context), 810 Message.UPDATED_TABLE_NAME); 811 812 // There should now be 4 messages in each of the deleted and updated tables again 813 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null)); 814 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null)); 815 } 816 817 /** 818 * Test delete mailbox 819 */ 820 public void testMailboxDelete() { 821 Account account1 = ProviderTestUtils.setupAccount("mailbox-delete", true, mMockContext); 822 long account1Id = account1.mId; 823 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 824 long box1Id = box1.mId; 825 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext); 826 long box2Id = box2.mId; 827 828 String selection = EmailContent.MailboxColumns.ACCOUNT_KEY + "=?"; 829 String[] selArgs = new String[] { String.valueOf(account1Id) }; 830 831 // make sure there are two mailboxes 832 int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 833 assertEquals(2, numBoxes); 834 835 // now delete one of them 836 Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id); 837 mMockContext.getContentResolver().delete(uri, null, null); 838 839 // make sure there's only one mailbox now 840 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 841 assertEquals(1, numBoxes); 842 843 // now delete the other one 844 uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id); 845 mMockContext.getContentResolver().delete(uri, null, null); 846 847 // make sure there are no mailboxes now 848 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, selection, selArgs); 849 assertEquals(0, numBoxes); 850 } 851 852 /** 853 * Test delete message 854 * TODO: body 855 * TODO: attachments 856 */ 857 public void testMessageDelete() { 858 Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mMockContext); 859 long account1Id = account1.mId; 860 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 861 long box1Id = box1.mId; 862 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 863 true, mMockContext); 864 long message1Id = message1.mId; 865 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 866 true, mMockContext); 867 long message2Id = message2.mId; 868 869 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " + 870 EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 871 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) }; 872 873 // make sure there are two messages 874 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 875 assertEquals(2, numMessages); 876 877 // now delete one of them 878 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 879 mMockContext.getContentResolver().delete(uri, null, null); 880 881 // make sure there's only one message now 882 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 883 assertEquals(1, numMessages); 884 885 // now delete the other one 886 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 887 mMockContext.getContentResolver().delete(uri, null, null); 888 889 // make sure there are no messages now 890 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 891 assertEquals(0, numMessages); 892 } 893 894 /** 895 * Test delete synced message 896 * TODO: body 897 * TODO: attachments 898 */ 899 public void testSyncedMessageDelete() { 900 Account account1 = ProviderTestUtils.setupAccount("synced-message-delete", true, 901 mMockContext); 902 long account1Id = account1.mId; 903 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 904 long box1Id = box1.mId; 905 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 906 true, mMockContext); 907 long message1Id = message1.mId; 908 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 909 true, mMockContext); 910 long message2Id = message2.mId; 911 912 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " 913 + EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 914 String[] selArgs = new String[] { 915 String.valueOf(account1Id), String.valueOf(box1Id) 916 }; 917 918 // make sure there are two messages 919 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 920 assertEquals(2, numMessages); 921 922 // make sure we start with no synced deletions 923 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 924 selArgs); 925 assertEquals(0, numMessages); 926 927 // now delete one of them SYNCED 928 Uri uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1Id); 929 mMockContext.getContentResolver().delete(uri, null, null); 930 931 // make sure there's only one message now 932 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 933 assertEquals(1, numMessages); 934 935 // make sure there's one synced deletion now 936 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 937 selArgs); 938 assertEquals(1, numMessages); 939 940 // now delete the other one NOT SYNCED 941 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 942 mMockContext.getContentResolver().delete(uri, null, null); 943 944 // make sure there are no messages now 945 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 946 assertEquals(0, numMessages); 947 948 // make sure there's still one deletion now 949 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 950 selArgs); 951 assertEquals(1, numMessages); 952 } 953 954 /** 955 * Test message update 956 * TODO: body 957 * TODO: attachments 958 */ 959 public void testMessageUpdate() { 960 Account account1 = ProviderTestUtils.setupAccount("message-update", true, mMockContext); 961 long account1Id = account1.mId; 962 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 963 long box1Id = box1.mId; 964 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, 965 true, mMockContext); 966 long message1Id = message1.mId; 967 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, 968 true, mMockContext); 969 long message2Id = message2.mId; 970 ContentResolver cr = mMockContext.getContentResolver(); 971 972 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " 973 + EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 974 String[] selArgs = new String[] { 975 String.valueOf(account1Id), String.valueOf(box1Id) 976 }; 977 978 // make sure there are two messages 979 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 980 assertEquals(2, numMessages); 981 982 // change the first one 983 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 984 ContentValues cv = new ContentValues(); 985 cv.put(MessageColumns.FROM_LIST, "from-list"); 986 cr.update(uri, cv, null, null); 987 988 // make sure there's no updated message 989 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 990 selArgs); 991 assertEquals(0, numMessages); 992 993 // get the message back from the provider, make sure the change "stuck" 994 Message restoredMessage = Message.restoreMessageWithId(mMockContext, message1Id); 995 assertEquals("from-list", restoredMessage.mFrom); 996 997 // change the second one 998 uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id); 999 cv = new ContentValues(); 1000 cv.put(MessageColumns.FROM_LIST, "from-list"); 1001 cr.update(uri, cv, null, null); 1002 1003 // make sure there's one updated message 1004 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1005 selArgs); 1006 assertEquals(1, numMessages); 1007 1008 // get the message back from the provider, make sure the change "stuck", 1009 // as before 1010 restoredMessage = Message.restoreMessageWithId(mMockContext, message2Id); 1011 assertEquals("from-list", restoredMessage.mFrom); 1012 1013 // get the original message back from the provider 1014 Cursor c = cr.query(Message.UPDATED_CONTENT_URI, Message.CONTENT_PROJECTION, null, null, 1015 null); 1016 try { 1017 assertTrue(c.moveToFirst()); 1018 Message originalMessage = EmailContent.getContent(c, Message.class); 1019 // make sure this has the original value 1020 assertEquals("from message2", originalMessage.mFrom); 1021 // Should only be one 1022 assertFalse(c.moveToNext()); 1023 } finally { 1024 c.close(); 1025 } 1026 1027 // delete the second message 1028 cr.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id), null, null); 1029 1030 // hey, presto! the change should be gone 1031 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1032 selArgs); 1033 assertEquals(0, numMessages); 1034 1035 // and there should now be a deleted record 1036 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1037 selArgs); 1038 assertEquals(1, numMessages); 1039 } 1040 1041 /** 1042 * TODO: cascaded delete account 1043 * TODO: hostauth 1044 * TODO: body 1045 * TODO: attachments 1046 * TODO: create other account, mailbox & messages and confirm the right objects were deleted 1047 */ 1048 public void testCascadeDeleteAccount() { 1049 Account account1 = ProviderTestUtils.setupAccount("account-delete-cascade", true, 1050 mMockContext); 1051 long account1Id = account1.mId; 1052 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1053 long box1Id = box1.mId; 1054 /* Message message1 = */ ProviderTestUtils.setupMessage("message1", account1Id, box1Id, 1055 false, true, mMockContext); 1056 /* Message message2 = */ ProviderTestUtils.setupMessage("message2", account1Id, box1Id, 1057 false, true, mMockContext); 1058 1059 // make sure there is one account, one mailbox, and two messages 1060 int numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 1061 assertEquals(1, numAccounts); 1062 int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null); 1063 assertEquals(1, numBoxes); 1064 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1065 assertEquals(2, numMessages); 1066 1067 // delete the account 1068 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 1069 mMockContext.getContentResolver().delete(uri, null, null); 1070 1071 // make sure there are no accounts, mailboxes, or messages 1072 numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null); 1073 assertEquals(0, numAccounts); 1074 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null); 1075 assertEquals(0, numBoxes); 1076 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1077 assertEquals(0, numMessages); 1078 } 1079 1080 /** 1081 * Test cascaded delete mailbox 1082 * TODO: body 1083 * TODO: attachments 1084 * TODO: create other mailbox & messages and confirm the right objects were deleted 1085 */ 1086 public void testCascadeDeleteMailbox() { 1087 Account account1 = ProviderTestUtils.setupAccount("mailbox-delete-cascade", true, 1088 mMockContext); 1089 long account1Id = account1.mId; 1090 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1091 long box1Id = box1.mId; 1092 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, 1093 false, true, mMockContext); 1094 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, 1095 false, true, mMockContext); 1096 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, 1097 false, true, mMockContext); 1098 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, 1099 false, true, mMockContext); 1100 ProviderTestUtils.setupMessage("message5", account1Id, box1Id, false, true, mMockContext); 1101 ProviderTestUtils.setupMessage("message6", account1Id, box1Id, false, true, mMockContext); 1102 1103 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " + 1104 EmailContent.MessageColumns.MAILBOX_KEY + "=?"; 1105 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) }; 1106 1107 // make sure there are six messages 1108 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1109 assertEquals(6, numMessages); 1110 1111 ContentValues cv = new ContentValues(); 1112 cv.put(Message.SERVER_ID, "SERVER_ID"); 1113 ContentResolver resolver = mMockContext.getContentResolver(); 1114 1115 // Update two messages 1116 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1.mId), 1117 cv, null, null); 1118 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2.mId), 1119 cv, null, null); 1120 // Delete two messages 1121 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message3.mId), 1122 null, null); 1123 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message4.mId), 1124 null, null); 1125 1126 // There should now be two messages in updated/deleted, and 4 in messages 1127 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1128 assertEquals(4, numMessages); 1129 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1130 selArgs); 1131 assertEquals(2, numMessages); 1132 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1133 selArgs); 1134 assertEquals(2, numMessages); 1135 1136 // now delete the mailbox 1137 Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id); 1138 resolver.delete(uri, null, null); 1139 1140 // there should now be zero messages in all three tables 1141 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs); 1142 assertEquals(0, numMessages); 1143 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection, 1144 selArgs); 1145 assertEquals(0, numMessages); 1146 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection, 1147 selArgs); 1148 assertEquals(0, numMessages); 1149 } 1150 1151 /** 1152 * Test cascaded delete message 1153 * Confirms that deleting a message will also delete its body & attachments 1154 */ 1155 public void testCascadeMessageDelete() { 1156 Account account1 = ProviderTestUtils.setupAccount("message-cascade", true, mMockContext); 1157 long account1Id = account1.mId; 1158 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext); 1159 long box1Id = box1.mId; 1160 1161 // Each message has a body, and also give each 2 attachments 1162 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true, 1163 false, mMockContext); 1164 ArrayList<Attachment> atts = new ArrayList<Attachment>(); 1165 for (int i = 0; i < 2; i++) { 1166 atts.add(ProviderTestUtils.setupAttachment( 1167 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 1168 false, mMockContext)); 1169 } 1170 message1.mAttachments = atts; 1171 message1.save(mMockContext); 1172 long message1Id = message1.mId; 1173 1174 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, true, 1175 false, mMockContext); 1176 atts = new ArrayList<Attachment>(); 1177 for (int i = 0; i < 2; i++) { 1178 atts.add(ProviderTestUtils.setupAttachment( 1179 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i], 1180 false, mMockContext)); 1181 } 1182 message2.mAttachments = atts; 1183 message2.save(mMockContext); 1184 long message2Id = message2.mId; 1185 1186 // Set up to test total counts of bodies & attachments for our test messages 1187 String bodySelection = BodyColumns.MESSAGE_KEY + " IN (?,?)"; 1188 String attachmentSelection = AttachmentColumns.MESSAGE_KEY + " IN (?,?)"; 1189 String[] selArgs = new String[] { String.valueOf(message1Id), String.valueOf(message2Id) }; 1190 1191 // make sure there are two bodies 1192 int numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1193 assertEquals(2, numBodies); 1194 1195 // make sure there are four attachments 1196 int numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1197 attachmentSelection, selArgs); 1198 assertEquals(4, numAttachments); 1199 1200 // now delete one of the messages 1201 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id); 1202 mMockContext.getContentResolver().delete(uri, null, null); 1203 1204 // there should be one body and two attachments 1205 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1206 assertEquals(1, numBodies); 1207 1208 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1209 attachmentSelection, selArgs); 1210 assertEquals(2, numAttachments); 1211 1212 // now delete the other message 1213 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id); 1214 mMockContext.getContentResolver().delete(uri, null, null); 1215 1216 // make sure there are no bodies or attachments 1217 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs); 1218 assertEquals(0, numBodies); 1219 1220 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI, 1221 attachmentSelection, selArgs); 1222 assertEquals(0, numAttachments); 1223 } 1224 1225 /** 1226 * Test that our unique file name algorithm works as expected. Since this test requires an 1227 * SD card, we check the environment first, and return immediately if none is mounted. 1228 * @throws IOException 1229 */ 1230 public void testCreateUniqueFile() throws IOException { 1231 // Delete existing files, if they exist 1232 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 1233 return; 1234 } 1235 try { 1236 String fileName = "A11achm3n1.doc"; 1237 File uniqueFile = Attachment.createUniqueFile(fileName); 1238 assertEquals(fileName, uniqueFile.getName()); 1239 if (uniqueFile.createNewFile()) { 1240 uniqueFile = Attachment.createUniqueFile(fileName); 1241 assertEquals("A11achm3n1-2.doc", uniqueFile.getName()); 1242 if (uniqueFile.createNewFile()) { 1243 uniqueFile = Attachment.createUniqueFile(fileName); 1244 assertEquals("A11achm3n1-3.doc", uniqueFile.getName()); 1245 } 1246 } 1247 fileName = "A11achm3n1"; 1248 uniqueFile = Attachment.createUniqueFile(fileName); 1249 assertEquals(fileName, uniqueFile.getName()); 1250 if (uniqueFile.createNewFile()) { 1251 uniqueFile = Attachment.createUniqueFile(fileName); 1252 assertEquals("A11achm3n1-2", uniqueFile.getName()); 1253 } 1254 } finally { 1255 File directory = Environment.getExternalStorageDirectory(); 1256 // These are the files that should be created earlier in the test. Make sure 1257 // they are deleted for the next go-around 1258 String[] fileNames = new String[] {"A11achm3n1.doc", "A11achm3n1-2.doc", "A11achm3n1"}; 1259 int length = fileNames.length; 1260 for (int i = 0; i < length; i++) { 1261 File file = new File(directory, fileNames[i]); 1262 if (file.exists()) { 1263 file.delete(); 1264 } 1265 } 1266 } 1267 } 1268 1269 /** 1270 * Test retrieving attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI) 1271 */ 1272 public void testGetAttachmentByMessageIdUri() { 1273 1274 // Note, we don't strictly need accounts, mailboxes or messages to run this test. 1275 Attachment a1 = ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext); 1276 Attachment a2 = ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext); 1277 ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext); 1278 ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext); 1279 1280 // Now ask for the attachments of message id=1 1281 // Note: Using the "sort by size" trick to bring them back in expected order 1282 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1); 1283 Cursor c = mMockContext.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION, 1284 null, null, Attachment.SIZE); 1285 assertEquals(2, c.getCount()); 1286 1287 try { 1288 c.moveToFirst(); 1289 Attachment a1Get = EmailContent.getContent(c, Attachment.class); 1290 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-1", a1, a1Get); 1291 c.moveToNext(); 1292 Attachment a2Get = EmailContent.getContent(c, Attachment.class); 1293 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-2", a2, a2Get); 1294 } finally { 1295 c.close(); 1296 } 1297 } 1298 1299 /** 1300 * Test deleting attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI) 1301 */ 1302 public void testDeleteAttachmentByMessageIdUri() { 1303 ContentResolver mockResolver = mMockContext.getContentResolver(); 1304 1305 // Note, we don't strictly need accounts, mailboxes or messages to run this test. 1306 ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext); 1307 ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext); 1308 Attachment a3 = ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext); 1309 Attachment a4 = ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext); 1310 1311 // Delete all attachments for message id=1 1312 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1); 1313 mockResolver.delete(uri, null, null); 1314 1315 // Read back all attachments and confirm that we have the expected remaining attachments 1316 // (the attachments that are set for message id=2). Note order-by size to simplify test. 1317 Cursor c = mockResolver.query(Attachment.CONTENT_URI, Attachment.CONTENT_PROJECTION, 1318 null, null, Attachment.SIZE); 1319 assertEquals(2, c.getCount()); 1320 1321 try { 1322 c.moveToFirst(); 1323 Attachment a3Get = EmailContent.getContent(c, Attachment.class); 1324 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-3", a3, a3Get); 1325 c.moveToNext(); 1326 Attachment a4Get = EmailContent.getContent(c, Attachment.class); 1327 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-4", a4, a4Get); 1328 } finally { 1329 c.close(); 1330 } 1331 } 1332 1333 /** 1334 * Tests of default account behavior 1335 * 1336 * 1. Simple set/get 1337 * 2. Moving default between 3 accounts 1338 * 3. Delete default, make sure another becomes default 1339 */ 1340 public void testSetGetDefaultAccount() { 1341 // There should be no default account if there are no accounts 1342 long defaultAccountId = Account.getDefaultAccountId(mMockContext); 1343 assertEquals(-1, defaultAccountId); 1344 1345 Account account1 = ProviderTestUtils.setupAccount("account-default-1", true, mMockContext); 1346 long account1Id = account1.mId; 1347 Account account2 = ProviderTestUtils.setupAccount("account-default-2", true, mMockContext); 1348 long account2Id = account2.mId; 1349 Account account3 = ProviderTestUtils.setupAccount("account-default-3", true, mMockContext); 1350 long account3Id = account3.mId; 1351 1352 // With three accounts, but none marked default, confirm that some default account 1353 // is returned. Which one is undefined here. 1354 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1355 assertTrue(defaultAccountId == account1Id 1356 || defaultAccountId == account2Id 1357 || defaultAccountId == account3Id); 1358 1359 updateIsDefault(account1, true); 1360 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1361 assertEquals(account1Id, defaultAccountId); 1362 1363 updateIsDefault(account2, true); 1364 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1365 assertEquals(account2Id, defaultAccountId); 1366 1367 updateIsDefault(account3, true); 1368 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1369 assertEquals(account3Id, defaultAccountId); 1370 1371 // Now delete a non-default account and confirm no change 1372 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id); 1373 mMockContext.getContentResolver().delete(uri, null, null); 1374 1375 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1376 assertEquals(account3Id, defaultAccountId); 1377 1378 // Now confirm deleting the default account and it switches to another one 1379 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account3Id); 1380 mMockContext.getContentResolver().delete(uri, null, null); 1381 1382 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1383 assertEquals(account2Id, defaultAccountId); 1384 1385 // Now delete the final account and confirm there are no default accounts again 1386 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id); 1387 mMockContext.getContentResolver().delete(uri, null, null); 1388 1389 defaultAccountId = Account.getDefaultAccountId(mMockContext); 1390 assertEquals(-1, defaultAccountId); 1391 } 1392 1393 private void updateIsDefault(Account account, boolean newState) { 1394 account.setDefaultAccount(newState); 1395 ContentValues cv = new ContentValues(); 1396 cv.put(AccountColumns.IS_DEFAULT, account.mIsDefault); 1397 account.update(mMockContext, cv); 1398 } 1399 1400 public static Message setupUnreadMessage(String name, long accountId, long mailboxId, 1401 boolean addBody, boolean saveIt, Context context) { 1402 Message msg = 1403 ProviderTestUtils.setupMessage(name, accountId, mailboxId, addBody, false, context); 1404 msg.mFlagRead = false; 1405 if (saveIt) { 1406 msg.save(context); 1407 } 1408 return msg; 1409 } 1410 1411 public void testUnreadCountTriggers() { 1412 // Start with one account and three mailboxes 1413 Account account = ProviderTestUtils.setupAccount("triggers", true, mMockContext); 1414 Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext); 1415 Mailbox boxB = ProviderTestUtils.setupMailbox("boxB", account.mId, true, mMockContext); 1416 Mailbox boxC = ProviderTestUtils.setupMailbox("boxC", account.mId, true, mMockContext); 1417 1418 // Make sure there are no unreads 1419 assertEquals(0, getUnreadCount(boxA.mId)); 1420 assertEquals(0, getUnreadCount(boxB.mId)); 1421 assertEquals(0, getUnreadCount(boxC.mId)); 1422 1423 // Create 4 unread messages (only 3 named) in boxA 1424 Message message1 = setupUnreadMessage("message1", account.mId, boxA.mId, 1425 false, true, mMockContext); 1426 Message message2= setupUnreadMessage("message2", account.mId, boxA.mId, 1427 false, true, mMockContext); 1428 Message message3 = setupUnreadMessage("message3", account.mId, boxA.mId, 1429 false, true, mMockContext); 1430 setupUnreadMessage("message4", account.mId, boxC.mId, false, true, mMockContext); 1431 1432 // Make sure the unreads are where we expect them 1433 assertEquals(3, getUnreadCount(boxA.mId)); 1434 assertEquals(0, getUnreadCount(boxB.mId)); 1435 assertEquals(1, getUnreadCount(boxC.mId)); 1436 1437 // After deleting message 1, the count in box A should be decremented (to 2) 1438 ContentResolver cr = mMockContext.getContentResolver(); 1439 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1.mId); 1440 cr.delete(uri, null, null); 1441 assertEquals(2, getUnreadCount(boxA.mId)); 1442 assertEquals(0, getUnreadCount(boxB.mId)); 1443 assertEquals(1, getUnreadCount(boxC.mId)); 1444 1445 // Move message 2 to box B, leaving 1 in box A and 1 in box B 1446 message2.mMailboxKey = boxB.mId; 1447 ContentValues cv = new ContentValues(); 1448 cv.put(MessageColumns.MAILBOX_KEY, boxB.mId); 1449 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message2.mId), cv, null, null); 1450 assertEquals(1, getUnreadCount(boxA.mId)); 1451 assertEquals(1, getUnreadCount(boxB.mId)); 1452 assertEquals(1, getUnreadCount(boxC.mId)); 1453 1454 // Mark message 3 (from box A) read, leaving 0 in box A 1455 cv.clear(); 1456 cv.put(MessageColumns.FLAG_READ, 1); 1457 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1458 assertEquals(0, getUnreadCount(boxA.mId)); 1459 assertEquals(1, getUnreadCount(boxB.mId)); 1460 assertEquals(1, getUnreadCount(boxC.mId)); 1461 1462 // Move message 3 to box C; should be no change (it's read) 1463 message3.mMailboxKey = boxC.mId; 1464 cv.clear(); 1465 cv.put(MessageColumns.MAILBOX_KEY, boxC.mId); 1466 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1467 assertEquals(0, getUnreadCount(boxA.mId)); 1468 assertEquals(1, getUnreadCount(boxB.mId)); 1469 assertEquals(1, getUnreadCount(boxC.mId)); 1470 1471 // Mark message 3 unread; it's now in box C, so that box's count should go up to 3 1472 cv.clear(); 1473 cv.put(MessageColumns.FLAG_READ, 0); 1474 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null); 1475 assertEquals(0, getUnreadCount(boxA.mId)); 1476 assertEquals(1, getUnreadCount(boxB.mId)); 1477 assertEquals(2, getUnreadCount(boxC.mId)); 1478 } 1479 1480 /** 1481 * Test for EmailProvider.createIndex(). 1482 * Check that it returns exacly the same string as the one used previously for index creation. 1483 */ 1484 public void testCreateIndex() { 1485 String oldStr = "create index message_" + MessageColumns.TIMESTAMP 1486 + " on " + Message.TABLE_NAME + " (" + MessageColumns.TIMESTAMP + ");"; 1487 String newStr = EmailProvider.createIndex(Message.TABLE_NAME, MessageColumns.TIMESTAMP); 1488 assertEquals(newStr, oldStr); 1489 } 1490 1491 public void testIdAddToField() { 1492 ContentResolver cr = mMockContext.getContentResolver(); 1493 ContentValues cv = new ContentValues(); 1494 1495 // Try changing the newMessageCount of an account 1496 Account account = ProviderTestUtils.setupAccount("field-add", true, mMockContext); 1497 int startCount = account.mNewMessageCount; 1498 // "field" and "add" are the two required elements 1499 cv.put(EmailContent.FIELD_COLUMN_NAME, AccountColumns.NEW_MESSAGE_COUNT); 1500 cv.put(EmailContent.ADD_COLUMN_NAME, 17); 1501 cr.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, account.mId), 1502 cv, null, null); 1503 Account restoredAccount = Account.restoreAccountWithId(mMockContext, account.mId); 1504 assertEquals(17 + startCount, restoredAccount.mNewMessageCount); 1505 cv.put(EmailContent.ADD_COLUMN_NAME, -11); 1506 cr.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, account.mId), 1507 cv, null, null); 1508 restoredAccount = Account.restoreAccountWithId(mMockContext, account.mId); 1509 assertEquals(17 - 11 + startCount, restoredAccount.mNewMessageCount); 1510 1511 // Now try with a mailbox 1512 Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext); 1513 assertEquals(0, boxA.mUnreadCount); 1514 cv.put(EmailContent.FIELD_COLUMN_NAME, MailboxColumns.UNREAD_COUNT); 1515 cv.put(EmailContent.ADD_COLUMN_NAME, 11); 1516 cr.update(ContentUris.withAppendedId(Mailbox.ADD_TO_FIELD_URI, boxA.mId), cv, null, null); 1517 Mailbox restoredBoxA = Mailbox.restoreMailboxWithId(mMockContext, boxA.mId); 1518 assertEquals(11, restoredBoxA.mUnreadCount); 1519 } 1520 1521 public void testDatabaseCorruptionRecovery() { 1522 final ContentResolver resolver = mMockContext.getContentResolver(); 1523 final Context context = mMockContext; 1524 1525 // Create account and two mailboxes 1526 Account acct = ProviderTestUtils.setupAccount("acct1", true, context); 1527 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 1528 1529 // Create 4 messages in box1 with bodies 1530 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context); 1531 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context); 1532 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context); 1533 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context); 1534 1535 // Confirm there are four messages 1536 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1537 assertEquals(4, count); 1538 // Confirm there are four bodies 1539 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1540 assertEquals(4, count); 1541 1542 // Find the EmailProvider.db file 1543 File dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME); 1544 // The EmailProvider.db database should exist (the provider creates it automatically) 1545 assertTrue(dbFile != null); 1546 assertTrue(dbFile.exists()); 1547 // Delete it, and confirm it is gone 1548 assertTrue(dbFile.delete()); 1549 assertFalse(dbFile.exists()); 1550 1551 // Find the EmailProviderBody.db file 1552 dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME); 1553 // The EmailProviderBody.db database should still exist 1554 assertTrue(dbFile != null); 1555 assertTrue(dbFile.exists()); 1556 1557 // URI to uncache the databases 1558 // This simulates the Provider starting up again (otherwise, it will still be pointing to 1559 // the already opened files) 1560 // Note that we only have access to the EmailProvider via the ContentResolver; therefore, 1561 // we cannot directly call into the provider and use a URI for this 1562 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null); 1563 1564 // TODO We should check for the deletion of attachment files once this is implemented in 1565 // the provider 1566 1567 // Explanation for what happens below... 1568 // The next time the database is created by the provider, it will notice that there's 1569 // already a EmailProviderBody.db file. In this case, it will delete that database to 1570 // ensure that both are in sync (and empty) 1571 1572 // Confirm there are no bodies 1573 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1574 assertEquals(0, count); 1575 1576 // Confirm there are no messages 1577 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1578 assertEquals(0, count); 1579 } 1580 1581 public void testBodyDatabaseCorruptionRecovery() { 1582 final ContentResolver resolver = mMockContext.getContentResolver(); 1583 final Context context = mMockContext; 1584 1585 // Create account and two mailboxes 1586 Account acct = ProviderTestUtils.setupAccount("acct1", true, context); 1587 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context); 1588 1589 // Create 4 messages in box1 with bodies 1590 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context); 1591 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context); 1592 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context); 1593 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context); 1594 1595 // Confirm there are four messages 1596 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1597 assertEquals(4, count); 1598 // Confirm there are four bodies 1599 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1600 assertEquals(4, count); 1601 1602 // Find the EmailProviderBody.db file 1603 File dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME); 1604 // The EmailProviderBody.db database should exist (the provider creates it automatically) 1605 assertTrue(dbFile != null); 1606 assertTrue(dbFile.exists()); 1607 // Delete it, and confirm it is gone 1608 assertTrue(dbFile.delete()); 1609 assertFalse(dbFile.exists()); 1610 1611 // Find the EmailProvider.db file 1612 dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME); 1613 // The EmailProviderBody.db database should still exist 1614 assertTrue(dbFile != null); 1615 assertTrue(dbFile.exists()); 1616 1617 // URI to uncache the databases 1618 // This simulates the Provider starting up again (otherwise, it will still be pointing to 1619 // the already opened files) 1620 // Note that we only have access to the EmailProvider via the ContentResolver; therefore, 1621 // we cannot directly call into the provider and use a URI for this 1622 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null); 1623 1624 // TODO We should check for the deletion of attachment files once this is implemented in 1625 // the provider 1626 1627 // Explanation for what happens below... 1628 // The next time the body database is created by the provider, it will notice that there's 1629 // already a populated EmailProvider.db file. In this case, it will delete that database to 1630 // ensure that both are in sync (and empty) 1631 1632 // Confirm there are no messages 1633 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null); 1634 assertEquals(0, count); 1635 1636 // Confirm there are no bodies 1637 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null); 1638 assertEquals(0, count); 1639 } 1640 1641 public void testFindMailboxOfType() { 1642 final Context context = mMockContext; 1643 1644 // Create two accounts and a variety of mailbox types 1645 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context); 1646 Mailbox acct1Inbox = 1647 ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX); 1648 Mailbox acct1Calendar 1649 = ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR); 1650 Mailbox acct1Contacts = 1651 ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS); 1652 Account acct2 = ProviderTestUtils.setupAccount("acct1", true, context); 1653 Mailbox acct2Inbox = 1654 ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX); 1655 Mailbox acct2Calendar = 1656 ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR); 1657 Mailbox acct2Contacts = 1658 ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS); 1659 1660 // Check that we can find them by type 1661 assertEquals(acct1Inbox.mId, 1662 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX)); 1663 assertEquals(acct2Inbox.mId, 1664 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX)); 1665 assertEquals(acct1Calendar.mId, 1666 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR)); 1667 assertEquals(acct2Calendar.mId, 1668 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR)); 1669 assertEquals(acct1Contacts.mId, 1670 Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS)); 1671 assertEquals(acct2Contacts.mId, 1672 Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS)); 1673 } 1674 1675 public void testRestoreMailboxOfType() { 1676 final Context context = mMockContext; 1677 1678 // Create two accounts and a variety of mailbox types 1679 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context); 1680 Mailbox acct1Inbox = 1681 ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX); 1682 Mailbox acct1Calendar 1683 = ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR); 1684 Mailbox acct1Contacts = 1685 ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS); 1686 Account acct2 = ProviderTestUtils.setupAccount("acct1", true, context); 1687 Mailbox acct2Inbox = 1688 ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX); 1689 Mailbox acct2Calendar = 1690 ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR); 1691 Mailbox acct2Contacts = 1692 ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS); 1693 1694 // Check that we can find them by type 1695 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Inbox, 1696 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX)); 1697 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Inbox, 1698 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX)); 1699 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Calendar, 1700 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR)); 1701 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Calendar, 1702 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR)); 1703 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Contacts, 1704 Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS)); 1705 ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Contacts, 1706 Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS)); 1707 } 1708} 1709