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
17package com.android.emailcommon.provider;
18
19import com.android.email.provider.ContentCache;
20import com.android.email.provider.EmailProvider;
21import com.android.email.provider.ProviderTestUtils;
22import com.android.emailcommon.provider.EmailContent.MailboxColumns;
23import com.android.emailcommon.provider.EmailContent.Message;
24import com.android.emailcommon.provider.EmailContent.MessageColumns;
25import com.android.emailcommon.utility.Utility;
26
27import android.content.ContentUris;
28import android.content.ContentValues;
29import android.content.Context;
30import android.net.Uri;
31import android.os.Parcel;
32import android.test.MoreAsserts;
33import android.test.ProviderTestCase2;
34import android.test.suitebuilder.annotation.SmallTest;
35
36import java.util.Arrays;
37
38/**
39 * Unit tests for the Mailbox inner class.
40 * These tests must be locally complete - no server(s) required.
41 */
42@SmallTest
43public class MailboxTests extends ProviderTestCase2<EmailProvider> {
44    private static final String TEST_DISPLAY_NAME = "display-name";
45    private static final String TEST_PARENT_SERVER_ID = "parent-server-id";
46    private static final String TEST_SERVER_ID = "server-id";
47    private static final String TEST_SYNC_KEY = "sync-key";
48    private static final String TEST_SYNC_STATUS = "sync-status";
49
50    private Context mMockContext;
51    private EmailProvider mProvider;
52
53    public MailboxTests() {
54        super(EmailProvider.class, EmailContent.AUTHORITY);
55    }
56
57    @Override
58    public void setUp() throws Exception {
59        super.setUp();
60        mMockContext = getMockContext();
61        mProvider = getProvider();
62        // Invalidate all caches, since we reset the database for each test
63        ContentCache.invalidateAllCaches();
64    }
65
66    //////////////////////////////////////////////////////////
67    ////// Utility methods
68    //////////////////////////////////////////////////////////
69
70    /** Returns the number of messages in a mailbox. */
71    private int getMessageCount(long mailboxId) {
72        return Utility.getFirstRowInt(mMockContext,
73                ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
74                new String[] {MailboxColumns.MESSAGE_COUNT}, null, null, null, 0);
75    }
76
77    /** Creates a new message. */
78    private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read,
79            int flagLoaded) {
80        Message message = ProviderTestUtils.setupMessage(
81                "1", b.mAccountKey, b.mId, true, false, c, starred, read);
82        message.mFlagLoaded = flagLoaded;
83        message.save(c);
84        return message;
85    }
86
87    //////////////////////////////////////////////////////////
88    ////// The tests
89    //////////////////////////////////////////////////////////
90
91    /**
92     * Test simple mailbox save/retrieve
93     */
94    public void testSave() {
95        final Context c = mMockContext;
96
97        Account account1 = ProviderTestUtils.setupAccount("mailbox-save", true, c);
98        long account1Id = account1.mId;
99        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, c);
100        long box1Id = box1.mId;
101
102        Mailbox box2 = Mailbox.restoreMailboxWithId(c, box1Id);
103
104        ProviderTestUtils.assertMailboxEqual("testMailboxSave", box1, box2);
105    }
106
107    /**
108     * Test delete mailbox
109     */
110    public void testDelete() {
111        final Context c = mMockContext;
112
113        Account account1 = ProviderTestUtils.setupAccount("mailbox-delete", true, c);
114        long account1Id = account1.mId;
115        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, c);
116        long box1Id = box1.mId;
117        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, c);
118        long box2Id = box2.mId;
119
120        String selection = EmailContent.MailboxColumns.ACCOUNT_KEY + "=?";
121        String[] selArgs = new String[] { String.valueOf(account1Id) };
122
123        // make sure there are two mailboxes
124        int numBoxes = EmailContent.count(c, Mailbox.CONTENT_URI, selection, selArgs);
125        assertEquals(2, numBoxes);
126
127        // now delete one of them
128        Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id);
129        c.getContentResolver().delete(uri, null, null);
130
131        // make sure there's only one mailbox now
132        numBoxes = EmailContent.count(c, Mailbox.CONTENT_URI, selection, selArgs);
133        assertEquals(1, numBoxes);
134
135        // now delete the other one
136        uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id);
137        c.getContentResolver().delete(uri, null, null);
138
139        // make sure there are no mailboxes now
140        numBoxes = EmailContent.count(c, Mailbox.CONTENT_URI, selection, selArgs);
141        assertEquals(0, numBoxes);
142    }
143
144    public void testGetMailboxType() {
145        final Context c = mMockContext;
146
147        Account a = ProviderTestUtils.setupAccount("acct1", true, c);
148        Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX);
149        Mailbox bm = ProviderTestUtils.setupMailbox("b2", a.mId, true, c, Mailbox.TYPE_MAIL);
150
151        assertEquals(Mailbox.TYPE_INBOX, Mailbox.getMailboxType(c, bi.mId));
152        assertEquals(Mailbox.TYPE_MAIL, Mailbox.getMailboxType(c, bm.mId));
153        assertEquals(-1, Mailbox.getMailboxType(c, 999999)); // mailbox not found
154    }
155
156    public void testGetDisplayName() {
157        final Context c = mMockContext;
158
159        Account a = ProviderTestUtils.setupAccount("acct1", true, c);
160        Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX);
161        Mailbox bm = ProviderTestUtils.setupMailbox("b2", a.mId, true, c, Mailbox.TYPE_MAIL);
162
163        assertEquals("b1", Mailbox.getDisplayName(c, bi.mId));
164        assertEquals("b2", Mailbox.getDisplayName(c, bm.mId));
165        assertEquals(null, Mailbox.getDisplayName(c, 999999)); // mailbox not found
166    }
167
168    public void testIsRefreshable() {
169        final Context c = mMockContext;
170
171        Account a = ProviderTestUtils.setupAccount("acct1", true, c);
172        Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX);
173        Mailbox bm = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_MAIL);
174        Mailbox bd = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_DRAFTS);
175        Mailbox bo = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_OUTBOX);
176
177        assertTrue(Mailbox.isRefreshable(c, bi.mId));
178        assertTrue(Mailbox.isRefreshable(c, bm.mId));
179        assertFalse(Mailbox.isRefreshable(c, bd.mId));
180        assertFalse(Mailbox.isRefreshable(c, bo.mId));
181
182        // No such mailbox
183        assertFalse(Mailbox.isRefreshable(c, 9999999));
184
185        // Magic mailboxes can't be refreshed.
186        assertFalse(Mailbox.isRefreshable(c, Mailbox.QUERY_ALL_DRAFTS));
187        assertFalse(Mailbox.isRefreshable(c, Mailbox.QUERY_ALL_INBOXES));
188    }
189
190    public void testCanMoveFrom() {
191        final Context c = mMockContext;
192
193        Account a = ProviderTestUtils.setupAccount("acct1", true, c);
194        Mailbox bi = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_INBOX);
195        Mailbox bm = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_MAIL);
196        Mailbox bd = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_DRAFTS);
197        Mailbox bo = ProviderTestUtils.setupMailbox("b1", a.mId, true, c, Mailbox.TYPE_OUTBOX);
198
199        assertTrue(bi.canHaveMessagesMoved());
200        assertTrue(bm.canHaveMessagesMoved());
201        assertFalse(bd.canHaveMessagesMoved());
202        assertFalse(bo.canHaveMessagesMoved());
203    }
204
205    public void testGetMailboxForMessageId() {
206        final Context c = mMockContext;
207        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", 1, true, c, Mailbox.TYPE_MAIL);
208        Mailbox b2 = ProviderTestUtils.setupMailbox("box2", 1, true, c, Mailbox.TYPE_MAIL);
209        Message m1 = ProviderTestUtils.setupMessage("1", b1.mAccountKey, b1.mId,
210                true, true, c, false, false);
211        Message m2 = ProviderTestUtils.setupMessage("1", b2.mAccountKey, b2.mId,
212                true, true, c, false, false);
213        ProviderTestUtils.assertMailboxEqual("x", b1, Mailbox.getMailboxForMessageId(c, m1.mId));
214        ProviderTestUtils.assertMailboxEqual("x", b2, Mailbox.getMailboxForMessageId(c, m2.mId));
215    }
216
217    public void testRestoreMailboxWithId() {
218        final Context c = mMockContext;
219        Mailbox testMailbox;
220
221        testMailbox = ProviderTestUtils.setupMailbox("box1", 1, true, c, Mailbox.TYPE_MAIL);
222        ProviderTestUtils.assertMailboxEqual(
223                "x", testMailbox, Mailbox.restoreMailboxWithId(c, testMailbox.mId));
224        testMailbox = ProviderTestUtils.setupMailbox("box2", 1, true, c, Mailbox.TYPE_MAIL);
225        ProviderTestUtils.assertMailboxEqual(
226                "x", testMailbox, Mailbox.restoreMailboxWithId(c, testMailbox.mId));
227        // Unknown IDs
228        assertNull(Mailbox.restoreMailboxWithId(c, 8));
229        assertNull(Mailbox.restoreMailboxWithId(c, -1));
230        assertNull(Mailbox.restoreMailboxWithId(c, Long.MAX_VALUE));
231    }
232
233    public void testRestoreMailboxForPath() {
234        final Context c = mMockContext;
235        Mailbox testMailbox;
236        testMailbox = ProviderTestUtils.setupMailbox("a/b/c/box", 1, true, c, Mailbox.TYPE_MAIL);
237        ProviderTestUtils.assertMailboxEqual(
238                "x", testMailbox, Mailbox.restoreMailboxForPath(c, 1, "a/b/c/box"));
239        // Same name, different account; no match
240        assertNull(Mailbox.restoreMailboxForPath(c, 2, "a/b/c/box"));
241        // Substring; no match
242        assertNull(Mailbox.restoreMailboxForPath(c, 1, "a/b/c"));
243        // Wild cards not supported; no match
244        assertNull(Mailbox.restoreMailboxForPath(c, 1, "a/b/c/%"));
245    }
246
247    public void testFindMailboxOfType() {
248        final Context context = mMockContext;
249
250        // Create two accounts and a variety of mailbox types
251        Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context);
252        Mailbox acct1Inbox =
253            ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX);
254        Mailbox acct1Calendar =
255            ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR);
256        Mailbox acct1Contacts =
257            ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS);
258        Account acct2 = ProviderTestUtils.setupAccount("acct1", true, context);
259        Mailbox acct2Inbox =
260            ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX);
261        Mailbox acct2Calendar =
262            ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR);
263        Mailbox acct2Contacts =
264            ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS);
265
266        // Check that we can find them by type
267        assertEquals(acct1Inbox.mId,
268                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX));
269        assertEquals(acct2Inbox.mId,
270                Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX));
271        assertEquals(acct1Calendar.mId,
272                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR));
273        assertEquals(acct2Calendar.mId,
274                Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR));
275        assertEquals(acct1Contacts.mId,
276                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS));
277        assertEquals(acct2Contacts.mId,
278                Mailbox.findMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS));
279
280        // Check that nonexistent mailboxes are not returned
281        assertEquals(Mailbox.NO_MAILBOX,
282                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_DRAFTS));
283        assertEquals(Mailbox.NO_MAILBOX,
284                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_OUTBOX));
285
286        // delete account 1 and confirm no mailboxes are returned
287        context.getContentResolver().delete(
288                ContentUris.withAppendedId(Account.CONTENT_URI, acct1.mId), null, null);
289        assertEquals(Mailbox.NO_MAILBOX,
290                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX));
291        assertEquals(Mailbox.NO_MAILBOX,
292                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR));
293        assertEquals(Mailbox.NO_MAILBOX,
294                Mailbox.findMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS));
295    }
296
297    public void testRestoreMailboxOfType() {
298        final Context context = getMockContext();
299
300        // Create two accounts and a variety of mailbox types
301        Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context);
302        Mailbox acct1Inbox =
303            ProviderTestUtils.setupMailbox("Inbox1", acct1.mId, true, context, Mailbox.TYPE_INBOX);
304        Mailbox acct1Calendar =
305            ProviderTestUtils.setupMailbox("Cal1", acct1.mId, true, context, Mailbox.TYPE_CALENDAR);
306        Mailbox acct1Contacts =
307            ProviderTestUtils.setupMailbox("Con1", acct1.mId, true, context, Mailbox.TYPE_CONTACTS);
308        Account acct2 =ProviderTestUtils.setupAccount("acct1", true, context);
309        Mailbox acct2Inbox =
310            ProviderTestUtils.setupMailbox("Inbox2", acct2.mId, true, context, Mailbox.TYPE_INBOX);
311        Mailbox acct2Calendar =
312            ProviderTestUtils.setupMailbox("Cal2", acct2.mId, true, context, Mailbox.TYPE_CALENDAR);
313        Mailbox acct2Contacts =
314            ProviderTestUtils.setupMailbox("Con2", acct2.mId, true, context, Mailbox.TYPE_CONTACTS);
315
316        // Check that we can find them by type
317        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Inbox,
318                Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_INBOX));
319        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Inbox,
320                Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_INBOX));
321        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Calendar,
322                Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CALENDAR));
323        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Calendar,
324                Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CALENDAR));
325        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct1Contacts,
326                Mailbox.restoreMailboxOfType(context, acct1.mId, Mailbox.TYPE_CONTACTS));
327        ProviderTestUtils.assertMailboxEqual("testRestoreMailboxOfType", acct2Contacts,
328                Mailbox.restoreMailboxOfType(context, acct2.mId, Mailbox.TYPE_CONTACTS));
329    }
330
331    /**
332     * Test for the message count triggers (insert/delete/move mailbox), and also
333     * {@link EmailProvider#recalculateMessageCount}.
334     *
335     * It also covers:
336     * - {@link Mailbox#getMessageCountByMailboxType(Context, int)}
337     * - {@link Mailbox#getUnreadCountByAccountAndMailboxType(Context, long, int)}
338     * - {@link Mailbox#getUnreadCountByMailboxType(Context, int)}
339     * - {@link Message#getFavoriteMessageCount(Context)}
340     * - {@link Message#getFavoriteMessageCount(Context, long)}
341     */
342    public void testMessageCount() {
343        final Context c = mMockContext;
344
345        // Create 2 accounts
346        Account a1 = ProviderTestUtils.setupAccount("holdflag-1", true, c);
347        Account a2 = ProviderTestUtils.setupAccount("holdflag-2", true, c);
348
349        // Create 2 mailboxes for each account
350        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_INBOX);
351        Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a1.mId, true, c, Mailbox.TYPE_OUTBOX);
352        Mailbox b3 = ProviderTestUtils.setupMailbox("box3", a2.mId, true, c, Mailbox.TYPE_INBOX);
353        Mailbox b4 = ProviderTestUtils.setupMailbox("box4", a2.mId, true, c, Mailbox.TYPE_OUTBOX);
354        Mailbox bt = ProviderTestUtils.setupMailbox("boxT", a2.mId, true, c, Mailbox.TYPE_TRASH);
355
356        // 0. Check the initial values, just in case.
357
358        assertEquals(0, getMessageCount(b1.mId));
359        assertEquals(0, getMessageCount(b2.mId));
360        assertEquals(0, getMessageCount(b3.mId));
361        assertEquals(0, getMessageCount(b4.mId));
362        assertEquals(0, getMessageCount(bt.mId));
363
364        assertEquals(0, Message.getFavoriteMessageCount(c));
365        assertEquals(0, Message.getFavoriteMessageCount(c, a1.mId));
366        assertEquals(0, Message.getFavoriteMessageCount(c, a2.mId));
367        assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_INBOX));
368        assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_OUTBOX));
369        assertEquals(0, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_INBOX));
370        assertEquals(0, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_OUTBOX));
371        assertEquals(0, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_TRASH));
372
373        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
374                a1.mId, Mailbox.TYPE_INBOX));
375        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
376                a1.mId, Mailbox.TYPE_OUTBOX));
377        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
378                a1.mId, Mailbox.TYPE_TRASH));
379        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
380                a2.mId, Mailbox.TYPE_INBOX));
381        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
382                a2.mId, Mailbox.TYPE_OUTBOX));
383        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
384                a2.mId, Mailbox.TYPE_TRASH));
385
386        // 1. Test for insert triggers.
387
388        // Create some messages
389        // b1 (account 1, inbox): 1 message, including 1 starred
390        Message m11 = createMessage(c, b1, true, false, Message.FLAG_LOADED_COMPLETE);
391
392        // b2 (account 1, outbox): 2 message, including 1 starred
393        Message m21 = createMessage(c, b2, false, false, Message.FLAG_LOADED_COMPLETE);
394        Message m22 = createMessage(c, b2, true, true, Message.FLAG_LOADED_COMPLETE);
395
396        // b3 (account 2, inbox): 3 message, including 1 starred
397        Message m31 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
398        Message m32 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
399        Message m33 = createMessage(c, b3, true, true, Message.FLAG_LOADED_COMPLETE);
400
401        // b4 (account 2, outbox) has no messages.
402
403        // bt (account 2, trash) has 3 messages, including 2 starred
404        Message mt1 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
405        Message mt2 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
406        Message mt3 = createMessage(c, bt, false, false, Message.FLAG_LOADED_COMPLETE);
407
408        // Check message counts
409        assertEquals(1, getMessageCount(b1.mId));
410        assertEquals(2, getMessageCount(b2.mId));
411        assertEquals(3, getMessageCount(b3.mId));
412        assertEquals(0, getMessageCount(b4.mId));
413        assertEquals(3, getMessageCount(bt.mId));
414
415        // Check the simple counting methods.
416        assertEquals(3, Message.getFavoriteMessageCount(c)); // excludes starred in trash
417        assertEquals(2, Message.getFavoriteMessageCount(c, a1.mId));
418        assertEquals(1, Message.getFavoriteMessageCount(c, a2.mId)); // excludes starred in trash
419        assertEquals(3, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_INBOX));
420        assertEquals(1, Mailbox.getUnreadCountByMailboxType(c, Mailbox.TYPE_OUTBOX));
421        assertEquals(4, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_INBOX));
422        assertEquals(2, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_OUTBOX));
423        assertEquals(3, Mailbox.getMessageCountByMailboxType(c, Mailbox.TYPE_TRASH));
424
425        assertEquals(1, Mailbox.getUnreadCountByAccountAndMailboxType(c,
426                a1.mId, Mailbox.TYPE_INBOX));
427        assertEquals(1, Mailbox.getUnreadCountByAccountAndMailboxType(c,
428                a1.mId, Mailbox.TYPE_OUTBOX));
429        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
430                a1.mId, Mailbox.TYPE_TRASH));
431        assertEquals(2, Mailbox.getUnreadCountByAccountAndMailboxType(c,
432                a2.mId, Mailbox.TYPE_INBOX));
433        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
434                a2.mId, Mailbox.TYPE_OUTBOX));
435        assertEquals(3, Mailbox.getUnreadCountByAccountAndMailboxType(c,
436                a2.mId, Mailbox.TYPE_TRASH));
437
438        // 2. Check the "move mailbox" trigger.
439
440        // Move m32 (in mailbox 3) to mailbox 4.
441        ContentValues values = new ContentValues();
442        values.put(MessageColumns.MAILBOX_KEY, b4.mId);
443
444        getProvider().update(Message.CONTENT_URI, values, EmailContent.ID_SELECTION,
445                new String[] {"" + m32.mId});
446
447        // Check message counts
448        assertEquals(1, getMessageCount(b1.mId));
449        assertEquals(2, getMessageCount(b2.mId));
450        assertEquals(2, getMessageCount(b3.mId));
451        assertEquals(1, getMessageCount(b4.mId));
452
453        // 3. Check the delete trigger.
454
455        // Delete m11 (in mailbox 1)
456        getProvider().delete(Message.CONTENT_URI, EmailContent.ID_SELECTION,
457                new String[] {"" + m11.mId});
458        // Delete m21 (in mailbox 2)
459        getProvider().delete(Message.CONTENT_URI, EmailContent.ID_SELECTION,
460                new String[] {"" + m21.mId});
461
462        // Check message counts
463        assertEquals(0, getMessageCount(b1.mId));
464        assertEquals(1, getMessageCount(b2.mId));
465        assertEquals(2, getMessageCount(b3.mId));
466        assertEquals(1, getMessageCount(b4.mId));
467
468        // No such mailbox type.
469        assertEquals(0, Mailbox.getMessageCountByMailboxType(c, 99999));
470        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c, a1.mId, 99999));
471        assertEquals(0, Mailbox.getUnreadCountByMailboxType(c, 99999));
472
473        // No such account
474        assertEquals(0, Mailbox.getUnreadCountByAccountAndMailboxType(c,
475                99999, Mailbox.TYPE_INBOX));
476    }
477
478    /**
479     * Check if update on MAILBOX_ID_ADD_TO_FIELD updates the cache properly.
480     */
481    public void testUpdateCacheMailboxIdAddToField() {
482        final Context c = mMockContext;
483
484        Account a1 = ProviderTestUtils.setupAccount("a1", true, c);
485        Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_INBOX);
486
487        int start = Mailbox.restoreMailboxWithId(c, b1.mId).mSyncInterval;
488
489        // +1 to SYNC_INTERVAL
490        ContentValues cv = new ContentValues();
491        cv.put(EmailContent.FIELD_COLUMN_NAME, MailboxColumns.SYNC_INTERVAL);
492        cv.put(EmailContent.ADD_COLUMN_NAME, 1);
493        mProvider.update(ContentUris.withAppendedId(Mailbox.ADD_TO_FIELD_URI, a1.mId), cv,
494                null, null);
495
496        // Check
497        assertEquals(start + 1, Mailbox.restoreMailboxWithId(c, b1.mId).mSyncInterval);
498    }
499
500    private Mailbox buildTestMailbox(String serverId) {
501        return buildTestMailbox(serverId, null);
502    }
503
504    private Mailbox buildTestMailbox(String serverId, String name) {
505        name = (name == null) ? TEST_DISPLAY_NAME : name;
506
507        Mailbox testMailbox = new Mailbox();
508        testMailbox.mServerId = serverId;
509        testMailbox.mDisplayName = name;
510        testMailbox.mParentServerId = TEST_PARENT_SERVER_ID;
511        testMailbox.mSyncKey = TEST_SYNC_KEY;
512        testMailbox.mSyncStatus = TEST_SYNC_STATUS;
513        testMailbox.mAccountKey = 1L;
514        testMailbox.mDelimiter = '/';
515        testMailbox.mFlags = 2;
516        testMailbox.mFlagVisible = true;
517        testMailbox.mParentKey = 3L;
518        testMailbox.mSyncInterval = 4;
519        testMailbox.mSyncLookback = 5;
520        testMailbox.mSyncTime = 6L;
521        testMailbox.mType = 7;
522        testMailbox.mVisibleLimit = 8;
523        testMailbox.mLastSeenMessageKey = 9L;
524        testMailbox.mLastTouchedTime = 10L;
525
526        return testMailbox;
527    }
528
529    public void testGetHashes() {
530        final Context c = mMockContext;
531        Mailbox testMailbox = buildTestMailbox(TEST_SERVER_ID);
532        testMailbox.save(c);
533
534        Object[] testHash;
535        testHash = new Object[] {
536                testMailbox.mId, TEST_DISPLAY_NAME, TEST_SERVER_ID,
537                TEST_PARENT_SERVER_ID, 1L /*mAccountKey*/, 7 /*mType */,
538                (int)'/' /*mDelimiter */, TEST_SYNC_KEY, 5 /*mSyncLookback*/,
539                4 /*mSyncInterval*/,  6L /*mSyncTime*/, true /*mFlagVisible*/, 2 /*mFlags*/,
540                8 /*mVisibleLimit*/, TEST_SYNC_STATUS, 3L /*mParentKey*/, 9L /*mLastSeen*/,
541                10L /*mLastTouchedTime*/,
542        };
543        MoreAsserts.assertEquals(testHash, testMailbox.getHashes());
544
545        // Verify null checks happen correctly
546        testMailbox.mDisplayName = null;
547        testMailbox.mParentServerId = null;
548        testMailbox.mServerId = null;
549        testMailbox.mSyncKey = null;
550        testMailbox.mSyncStatus = null;
551        testMailbox.mFlagVisible = false;
552
553        testHash = new Object[] {
554                testMailbox.mId, null /*mDisplayname*/, null /*mServerId*/,
555                null /*mParentServerId*/, 1L /*mAccountKey*/, 7 /*mType */,
556                (int)'/' /*mDelimiter */, null /*mSyncKey*/, 5 /*mSyncLookback*/,
557                4 /*mSyncInterval*/,  6L /*mSyncTime*/, false /*mFlagVisible*/, 2 /*mFlags*/,
558                8 /*mVisibleLimit*/, null /*mSyncStatus*/, 3L /*mParentKey*/, 9L /*mLastSeen*/,
559                10L /*mLastTouchedTime*/,
560        };
561        MoreAsserts.assertEquals(testHash, testMailbox.getHashes());
562    }
563
564    public void testParcelling() {
565        Mailbox original = buildTestMailbox("serverId", "display name for mailbox");
566
567        Parcel p = Parcel.obtain();
568        original.writeToParcel(p, 0 /* flags */);
569
570        // Reset.
571        p.setDataPosition(0);
572
573        Mailbox unparcelled = Mailbox.CREATOR.createFromParcel(p);
574        MoreAsserts.assertEquals(original.getHashes(), unparcelled.getHashes());
575
576        Mailbox phony = buildTestMailbox("different ID", "display name for mailbox");
577        assertFalse(Arrays.equals(phony.getHashes(), unparcelled.getHashes()));
578
579        p.recycle();
580    }
581
582    public void testParcellingWithPartialMailbox() {
583        Mailbox unpopulated = new Mailbox();
584        unpopulated.mDisplayName = "the only thing filled in for some reason";
585
586        Parcel p = Parcel.obtain();
587        unpopulated.writeToParcel(p, 0 /* flags */);
588
589        // Reset.
590        p.setDataPosition(0);
591
592        Mailbox unparcelled = Mailbox.CREATOR.createFromParcel(p);
593        MoreAsserts.assertEquals(unpopulated.getHashes(), unparcelled.getHashes());
594
595        p.recycle();
596    }
597}
598
599