1 /* 2 * Copyright (C) 2011 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 17 package com.android.exchange.provider; 18 19 import com.android.emailcommon.provider.Account; 20 import com.android.emailcommon.provider.EmailContent.MailboxColumns; 21 import com.android.emailcommon.provider.Mailbox; 22 import com.android.exchange.utility.ExchangeTestCase; 23 24 import android.content.ContentResolver; 25 import android.content.ContentUris; 26 import android.content.ContentValues; 27 import android.test.suitebuilder.annotation.MediumTest; 28 29 /** 30 * Tests of MailboxUtilities. 31 * 32 * You can run this entire test case with: 33 * runtest -c com.android.exchange.provider.MailboxUtilitiesTests exchange 34 */ 35 @MediumTest 36 public class MailboxUtilitiesTests extends ExchangeTestCase { 37 38 // All tests must build their accounts in mAccount so it will be deleted from live data 39 private Account mAccount; 40 private ContentResolver mResolver; 41 private ContentValues mNullParentKey; 42 43 // Flag sets found in regular email folders that are parents or children 44 private static final int PARENT_FLAGS = 45 Mailbox.FLAG_ACCEPTS_MOVED_MAIL | Mailbox.FLAG_HOLDS_MAIL | 46 Mailbox.FLAG_HAS_CHILDREN | Mailbox.FLAG_CHILDREN_VISIBLE; 47 private static final int CHILD_FLAGS = 48 Mailbox.FLAG_ACCEPTS_MOVED_MAIL | Mailbox.FLAG_HOLDS_MAIL; 49 50 @Override 51 public void setUp() throws Exception { 52 super.setUp(); 53 mAccount = null; 54 mResolver = mProviderContext.getContentResolver(); 55 mNullParentKey = new ContentValues(); 56 mNullParentKey.putNull(Mailbox.PARENT_KEY); 57 } 58 59 @Override 60 public void tearDown() throws Exception { 61 super.tearDown(); 62 // If we've created and saved an account, delete it 63 if (mAccount != null && mAccount.mId > 0) { 64 mResolver.delete( 65 ContentUris.withAppendedId(Account.CONTENT_URI, mAccount.mId), null, null); 66 } 67 } 68 69 public void testSetupParentKeyAndFlag() { 70 // Set up account and various mailboxes with/without parents 71 mAccount = setupTestAccount("acct1", true); 72 Mailbox box1 = EmailContentSetupUtils.setupMailbox("box1", mAccount.mId, true, 73 mProviderContext, Mailbox.TYPE_DRAFTS); 74 Mailbox box2 = EmailContentSetupUtils.setupMailbox("box2", mAccount.mId, true, 75 mProviderContext, Mailbox.TYPE_OUTBOX, box1); 76 Mailbox box3 = EmailContentSetupUtils.setupMailbox("box3", mAccount.mId, true, 77 mProviderContext, Mailbox.TYPE_ATTACHMENT, box1); 78 Mailbox box4 = EmailContentSetupUtils.setupMailbox("box4", mAccount.mId, true, 79 mProviderContext, Mailbox.TYPE_NOT_SYNCABLE + 64, box3); 80 Mailbox box5 = EmailContentSetupUtils.setupMailbox("box5", mAccount.mId, true, 81 mProviderContext, Mailbox.TYPE_MAIL, box3); 82 83 // To make this work, we need to manually set parentKey to null for all mailboxes 84 // This simulates an older database needing update 85 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 86 87 // Hand-create the account selector for our account 88 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 89 90 // Fix up the database and restore the mailboxes 91 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 92 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 93 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 94 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 95 box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId); 96 box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId); 97 98 // Test that flags and parent key are set properly 99 assertEquals(Mailbox.FLAG_HOLDS_MAIL | Mailbox.FLAG_HAS_CHILDREN | 100 Mailbox.FLAG_CHILDREN_VISIBLE, box1.mFlags); 101 assertEquals(-1, box1.mParentKey); 102 103 assertEquals(Mailbox.FLAG_HOLDS_MAIL, box2.mFlags); 104 assertEquals(box1.mId, box2.mParentKey); 105 106 assertEquals(Mailbox.FLAG_HAS_CHILDREN | Mailbox.FLAG_CHILDREN_VISIBLE, box3.mFlags); 107 assertEquals(box1.mId, box3.mParentKey); 108 109 assertEquals(0, box4.mFlags); 110 assertEquals(box3.mId, box4.mParentKey); 111 112 assertEquals(Mailbox.FLAG_HOLDS_MAIL | Mailbox.FLAG_ACCEPTS_MOVED_MAIL, box5.mFlags); 113 assertEquals(box3.mId, box5.mParentKey); 114 } 115 116 private void simulateFolderSyncChangeHandling(String accountSelector, Mailbox...mailboxes) { 117 // Run the parent key analyzer and reload the mailboxes 118 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 119 for (Mailbox mailbox: mailboxes) { 120 String serverId = mailbox.mServerId; 121 MailboxUtilities.setFlagsAndChildrensParentKey(mProviderContext, accountSelector, 122 serverId); 123 } 124 } 125 126 /** 127 * Test three cases of adding a folder to an existing hierarchy. Case 1: Add to parent. 128 */ 129 public void testParentKeyAddFolder1() { 130 // Set up account and various mailboxes with/without parents 131 mAccount = setupTestAccount("acct1", true); 132 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 133 134 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 135 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 136 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 137 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 138 139 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 140 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 141 142 // Run the parent key analyzer to set up the initial hierarchy. 143 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 144 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 145 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 146 147 // Confirm flags and parent key(s) as expected 148 assertEquals(PARENT_FLAGS, box1.mFlags); 149 assertEquals(-1, box1.mParentKey); 150 151 assertEquals(CHILD_FLAGS, box2.mFlags); 152 assertEquals(box1.mId, box2.mParentKey); 153 154 // The specific test: Create a 3rd mailbox and attach it to box1 (already a parent) 155 156 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 157 "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box1); 158 box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED; 159 box3.save(mProviderContext); 160 simulateFolderSyncChangeHandling(accountSelector, box1 /*box3's parent*/); 161 162 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 163 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 164 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 165 166 // Confirm flags and parent key(s) as expected 167 assertEquals(PARENT_FLAGS, box1.mFlags); 168 assertEquals(-1, box1.mParentKey); 169 170 assertEquals(CHILD_FLAGS, box2.mFlags); 171 assertEquals(box1.mId, box2.mParentKey); 172 173 assertEquals(CHILD_FLAGS, box3.mFlags); 174 assertEquals(box1.mId, box3.mParentKey); 175 } 176 177 /** 178 * Test three cases of adding a folder to an existing hierarchy. Case 2: Add to child. 179 */ 180 public void testParentKeyAddFolder2() { 181 // Set up account and various mailboxes with/without parents 182 mAccount = setupTestAccount("acct1", true); 183 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 184 185 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 186 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 187 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 188 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 189 190 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 191 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 192 193 // Run the parent key analyzer to set up the initial hierarchy. 194 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 195 196 // Skipping tests of initial hierarchy - see testParentKeyAddFolder1() 197 198 // The specific test: Create a 3rd mailbox and attach it to box2 (currently a child) 199 200 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 201 "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box2); 202 box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED; 203 box3.save(mProviderContext); 204 simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's parent*/); 205 206 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 207 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 208 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 209 210 // Confirm flags and parent key(s) as expected 211 assertEquals(PARENT_FLAGS, box1.mFlags); 212 assertEquals(-1, box1.mParentKey); 213 214 assertEquals(PARENT_FLAGS, box2.mFlags); // should become a parent 215 assertEquals(box1.mId, box2.mParentKey); 216 217 assertEquals(CHILD_FLAGS, box3.mFlags); // should be child of box2 218 assertEquals(box2.mId, box3.mParentKey); 219 } 220 221 /** 222 * Test three cases of adding a folder to an existing hierarchy. Case 3: Add to root. 223 */ 224 public void testParentKeyAddFolder3() { 225 // Set up account and various mailboxes with/without parents 226 mAccount = setupTestAccount("acct1", true); 227 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 228 229 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 230 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 231 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 232 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 233 234 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 235 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 236 237 // Run the parent key analyzer to set up the initial hierarchy. 238 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 239 240 // Skipping tests of initial hierarchy - see testParentKeyAddFolder1() 241 242 // The specific test: Create a 3rd mailbox and give it no parent (it's top-level). 243 244 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 245 "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL); 246 box3.mParentKey = Mailbox.PARENT_KEY_UNINITIALIZED; 247 box3.save(mProviderContext); 248 249 simulateFolderSyncChangeHandling(accountSelector); 250 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 251 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 252 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 253 254 // Confirm flags and parent key(s) as expected 255 assertEquals(PARENT_FLAGS, box1.mFlags); 256 assertEquals(-1, box1.mParentKey); 257 258 assertEquals(CHILD_FLAGS, box2.mFlags); 259 assertEquals(box1.mId, box2.mParentKey); 260 261 assertEquals(CHILD_FLAGS, box3.mFlags); 262 assertEquals(-1, box3.mParentKey); 263 } 264 265 /** 266 * Test three cases of removing a folder from the hierarchy. Case 1: Remove from parent. 267 */ 268 public void testParentKeyRemoveFolder1() { 269 // Set up account and mailboxes 270 mAccount = setupTestAccount("acct1", true); 271 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 272 273 // Initial configuration for this test: box1 has two children. 274 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 275 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 276 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 277 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 278 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 279 "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 280 281 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 282 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 283 284 // Confirm initial configuration as expected 285 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 286 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 287 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 288 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 289 290 // Confirm flags and parent key(s) as expected 291 assertEquals(PARENT_FLAGS, box1.mFlags); 292 assertEquals(-1, box1.mParentKey); 293 294 assertEquals(CHILD_FLAGS, box2.mFlags); 295 assertEquals(box1.mId, box2.mParentKey); 296 297 assertEquals(CHILD_FLAGS, box3.mFlags); 298 assertEquals(box1.mId, box3.mParentKey); 299 300 // The specific test: Delete box3 and check remaining configuration 301 mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null); 302 simulateFolderSyncChangeHandling(accountSelector, box1 /*box3's parent*/); 303 304 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 305 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 306 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 307 308 // Confirm flags and parent key(s) as expected 309 assertEquals(PARENT_FLAGS, box1.mFlags); // Should still be a parent 310 assertEquals(-1, box1.mParentKey); 311 312 assertEquals(CHILD_FLAGS, box2.mFlags); 313 assertEquals(box1.mId, box2.mParentKey); 314 315 assertNull(box3); 316 } 317 318 /** 319 * Test three cases of removing a folder from the hierarchy. Case 2: Remove from child. 320 */ 321 public void testParentKeyRemoveFolder2() { 322 // Set up account and mailboxes 323 mAccount = setupTestAccount("acct1", true); 324 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 325 326 // Initial configuration for this test: box1 has box2 and box2 has box3. 327 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 328 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 329 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 330 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 331 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 332 "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box2); 333 334 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 335 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 336 337 // Confirm initial configuration as expected 338 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 339 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 340 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 341 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 342 343 // Confirm flags and parent key(s) as expected 344 assertEquals(PARENT_FLAGS, box1.mFlags); 345 assertEquals(-1, box1.mParentKey); 346 347 assertEquals(PARENT_FLAGS, box2.mFlags); // becomes a parent 348 assertEquals(box1.mId, box2.mParentKey); 349 350 assertEquals(CHILD_FLAGS, box3.mFlags); 351 assertEquals(box2.mId, box3.mParentKey); 352 353 // The specific test: Delete box3 and check remaining configuration 354 mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null); 355 simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's parent*/); 356 357 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 358 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 359 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 360 361 // Confirm flags and parent key(s) as expected 362 assertEquals(PARENT_FLAGS, box1.mFlags); // Should still be a parent 363 assertEquals(-1, box1.mParentKey); 364 365 assertEquals(CHILD_FLAGS, box2.mFlags); // Becomes a child 366 assertEquals(box1.mId, box2.mParentKey); 367 368 assertNull(box3); 369 } 370 371 /** 372 * Test three cases of removing a folder from the hierarchy. Case 3: Remove from root. 373 */ 374 public void testParentKeyRemoveFolder3() { 375 // Set up account and mailboxes 376 mAccount = setupTestAccount("acct1", true); 377 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 378 379 // Initial configuration for this test: box1 has box2, box3 is also at root. 380 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 381 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 382 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 383 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 384 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 385 "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 386 387 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 388 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 389 390 // Confirm initial configuration as expected 391 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 392 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 393 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 394 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 395 396 // Confirm flags and parent key(s) as expected 397 assertEquals(PARENT_FLAGS, box1.mFlags); 398 assertEquals(-1, box1.mParentKey); 399 400 assertEquals(CHILD_FLAGS, box2.mFlags); 401 assertEquals(box1.mId, box2.mParentKey); 402 403 assertEquals(CHILD_FLAGS, box3.mFlags); 404 assertEquals(-1, box3.mParentKey); 405 406 // The specific test: Delete box3 and check remaining configuration 407 mResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), null, null); 408 simulateFolderSyncChangeHandling(accountSelector); 409 410 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 411 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 412 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 413 414 // Confirm flags and parent key(s) as expected 415 assertEquals(PARENT_FLAGS, box1.mFlags); // Should still be a parent 416 assertEquals(-1, box1.mParentKey); 417 418 assertEquals(CHILD_FLAGS, box2.mFlags); // Should still be a child 419 assertEquals(box1.mId, box2.mParentKey); 420 421 assertNull(box3); 422 } 423 424 /** 425 * Test changing a parent from none 426 */ 427 public void testChangeFromNoParentToParent() { 428 // Set up account and mailboxes 429 mAccount = setupTestAccount("acct1", true); 430 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 431 432 // Initial configuration for this test: box1 has box2, box3 is also at root. 433 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 434 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 435 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 436 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 437 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 438 "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 439 440 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 441 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 442 443 // Confirm initial configuration as expected 444 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 445 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 446 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 447 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 448 449 // Confirm flags and parent key(s) as expected 450 assertEquals(PARENT_FLAGS, box1.mFlags); 451 assertEquals(-1, box1.mParentKey); 452 453 assertEquals(CHILD_FLAGS, box2.mFlags); 454 assertEquals(box1.mId, box2.mParentKey); 455 456 assertEquals(CHILD_FLAGS, box3.mFlags); 457 assertEquals(-1, box3.mParentKey); 458 459 // The specific test: Give box 3 a new parent (box 2) and check remaining configuration 460 ContentValues values = new ContentValues(); 461 values.put(Mailbox.PARENT_SERVER_ID, box2.mServerId); 462 mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), values, 463 null, null); 464 simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's new parent*/); 465 466 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 467 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 468 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 469 470 // Confirm flags and parent key(s) as expected 471 assertEquals(PARENT_FLAGS, box1.mFlags); // Should still be a parent 472 assertEquals(-1, box1.mParentKey); 473 474 assertEquals(PARENT_FLAGS, box2.mFlags); // Should now be a parent 475 assertEquals(box1.mId, box2.mParentKey); 476 477 assertEquals(CHILD_FLAGS, box3.mFlags); // Should still be a child (of box2) 478 assertEquals(box2.mId, box3.mParentKey); 479 } 480 481 /** 482 * Test changing to no parent from a parent 483 */ 484 public void testChangeFromParentToNoParent() { 485 // Set up account and mailboxes 486 mAccount = setupTestAccount("acct1", true); 487 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 488 489 // Initial configuration for this test: box1 has box2, box3 is also at root. 490 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 491 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 492 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 493 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 494 495 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 496 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 497 498 // Confirm initial configuration as expected 499 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 500 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 501 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 502 503 // Confirm flags and parent key(s) as expected 504 assertEquals(PARENT_FLAGS, box1.mFlags); 505 assertEquals(-1, box1.mParentKey); 506 507 assertEquals(CHILD_FLAGS, box2.mFlags); 508 assertEquals(box1.mId, box2.mParentKey); 509 510 // The specific test: Remove the parent from box2 and check remaining configuration 511 ContentValues values = new ContentValues(); 512 values.putNull(Mailbox.PARENT_SERVER_ID); 513 mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2.mId), values, 514 null, null); 515 // Note: FolderSync handling of changed folder would cause parent key to be uninitialized 516 // so we do so here 517 mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2.mId), mNullParentKey, 518 null, null); 519 simulateFolderSyncChangeHandling(accountSelector, box1 /*box2's old parent*/); 520 521 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 522 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 523 524 // Confirm flags and parent key(s) as expected 525 assertEquals(CHILD_FLAGS, box1.mFlags); // Should no longer be a parent 526 assertEquals(-1, box1.mParentKey); 527 528 assertEquals(CHILD_FLAGS, box2.mFlags); // Should still be a child (no parent) 529 assertEquals(-1, box2.mParentKey); 530 } 531 532 /** 533 * Test a mailbox that has no server id (Hotmail Outbox is an example of this) 534 */ 535 public void testNoServerId() { 536 // Set up account and mailboxes 537 mAccount = setupTestAccount("acct1", true); 538 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 539 540 // Initial configuration for this test: box1 has no serverId, box2 is a child of box1 541 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 542 "box1", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL); 543 box1.mServerId = null; 544 box1.save(mProviderContext); 545 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 546 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_OUTBOX, box1); 547 548 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 549 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 550 551 // Confirm initial configuration as expected 552 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 553 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 554 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 555 556 // Box 1 should be a child, even though it is defined as the parent of box2, because it 557 // has no serverId (presumably, this case can't happen, because a child stores the parent's 558 // serverId, but it's nice to know it's handled properly). Box 1 should have no parent. 559 assertEquals(Mailbox.NO_MAILBOX, box1.mParentKey); 560 assertEquals(CHILD_FLAGS, box1.mFlags); 561 // Box 2 should be a child with no parent (see above). Since it's an outbox, the flags are 562 // only "holds mail". 563 assertEquals(Mailbox.NO_MAILBOX, box2.mParentKey); 564 assertEquals(Mailbox.FLAG_HOLDS_MAIL, box2.mFlags); 565 } 566 567 /** 568 * Test changing a parent from one mailbox to another 569 */ 570 public void testChangeParent() { 571 // Set up account and mailboxes 572 mAccount = setupTestAccount("acct1", true); 573 String accountSelector = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 574 575 // Initial configuration for this test: box1 has box2, box3 is also at root. 576 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 577 "box1", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 578 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 579 "box2", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL); 580 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 581 "box3", mAccount.mId, true, mProviderContext, Mailbox.TYPE_MAIL, box1); 582 583 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 584 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 585 586 // Confirm initial configuration as expected 587 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector); 588 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 589 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 590 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 591 592 // Confirm flags and parent key(s) as expected 593 assertEquals(PARENT_FLAGS, box1.mFlags); 594 assertEquals(-1, box1.mParentKey); 595 596 assertEquals(CHILD_FLAGS, box2.mFlags); 597 assertEquals(-1, box2.mParentKey); 598 599 assertEquals(CHILD_FLAGS, box3.mFlags); 600 assertEquals(box1.mId, box3.mParentKey); 601 602 // The specific test: Give box 3 a new parent (box 2) and check remaining configuration 603 ContentValues values = new ContentValues(); 604 values.put(Mailbox.PARENT_SERVER_ID, box2.mServerId); 605 mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box3.mId), values, 606 null, null); 607 // Changes to old and new parent 608 simulateFolderSyncChangeHandling(accountSelector, box2 /*box3's new parent*/, 609 box1 /*box3's old parent*/); 610 611 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 612 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 613 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 614 615 // Confirm flags and parent key(s) as expected 616 assertEquals(CHILD_FLAGS, box1.mFlags); // Should no longer be a parent 617 assertEquals(-1, box1.mParentKey); 618 619 assertEquals(PARENT_FLAGS, box2.mFlags); // Should now be a parent 620 assertEquals(-1, box2.mParentKey); 621 622 assertEquals(CHILD_FLAGS, box3.mFlags); // Should still be a child (of box2) 623 assertEquals(box2.mId, box3.mParentKey); 624 } 625 626 627 /** 628 * Tests the proper separation of two accounts using the methodology from the previous test. 629 * This test will fail if MailboxUtilities fails to distinguish between mailboxes in different 630 * accounts that happen to have the same serverId 631 */ 632 public void testChangeParentTwoAccounts() { 633 // Set up account and mailboxes 634 mAccount = setupTestAccount("acct1", true); 635 Account acct2 = setupTestAccount("acct2", true); 636 637 String accountSelector1 = MailboxColumns.ACCOUNT_KEY + " IN (" + mAccount.mId + ")"; 638 String accountSelector2 = MailboxColumns.ACCOUNT_KEY + " IN (" + acct2.mId + ")"; 639 640 // Box3 is in Box1 641 Mailbox box1 = EmailContentSetupUtils.setupMailbox( 642 "box1", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL); 643 box1.mServerId = "1:1"; 644 box1.save(mProviderContext); 645 Mailbox box2 = EmailContentSetupUtils.setupMailbox( 646 "box2", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL); 647 box2.mServerId = "1:2"; 648 box2.save(mProviderContext); 649 Mailbox box3 = EmailContentSetupUtils.setupMailbox( 650 "box3", mAccount.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box1); 651 box3.mServerId = "1:3"; 652 box3.save(mProviderContext); 653 654 // Box5 is in Box4; Box 6 is in Box5 655 // Note that the three serverId's are identical to those in acct1; we want to make sure 656 // that children get associated only with boxes in their own account 657 Mailbox box4 = EmailContentSetupUtils.setupMailbox( 658 "box4", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, null); 659 box4.mServerId = "1:1"; 660 box4.save(mProviderContext); 661 Mailbox box5 = EmailContentSetupUtils.setupMailbox( 662 "box5", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box4); 663 box5.mServerId = "1:2"; 664 box5.save(mProviderContext); 665 Mailbox box6 = EmailContentSetupUtils.setupMailbox( 666 "box6", acct2.mId, false, mProviderContext, Mailbox.TYPE_MAIL, box5); 667 box6.mServerId = "1:3"; 668 box6.save(mProviderContext); 669 670 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 671 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 672 673 // Confirm initial configuration as expected for mAccount 674 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector1); 675 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 676 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 677 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 678 679 // Confirm flags and parent key(s) as expected 680 assertEquals(PARENT_FLAGS, box1.mFlags); 681 assertEquals(-1, box1.mParentKey); 682 683 assertEquals(CHILD_FLAGS, box2.mFlags); 684 assertEquals(-1, box2.mParentKey); 685 686 assertEquals(CHILD_FLAGS, box3.mFlags); 687 assertEquals(box1.mId, box3.mParentKey); 688 689 // Confirm initial configuration as expected for acct2 690 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector2); 691 box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId); 692 box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId); 693 box6 = Mailbox.restoreMailboxWithId(mProviderContext, box6.mId); 694 695 // Confirm flags and parent key(s) as expected 696 assertEquals(PARENT_FLAGS, box4.mFlags); 697 assertEquals(-1, box4.mParentKey); 698 699 assertEquals(PARENT_FLAGS, box5.mFlags); 700 assertEquals(box4.mId, box5.mParentKey); 701 702 assertEquals(CHILD_FLAGS, box6.mFlags); 703 assertEquals(box5.mId, box6.mParentKey); 704 705 // The specific test: Change box1 to have a different serverId 706 ContentValues values = new ContentValues(); 707 values.put(MailboxColumns.SERVER_ID, "1:4"); 708 mResolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1.mId), values, 709 null, null); 710 // Manually set parentKey to null for all mailboxes, as if an initial sync or post-upgrade 711 mResolver.update(Mailbox.CONTENT_URI, mNullParentKey, null, null); 712 // Fix up the parent keys 713 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector1); 714 715 // Make sure that box1 reflects the change properly AND that other boxes remain correct 716 // The reason for all of the seemingly-duplicated tests is to make sure that the fixup of 717 // any account doesn't end up affecting the other account's mailboxes 718 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 719 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 720 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 721 722 // Confirm flags and parent key(s) as expected 723 assertEquals(CHILD_FLAGS, box1.mFlags); 724 assertEquals(-1, box1.mParentKey); 725 726 assertEquals(CHILD_FLAGS, box2.mFlags); 727 assertEquals(-1, box2.mParentKey); 728 729 assertEquals(CHILD_FLAGS, box3.mFlags); 730 assertEquals(-1, box3.mParentKey); 731 732 // Fix up the 2nd account now, and check that ALL boxes are correct 733 MailboxUtilities.fixupUninitializedParentKeys(mProviderContext, accountSelector2); 734 735 box1 = Mailbox.restoreMailboxWithId(mProviderContext, box1.mId); 736 box2 = Mailbox.restoreMailboxWithId(mProviderContext, box2.mId); 737 box3 = Mailbox.restoreMailboxWithId(mProviderContext, box3.mId); 738 739 // Confirm flags and parent key(s) as expected 740 assertEquals(CHILD_FLAGS, box1.mFlags); 741 assertEquals(-1, box1.mParentKey); 742 743 assertEquals(CHILD_FLAGS, box2.mFlags); 744 assertEquals(-1, box2.mParentKey); 745 746 assertEquals(CHILD_FLAGS, box3.mFlags); 747 assertEquals(-1, box3.mParentKey); 748 749 box4 = Mailbox.restoreMailboxWithId(mProviderContext, box4.mId); 750 box5 = Mailbox.restoreMailboxWithId(mProviderContext, box5.mId); 751 box6 = Mailbox.restoreMailboxWithId(mProviderContext, box6.mId); 752 753 assertEquals(PARENT_FLAGS, box4.mFlags); 754 assertEquals(-1, box4.mParentKey); 755 756 assertEquals(PARENT_FLAGS, box5.mFlags); 757 assertEquals(box4.mId, box5.mParentKey); 758 759 assertEquals(CHILD_FLAGS, box6.mFlags); 760 assertEquals(box5.mId, box6.mParentKey); 761 } 762 } 763