ControllerProviderOpsTests.java revision b53b1501055cbf5040bfd7b88a9cda084574c398
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     * @throws ExecutionException
162     * @throws InterruptedException
163     */
164    public void testMoveMessage() throws InterruptedException, ExecutionException {
165        Account account1 = ProviderTestUtils.setupAccount("message-move", true, mProviderContext);
166        long account1Id = account1.mId;
167        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
168        long box1Id = box1.mId;
169        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mProviderContext);
170        long box2Id = box2.mId;
171
172        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
173                true, mProviderContext);
174        long message1Id = message1.mId;
175
176        // Because moveMessage runs asynchronously, call get() to force it to complete
177        mTestController.moveMessage(message1Id, box2Id).get();
178
179        // now read back a fresh copy and confirm it's in the trash
180        Message message1get = EmailContent.Message.restoreMessageWithId(mProviderContext,
181                message1Id);
182        assertEquals(box2Id, message1get.mMailboxKey);
183    }
184
185    /**
186     * Test the "delete message" function.  Sunny day:
187     *    - message/mailbox/account all exist
188     *    - trash mailbox exists
189     * @throws ExecutionException
190     * @throws InterruptedException
191     */
192    public void testDeleteMessage() throws InterruptedException, ExecutionException {
193        Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mProviderContext);
194        long account1Id = account1.mId;
195        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
196        long box1Id = box1.mId;
197        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, false, mProviderContext);
198        box2.mType = EmailContent.Mailbox.TYPE_TRASH;
199        box2.save(mProviderContext);
200        long box2Id = box2.mId;
201
202        Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
203                true, mProviderContext);
204        long message1Id = message1.mId;
205
206        // Because deleteMessage now runs asynchronously, call get() to force it to complete
207        mTestController.deleteMessage(message1Id, account1Id).get();
208
209        // now read back a fresh copy and confirm it's in the trash
210        Message message1get = EmailContent.Message.restoreMessageWithId(mProviderContext,
211                message1Id);
212        assertEquals(box2Id, message1get.mMailboxKey);
213
214        // Now repeat test with accountId "unknown"
215        Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
216                true, mProviderContext);
217        long message2Id = message2.mId;
218
219        mTestController.deleteMessage(message2Id, -1).get();
220
221        // now read back a fresh copy and confirm it's in the trash
222        Message message2get = EmailContent.Message.restoreMessageWithId(mProviderContext,
223                message2Id);
224        assertEquals(box2Id, message2get.mMailboxKey);
225    }
226
227    /**
228     * Test deleting message when there is no trash mailbox
229     * @throws ExecutionException
230     * @throws InterruptedException
231     */
232    public void testDeleteMessageNoTrash() throws InterruptedException, ExecutionException {
233        Account account1 =
234                ProviderTestUtils.setupAccount("message-delete-notrash", true, mProviderContext);
235        long account1Id = account1.mId;
236        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mProviderContext);
237        long box1Id = box1.mId;
238
239        Message message1 =
240                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
241                        mProviderContext);
242        long message1Id = message1.mId;
243
244        // Because deleteMessage now runs asynchronously, call get() to force it to complete
245        mTestController.deleteMessage(message1Id, account1Id).get();
246
247        // now read back a fresh copy and confirm it's in the trash
248        Message message1get =
249                EmailContent.Message.restoreMessageWithId(mProviderContext, message1Id);
250
251        // check the new mailbox and see if it looks right
252        assertFalse(-1 == message1get.mMailboxKey);
253        assertFalse(box1Id == message1get.mMailboxKey);
254        Mailbox mailbox2get = EmailContent.Mailbox.restoreMailboxWithId(mProviderContext,
255                message1get.mMailboxKey);
256        assertEquals(EmailContent.Mailbox.TYPE_TRASH, mailbox2get.mType);
257    }
258
259    /**
260     * Test read/unread flag
261     */
262    public void testReadUnread() {
263        Account account1 = ProviderTestUtils.setupAccount("read-unread", false, mProviderContext);
264        account1.mHostAuthRecv
265                = ProviderTestUtils.setupHostAuth("read-unread", 0, false, mProviderContext);
266        account1.save(mProviderContext);
267        long account1Id = account1.mId;
268        long box1Id = 2;
269
270        Message message1 =
271                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
272                        mProviderContext);
273        long message1Id = message1.mId;
274
275        // test setting to "read"
276        mTestController.setMessageRead(message1Id, true);
277        Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
278        assertTrue(message1get.mFlagRead);
279
280        // test setting to "unread"
281        mTestController.setMessageRead(message1Id, false);
282        message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
283        assertFalse(message1get.mFlagRead);
284    }
285
286    /**
287     * Test favorites flag
288     */
289    public void testFavorites() {
290        Account account1 = ProviderTestUtils.setupAccount("favorites", false, mProviderContext);
291        account1.mHostAuthRecv
292                = ProviderTestUtils.setupHostAuth("favorites", 0, false, mProviderContext);
293        account1.save(mProviderContext);
294        long account1Id = account1.mId;
295        long box1Id = 2;
296
297        Message message1 =
298                ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true,
299                        mProviderContext);
300        long message1Id = message1.mId;
301
302        // test setting to "favorite"
303        mTestController.setMessageFavorite(message1Id, true);
304        Message message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
305        assertTrue(message1get.mFlagFavorite);
306
307        // test setting to "not favorite"
308        mTestController.setMessageFavorite(message1Id, false);
309        message1get = Message.restoreMessageWithId(mProviderContext, message1Id);
310        assertFalse(message1get.mFlagFavorite);
311    }
312
313    public void testGetAndDeleteAttachmentMailbox() {
314        Mailbox box = mTestController.getAttachmentMailbox();
315        assertNotNull(box);
316        Mailbox anotherBox = mTestController.getAttachmentMailbox();
317        assertNotNull(anotherBox);
318        // We should always get back the same Mailbox row
319        assertEquals(box.mId, anotherBox.mId);
320        // Add two messages to this mailbox
321        ProviderTestUtils.setupMessage("message1", 0, box.mId, false, true,
322                mProviderContext);
323        ProviderTestUtils.setupMessage("message2", 0, box.mId, false, true,
324                mProviderContext);
325        // Make sure we can find them where they are expected
326        assertEquals(2, EmailContent.count(mProviderContext, Message.CONTENT_URI,
327                Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)}));
328        // Delete them
329        mTestController.deleteAttachmentMessages();
330        // Make sure they're gone
331        assertEquals(0, EmailContent.count(mProviderContext, Message.CONTENT_URI,
332                Message.MAILBOX_KEY + "=?", new String[] {Long.toString(box.mId)}));
333    }
334
335    public void testLoadMessageFromUri() throws Exception {
336        // Create a simple message
337        Message msg = new Message();
338        String text = "This is some text";
339        msg.mText = text;
340        String sender = "sender@host.com";
341        msg.mFrom = sender;
342        // Save this away
343        msg.save(mProviderContext);
344
345        Uri fileUri = ProviderTestUtils.createTempEmlFile(mProviderContext, msg,
346                mContext.getFilesDir());
347
348        // Load the message via Controller and a Uri
349        Message loadedMsg = mTestController.loadMessageFromUri(fileUri);
350
351        // Check server id, mailbox key, account key, and from
352        assertNotNull(loadedMsg);
353        assertTrue(loadedMsg.mServerId.startsWith(Controller.ATTACHMENT_MESSAGE_UID_PREFIX));
354        Mailbox box = mTestController.getAttachmentMailbox();
355        assertNotNull(box);
356        assertEquals(box.mId, loadedMsg.mMailboxKey);
357        assertEquals(0, loadedMsg.mAccountKey);
358        assertEquals(loadedMsg.mFrom, sender);
359        // Check body text
360        String loadedMsgText = Body.restoreBodyTextWithMessageId(mProviderContext, loadedMsg.mId);
361        assertEquals(text, loadedMsgText);
362    }
363
364    /**
365     * Create a simple HostAuth with protocol
366     */
367    private HostAuth setupSimpleHostAuth(String protocol) {
368        HostAuth hostAuth = new HostAuth();
369        hostAuth.mProtocol = protocol;
370        return hostAuth;
371    }
372
373    public void testIsMessagingController() {
374        Account account1 = ProviderTestUtils.setupAccount("account1", false,
375                mProviderContext);
376        account1.mHostAuthRecv = setupSimpleHostAuth("eas");
377        account1.save(mProviderContext);
378        assertFalse(mTestController.isMessagingController(account1));
379        Account account2 = ProviderTestUtils.setupAccount("account2", false,
380                mProviderContext);
381        account2.mHostAuthRecv = setupSimpleHostAuth("imap");
382        account2.save(mProviderContext);
383        assertTrue(mTestController.isMessagingController(account2));
384        Account account3 = ProviderTestUtils.setupAccount("account3", false,
385                mProviderContext);
386        account3.mHostAuthRecv = setupSimpleHostAuth("pop3");
387        account3.save(mProviderContext);
388        assertTrue(mTestController.isMessagingController(account3));
389        Account account4 = ProviderTestUtils.setupAccount("account4", false,
390                mProviderContext);
391        account4.mHostAuthRecv = setupSimpleHostAuth("smtp");
392        account4.save(mProviderContext);
393        assertFalse(mTestController.isMessagingController(account4));
394        // There should be values for all of these accounts in the legacy map
395        assertNotNull(mTestController.mLegacyControllerMap.get(account1.mId));
396        assertNotNull(mTestController.mLegacyControllerMap.get(account2.mId));
397        assertNotNull(mTestController.mLegacyControllerMap.get(account3.mId));
398        assertNotNull(mTestController.mLegacyControllerMap.get(account4.mId));
399        // The map should have the expected values
400        assertFalse(mTestController.mLegacyControllerMap.get(account1.mId));
401        assertTrue(mTestController.mLegacyControllerMap.get(account2.mId));
402        assertTrue(mTestController.mLegacyControllerMap.get(account3.mId));
403        assertFalse(mTestController.mLegacyControllerMap.get(account4.mId));
404        // This second pass should pull values from the cache
405        assertFalse(mTestController.isMessagingController(account1));
406        assertTrue(mTestController.isMessagingController(account2));
407        assertTrue(mTestController.isMessagingController(account3));
408        assertFalse(mTestController.isMessagingController(account4));
409    }
410
411    /**
412     * TODO: releasing associated data (e.g. attachments, embedded images)
413     */
414}
415