Home | History | Annotate | Download | only in provider
      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