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