ControllerProviderOpsTests.java revision 77aabd951992057a543f1699150971bf1f2d4394
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.email;
18
19import com.android.email.provider.EmailContent;
20import com.android.email.provider.EmailProvider;
21import com.android.email.provider.ProviderTestUtils;
22import com.android.email.provider.EmailContent.Account;
23import com.android.email.provider.EmailContent.Body;
24import com.android.email.provider.EmailContent.HostAuth;
25import com.android.email.provider.EmailContent.Mailbox;
26import com.android.email.provider.EmailContent.Message;
27
28import android.content.Context;
29import android.net.Uri;
30import android.test.ProviderTestCase2;
31
32import java.util.Locale;
33import java.util.concurrent.ExecutionException;
34
35/**
36 * Tests of the Controller class that depend on the underlying provider.
37 *
38 * NOTE:  It would probably make sense to rewrite this using a MockProvider, instead of the
39 * ProviderTestCase (which is a real provider running on a temp database).  This would be more of
40 * a true "unit test".
41 *
42 * You can run this entire test case with:
43 *   runtest -c com.android.email.ControllerProviderOpsTests email
44 */
45public class ControllerProviderOpsTests extends ProviderTestCase2<EmailProvider> {
46
47    private Context mProviderContext;
48    private Context mContext;
49    private TestController mTestController;
50
51
52    public ControllerProviderOpsTests() {
53        super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY);
54    }
55
56    @Override
57    public void setUp() throws Exception {
58        super.setUp();
59        mProviderContext = getMockContext();
60        mContext = getContext();
61        mTestController = new TestController(mProviderContext, mContext);
62    }
63
64    @Override
65    public void tearDown() throws Exception {
66        super.tearDown();
67        mTestController.cleanupForTest();
68    }
69
70    /**
71     * Lightweight subclass of the Controller class allows injection of mock context
72     */
73    public static class TestController extends Controller {
74
75        protected TestController(Context providerContext, Context systemContext) {
76            super(systemContext);
77            setProviderContext(providerContext);
78        }
79    }
80
81    /**
82     * These are strings that should not change per locale.
83     */
84    public void testGetMailboxServerName() {
85        assertEquals("", mTestController.getMailboxServerName(-1));
86
87        assertEquals("Inbox", mTestController.getMailboxServerName(Mailbox.TYPE_INBOX));
88        assertEquals("Outbox", mTestController.getMailboxServerName(Mailbox.TYPE_OUTBOX));
89        assertEquals("Trash", mTestController.getMailboxServerName(Mailbox.TYPE_TRASH));
90        assertEquals("Sent", mTestController.getMailboxServerName(Mailbox.TYPE_SENT));
91        assertEquals("Junk", mTestController.getMailboxServerName(Mailbox.TYPE_JUNK));
92
93        // Now try again with translation
94        Locale savedLocale = Locale.getDefault();
95        Locale.setDefault(Locale.FRANCE);
96        assertEquals("Inbox", mTestController.getMailboxServerName(Mailbox.TYPE_INBOX));
97        assertEquals("Outbox", mTestController.getMailboxServerName(Mailbox.TYPE_OUTBOX));
98        assertEquals("Trash", mTestController.getMailboxServerName(Mailbox.TYPE_TRASH));
99        assertEquals("Sent", mTestController.getMailboxServerName(Mailbox.TYPE_SENT));
100        assertEquals("Junk", mTestController.getMailboxServerName(Mailbox.TYPE_JUNK));
101        Locale.setDefault(savedLocale);
102    }
103
104    /**
105     * Test of Controller.createMailbox().
106     * Sunny day test only - creates a mailbox that does not exist.
107     * Does not test duplication, bad accountID, or any other bad input.
108     */
109    public void testCreateMailbox() {
110        Account account = ProviderTestUtils.setupAccount("mailboxid", true, mProviderContext);
111        long accountId = account.mId;
112
113        long oldBoxId = Mailbox.findMailboxOfType(mProviderContext, accountId, Mailbox.TYPE_DRAFTS);
114        assertEquals(Mailbox.NO_MAILBOX, oldBoxId);
115
116        mTestController.createMailbox(accountId, Mailbox.TYPE_DRAFTS);
117        long boxId = Mailbox.findMailboxOfType(mProviderContext, accountId, Mailbox.TYPE_DRAFTS);
118
119        // check that the drafts mailbox exists
120        assertTrue("mailbox exists", boxId != Mailbox.NO_MAILBOX);
121    }
122
123    /**
124     * Test of Controller.findOrCreateMailboxOfType().
125     * Checks:
126     * - finds correctly the ID of existing mailbox
127     * - creates non-existing mailbox
128     * - creates only once a new mailbox
129     * - when accountId or mailboxType are -1, returns NO_MAILBOX
130     */
131    public void testFindOrCreateMailboxOfType() {
132        Account account = ProviderTestUtils.setupAccount("mailboxid", true, mProviderContext);
133        long accountId = account.mId;
134        Mailbox box = ProviderTestUtils.setupMailbox("box", accountId, false, mProviderContext);
135        final int boxType = Mailbox.TYPE_TRASH;
136        box.mType = boxType;
137        box.save(mProviderContext);
138        long boxId = box.mId;
139
140        long testBoxId = mTestController.findOrCreateMailboxOfType(accountId, boxType);
141
142        // check it found the right mailbox id
143        assertEquals(boxId, testBoxId);
144
145        long boxId2 = mTestController.findOrCreateMailboxOfType(accountId, Mailbox.TYPE_DRAFTS);
146        assertTrue("mailbox created", boxId2 != Mailbox.NO_MAILBOX);
147        assertTrue("with different id", testBoxId != boxId2);
148
149        // check it doesn't create twice when existing
150        long boxId3 = mTestController.findOrCreateMailboxOfType(accountId, Mailbox.TYPE_DRAFTS);
151        assertEquals("don't create if exists", boxId3, boxId2);
152
153        // check invalid aruments
154        assertEquals(Mailbox.NO_MAILBOX,
155                mTestController.findOrCreateMailboxOfType(-1, Mailbox.TYPE_DRAFTS));
156        assertEquals(Mailbox.NO_MAILBOX, mTestController.findOrCreateMailboxOfType(accountId, -1));
157    }
158
159    /**
160     * Test the "move message" function.
161     *
162     * @throws ExecutionException
163     * @throws InterruptedException
164     */
165    public void testMoveMessage() throws InterruptedException, ExecutionException {
166        Account account1 = ProviderTestUtils.setupAccount("message-move", true, mProviderContext);
167        long account1Id = account1.mId;
168        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
169        long box1Id = box1.mId;
170        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mProviderContext);
171        long box2Id = box2.mId;
172        Mailbox boxDest = ProviderTestUtils.setupMailbox("d", account1Id, true, mProviderContext);
173        long boxDestId = boxDest.mId;
174
175        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
176                true, mProviderContext);
177        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box2Id, false,
178                true, mProviderContext);
179        long message1Id = message1.mId;
180        long message2Id = message2.mId;
181
182        // Because moveMessage runs asynchronously, call get() to force it to complete
183        mTestController.moveMessage(new long[] {message1Id, message2Id}, boxDestId).get();
184
185        // now read back a fresh copy and confirm it's in the trash
186        assertEquals(boxDestId, EmailContent.Message.restoreMessageWithId(mProviderContext,
187                message1Id).mMailboxKey);
188        assertEquals(boxDestId, EmailContent.Message.restoreMessageWithId(mProviderContext,
189                message2Id).mMailboxKey);
190    }
191
192    /**
193     * Test the "delete message" function.  Sunny day:
194     *    - message/mailbox/account all exist
195     *    - trash mailbox exists
196     * @throws ExecutionException
197     * @throws InterruptedException
198     */
199    public void testDeleteMessage() throws InterruptedException, ExecutionException {
200        Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mProviderContext);
201        long account1Id = account1.mId;
202        Mailbox box = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
203        long boxId = box.mId;
204
205        Mailbox trashBox = ProviderTestUtils.setupMailbox("box2", account1Id, false,
206                mProviderContext);
207        trashBox.mType = EmailContent.Mailbox.TYPE_TRASH;
208        trashBox.save(mProviderContext);
209        long trashBoxId = trashBox.mId;
210
211        Mailbox draftBox = ProviderTestUtils.setupMailbox("box3", account1Id, false,
212                mProviderContext);
213        draftBox.mType = EmailContent.Mailbox.TYPE_DRAFTS;
214        draftBox.save(mProviderContext);
215        long draftBoxId = draftBox.mId;
216
217        {
218            // Case 1: Message in a regular mailbox, account known.
219            Message message = ProviderTestUtils.setupMessage("message1", account1Id, boxId, false,
220                    true, mProviderContext);
221            long messageId = message.mId;
222
223            mTestController.deleteMessageSync(messageId, account1Id);
224
225            // now read back a fresh copy and confirm it's in the trash
226            Message restored = EmailContent.Message.restoreMessageWithId(mProviderContext,
227                    messageId);
228            assertEquals(trashBoxId, restored.mMailboxKey);
229        }
230
231        {
232            // Case 2: Message in a regular mailbox, account *un*known.
233            Message message = ProviderTestUtils.setupMessage("message2", account1Id, boxId, false,
234                    true, mProviderContext);
235            long messageId = message.mId;
236
237            mTestController.deleteMessageSync(messageId, -1);
238
239            // now read back a fresh copy and confirm it's in the trash
240            Message restored = EmailContent.Message.restoreMessageWithId(mProviderContext,
241                    messageId);
242            assertEquals(trashBoxId, restored.mMailboxKey);
243        }
244
245        {
246            // Case 3: Already in trash
247            Message message = ProviderTestUtils.setupMessage("message3", account1Id, trashBoxId,
248                    false, true, mProviderContext);
249            long messageId = message.mId;
250
251            mTestController.deleteMessageSync(messageId, account1Id);
252
253            // Message should be deleted.
254            assertNull(EmailContent.Message.restoreMessageWithId(mProviderContext, messageId));
255        }
256
257        {
258            // Case 4: Draft
259            Message message = ProviderTestUtils.setupMessage("message3", account1Id, draftBoxId,
260                    false, true, mProviderContext);
261            long messageId = message.mId;
262
263            mTestController.deleteMessageSync(messageId, account1Id);
264
265            // Message should be deleted.
266            assertNull(EmailContent.Message.restoreMessageWithId(mProviderContext, messageId));
267        }
268    }
269
270    /**
271     * Test deleting message when there is no trash mailbox
272     * @throws ExecutionException
273     * @throws InterruptedException
274     */
275    public void testDeleteMessageNoTrash() throws InterruptedException, ExecutionException {
276        Account account1 =
277                ProviderTestUtils.setupAccount("message-delete-notrash", true, mProviderContext);
278        long account1Id = account1.mId;
279        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
280        long box1Id = box1.mId;
281
282        Message message1 =
283                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
284                        mProviderContext);
285        long message1Id = message1.mId;
286
287        mTestController.deleteMessageSync(message1Id, account1Id);
288
289        // now read back a fresh copy and confirm it's in the trash
290        Message message1get =
291                EmailContent.Message.restoreMessageWithId(mProviderContext, message1Id);
292
293        // check the new mailbox and see if it looks right
294        assertFalse(-1 == message1get.mMailboxKey);
295        assertFalse(box1Id == message1get.mMailboxKey);
296        Mailbox mailbox2get = EmailContent.Mailbox.restoreMailboxWithId(mProviderContext,
297                message1get.mMailboxKey);
298        assertEquals(EmailContent.Mailbox.TYPE_TRASH, mailbox2get.mType);
299    }
300
301    /**
302     * Test read/unread flag
303     */
304    public void testReadUnread() {
305        Account account1 = ProviderTestUtils.setupAccount("read-unread", false, mProviderContext);
306        account1.mHostAuthRecv
307                = ProviderTestUtils.setupHostAuth("read-unread", 0, false, mProviderContext);
308        account1.save(mProviderContext);
309        long account1Id = account1.mId;
310        long box1Id = 2;
311
312        Message message1 =
313                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
314                        mProviderContext);
315        long message1Id = message1.mId;
316
317        // test setting to "read"
318        mTestController.setMessageRead(message1Id, true);
319        Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
320        assertTrue(message1get.mFlagRead);
321
322        // test setting to "unread"
323        mTestController.setMessageRead(message1Id, false);
324        message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
325        assertFalse(message1get.mFlagRead);
326    }
327
328    /**
329     * Test favorites flag
330     */
331    public void testFavorites() {
332        Account account1 = ProviderTestUtils.setupAccount("favorites", false, mProviderContext);
333        account1.mHostAuthRecv
334                = ProviderTestUtils.setupHostAuth("favorites", 0, false, mProviderContext);
335        account1.save(mProviderContext);
336        long account1Id = account1.mId;
337        long box1Id = 2;
338
339        Message message1 =
340                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
341                        mProviderContext);
342        long message1Id = message1.mId;
343
344        // test setting to "favorite"
345        mTestController.setMessageFavorite(message1Id, true);
346        Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
347        assertTrue(message1get.mFlagFavorite);
348
349        // test setting to "not favorite"
350        mTestController.setMessageFavorite(message1Id, false);
351        message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
352        assertFalse(message1get.mFlagFavorite);
353    }
354
355    public void testGetAndDeleteAttachmentMailbox() {
356        Mailbox box = mTestController.getAttachmentMailbox();
357        assertNotNull(box);
358        Mailbox anotherBox = mTestController.getAttachmentMailbox();
359        assertNotNull(anotherBox);
360        // We should always get back the same Mailbox row
361        assertEquals(box.mId, anotherBox.mId);
362        // Add two messages to this mailbox
363        ProviderTestUtils.setupMessage("message1", 0, box.mId, false, true,
364                mProviderContext);
365        ProviderTestUtils.setupMessage("message2", 0, box.mId, false, true,
366                mProviderContext);
367        // Make sure we can find them where they are expected
368        assertEquals(2, EmailContent.count(mProviderContext, Message.CONTENT_URI,
369                Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)}));
370        // Delete them
371        mTestController.deleteAttachmentMessages();
372        // Make sure they're gone
373        assertEquals(0, EmailContent.count(mProviderContext, Message.CONTENT_URI,
374                Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)}));
375    }
376
377    public void testLoadMessageFromUri() throws Exception {
378        // Create a simple message
379        Message msg = new Message();
380        String text = "This is some text";
381        msg.mText = text;
382        String sender = "sender@host.com";
383        msg.mFrom = sender;
384        // Save this away
385        msg.save(mProviderContext);
386
387        Uri fileUri = ProviderTestUtils.createTempEmlFile(mProviderContext, msg,
388                mContext.getFilesDir());
389
390        // Load the message via Controller and a Uri
391        Message loadedMsg = mTestController.loadMessageFromUri(fileUri);
392
393        // Check server id, mailbox key, account key, and from
394        assertNotNull(loadedMsg);
395        assertTrue(loadedMsg.mServerId.startsWith(Controller.ATTACHMENT_MESSAGE_UID_PREFIX));
396        Mailbox box = mTestController.getAttachmentMailbox();
397        assertNotNull(box);
398        assertEquals(box.mId, loadedMsg.mMailboxKey);
399        assertEquals(0, loadedMsg.mAccountKey);
400        assertEquals(loadedMsg.mFrom, sender);
401        // Check body text
402        String loadedMsgText = Body.restoreBodyTextWithMessageId(mProviderContext, loadedMsg.mId);
403        assertEquals(text, loadedMsgText);
404    }
405
406    /**
407     * Create a simple HostAuth with protocol
408     */
409    private HostAuth setupSimpleHostAuth(String protocol) {
410        HostAuth hostAuth = new HostAuth();
411        hostAuth.mProtocol = protocol;
412        return hostAuth;
413    }
414
415    public void testIsMessagingController() {
416        Account account1 = ProviderTestUtils.setupAccount("account1", false,
417                mProviderContext);
418        account1.mHostAuthRecv = setupSimpleHostAuth("eas");
419        account1.save(mProviderContext);
420        assertFalse(mTestController.isMessagingController(account1));
421        Account account2 = ProviderTestUtils.setupAccount("account2", false,
422                mProviderContext);
423        account2.mHostAuthRecv = setupSimpleHostAuth("imap");
424        account2.save(mProviderContext);
425        assertTrue(mTestController.isMessagingController(account2));
426        Account account3 = ProviderTestUtils.setupAccount("account3", false,
427                mProviderContext);
428        account3.mHostAuthRecv = setupSimpleHostAuth("pop3");
429        account3.save(mProviderContext);
430        assertTrue(mTestController.isMessagingController(account3));
431        Account account4 = ProviderTestUtils.setupAccount("account4", false,
432                mProviderContext);
433        account4.mHostAuthRecv = setupSimpleHostAuth("smtp");
434        account4.save(mProviderContext);
435        assertFalse(mTestController.isMessagingController(account4));
436        // There should be values for all of these accounts in the legacy map
437        assertNotNull(mTestController.mLegacyControllerMap.get(account1.mId));
438        assertNotNull(mTestController.mLegacyControllerMap.get(account2.mId));
439        assertNotNull(mTestController.mLegacyControllerMap.get(account3.mId));
440        assertNotNull(mTestController.mLegacyControllerMap.get(account4.mId));
441        // The map should have the expected values
442        assertFalse(mTestController.mLegacyControllerMap.get(account1.mId));
443        assertTrue(mTestController.mLegacyControllerMap.get(account2.mId));
444        assertTrue(mTestController.mLegacyControllerMap.get(account3.mId));
445        assertFalse(mTestController.mLegacyControllerMap.get(account4.mId));
446        // This second pass should pull values from the cache
447        assertFalse(mTestController.isMessagingController(account1));
448        assertTrue(mTestController.isMessagingController(account2));
449        assertTrue(mTestController.isMessagingController(account3));
450        assertFalse(mTestController.isMessagingController(account4));
451    }
452
453    /**
454     * TODO: releasing associated data (e.g. attachments, embedded images)
455     */
456}
457