Home | History | Annotate | Download | only in adapter
      1 /*
      2  * Copyright (C) 2010 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.adapter;
     18 
     19 import com.android.email.provider.EmailContent;
     20 import com.android.email.provider.ProviderTestUtils;
     21 import com.android.email.provider.EmailContent.Account;
     22 import com.android.email.provider.EmailContent.Body;
     23 import com.android.email.provider.EmailContent.Mailbox;
     24 import com.android.email.provider.EmailContent.Message;
     25 import com.android.email.provider.EmailContent.SyncColumns;
     26 import com.android.exchange.EasSyncService;
     27 import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser;
     28 import com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser.ServerChange;
     29 
     30 import android.content.ContentUris;
     31 import android.content.ContentValues;
     32 
     33 import java.io.ByteArrayInputStream;
     34 import java.io.IOException;
     35 import java.util.ArrayList;
     36 import java.util.GregorianCalendar;
     37 import java.util.TimeZone;
     38 
     39 public class EmailSyncAdapterTests extends SyncAdapterTestCase<EmailSyncAdapter> {
     40 
     41     public EmailSyncAdapterTests() {
     42         super();
     43     }
     44 
     45     /**
     46      * Check functionality for getting mime type from a file name (using its extension)
     47      * The default for all unknown files is application/octet-stream
     48      */
     49     public void testGetMimeTypeFromFileName() throws IOException {
     50         EasSyncService service = getTestService();
     51         EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
     52         EasEmailSyncParser p = adapter.new EasEmailSyncParser(getTestInputStream(), adapter);
     53         // Test a few known types
     54         String mimeType = p.getMimeTypeFromFileName("foo.jpg");
     55         assertEquals("image/jpeg", mimeType);
     56         // Make sure this is case insensitive
     57         mimeType = p.getMimeTypeFromFileName("foo.JPG");
     58         assertEquals("image/jpeg", mimeType);
     59         mimeType = p.getMimeTypeFromFileName("this_is_a_weird_filename.gif");
     60         assertEquals("image/gif", mimeType);
     61         // Test an illegal file name ending with the extension prefix
     62         mimeType = p.getMimeTypeFromFileName("foo.");
     63         assertEquals("application/octet-stream", mimeType);
     64         // Test a really awful name
     65         mimeType = p.getMimeTypeFromFileName(".....");
     66         assertEquals("application/octet-stream", mimeType);
     67         // Test a bare file name (no extension)
     68         mimeType = p.getMimeTypeFromFileName("foo");
     69         assertEquals("application/octet-stream", mimeType);
     70         // And no name at all (null isn't a valid input)
     71         mimeType = p.getMimeTypeFromFileName("");
     72         assertEquals("application/octet-stream", mimeType);
     73     }
     74 
     75     public void testFormatDateTime() throws IOException {
     76         EmailSyncAdapter adapter = getTestSyncAdapter(EmailSyncAdapter.class);
     77         GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
     78         // Calendar is odd, months are zero based, so the first 11 below is December...
     79         calendar.set(2008, 11, 11, 18, 19, 20);
     80         String date = adapter.formatDateTime(calendar);
     81         assertEquals("2008-12-11T18:19:20.000Z", date);
     82         calendar.clear();
     83         calendar.set(2012, 0, 2, 23, 0, 1);
     84         date = adapter.formatDateTime(calendar);
     85         assertEquals("2012-01-02T23:00:01.000Z", date);
     86     }
     87 
     88     public void testSendDeletedItems() throws IOException {
     89         EasSyncService service = getTestService();
     90         EmailSyncAdapter adapter = new EmailSyncAdapter(service.mMailbox, service);
     91         Serializer s = new Serializer();
     92         ArrayList<Long> ids = new ArrayList<Long>();
     93         ArrayList<Long> deletedIds = new ArrayList<Long>();
     94 
     95         adapter.mContext = mMockContext;
     96 
     97         // Create account and two mailboxes
     98         Account acct = ProviderTestUtils.setupAccount("account", true, mMockContext);
     99         adapter.mAccount = acct;
    100         Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, mMockContext);
    101         adapter.mMailbox = box1;
    102 
    103         // Create 3 messages
    104         Message msg1 = ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId,
    105                 true, true, mMockContext);
    106         ids.add(msg1.mId);
    107         Message msg2 = ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId,
    108                 true, true, mMockContext);
    109         ids.add(msg2.mId);
    110         Message msg3 = ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId,
    111                 true, true, mMockContext);
    112         ids.add(msg3.mId);
    113         assertEquals(3, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
    114 
    115         // Delete them
    116         for (long id: ids) {
    117             mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
    118                     null, null);
    119         }
    120 
    121         // Confirm that the messages are in the proper table
    122         assertEquals(0, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
    123         assertEquals(3, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
    124 
    125         // Call code to send deletions; the id's of the ones actually deleted will be in the
    126         // deletedIds list
    127         adapter.sendDeletedItems(s, deletedIds, true);
    128         assertEquals(3, deletedIds.size());
    129 
    130         // Clear this out for the next test
    131         deletedIds.clear();
    132 
    133         // Create a new message
    134         Message msg4 = ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId,
    135                 true, true, mMockContext);
    136         assertEquals(1, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
    137         // Find the body for this message
    138         Body body = Body.restoreBodyWithMessageId(mMockContext, msg4.mId);
    139         // Set its source message to msg2's id
    140         ContentValues values = new ContentValues();
    141         values.put(Body.SOURCE_MESSAGE_KEY, msg2.mId);
    142         body.update(mMockContext, values);
    143 
    144         // Now send deletions again; this time only two should get deleted; msg2 should NOT be
    145         // deleted as it's referenced by msg4
    146         adapter.sendDeletedItems(s, deletedIds, true);
    147         assertEquals(2, deletedIds.size());
    148         assertFalse(deletedIds.contains(msg2.mId));
    149     }
    150 
    151     void setupSyncParserAndAdapter(Account account, Mailbox mailbox) throws IOException {
    152         EasSyncService service = getTestService(account, mailbox);
    153         mSyncAdapter = new EmailSyncAdapter(mailbox, service);
    154         mSyncParser = mSyncAdapter.new EasEmailSyncParser(getTestInputStream(), mSyncAdapter);
    155     }
    156 
    157     ArrayList<Long> setupAccountMailboxAndMessages(int numMessages) {
    158         ArrayList<Long> ids = new ArrayList<Long>();
    159 
    160         // Create account and two mailboxes
    161         mAccount = ProviderTestUtils.setupAccount("account", true, mMockContext);
    162         mMailbox = ProviderTestUtils.setupMailbox("box1", mAccount.mId, true, mMockContext);
    163 
    164         for (int i = 0; i < numMessages; i++) {
    165             Message msg = ProviderTestUtils.setupMessage("message" + i, mAccount.mId, mMailbox.mId,
    166                     true, true, mMockContext);
    167             ids.add(msg.mId);
    168         }
    169 
    170         assertEquals(numMessages, EmailContent.count(mMockContext, Message.CONTENT_URI,
    171                 null, null));
    172         return ids;
    173     }
    174 
    175     public void testDeleteParser() throws IOException {
    176         // Setup some messages
    177         ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
    178         ContentValues cv = new ContentValues();
    179         cv.put(SyncColumns.SERVER_ID, "1:22");
    180         long deleteMessageId = messageIds.get(1);
    181         mMockResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, deleteMessageId), cv,
    182                 null, null);
    183 
    184         // Setup our adapter and parser
    185         setupSyncParserAndAdapter(mAccount, mMailbox);
    186 
    187         // Set up an input stream with a delete command
    188         Serializer s = new Serializer(false);
    189         s.start(Tags.SYNC_DELETE).data(Tags.SYNC_SERVER_ID, "1:22").end().done();
    190         byte[] bytes = s.toByteArray();
    191         mSyncParser.resetInput(new ByteArrayInputStream(bytes));
    192         mSyncParser.nextTag(0);
    193 
    194         // Run the delete parser
    195         ArrayList<Long> deleteList = new ArrayList<Long>();
    196         mSyncParser.deleteParser(deleteList, Tags.SYNC_DELETE);
    197         // It should have found the message
    198         assertEquals(1, deleteList.size());
    199         long id = deleteList.get(0);
    200         // And the id's should match
    201         assertEquals(deleteMessageId, id);
    202     }
    203 
    204     public void testChangeParser() throws IOException {
    205         // Setup some messages
    206         ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
    207         ContentValues cv = new ContentValues();
    208         cv.put(SyncColumns.SERVER_ID, "1:22");
    209         long changeMessageId = messageIds.get(1);
    210         mMockResolver.update(ContentUris.withAppendedId(Message.CONTENT_URI, changeMessageId), cv,
    211                 null, null);
    212 
    213         // Setup our adapter and parser
    214         setupSyncParserAndAdapter(mAccount, mMailbox);
    215 
    216         // Set up an input stream with a change command (marking 1:22 unread)
    217         // Note that the test message creation code sets read to "true"
    218         Serializer s = new Serializer(false);
    219         s.start(Tags.SYNC_CHANGE).data(Tags.SYNC_SERVER_ID, "1:22");
    220         s.start(Tags.SYNC_APPLICATION_DATA).data(Tags.EMAIL_READ, "0").end();
    221         s.end().done();
    222         byte[] bytes = s.toByteArray();
    223         mSyncParser.resetInput(new ByteArrayInputStream(bytes));
    224         mSyncParser.nextTag(0);
    225 
    226         // Run the delete parser
    227         ArrayList<ServerChange> changeList = new ArrayList<ServerChange>();
    228         mSyncParser.changeParser(changeList);
    229         // It should have found the message
    230         assertEquals(1, changeList.size());
    231         // And the id's should match
    232         ServerChange change = changeList.get(0);
    233         assertEquals(changeMessageId, change.id);
    234         assertNotNull(change.read);
    235         assertFalse(change.read);
    236     }
    237 
    238     public void testCleanup() throws IOException {
    239         // Setup some messages
    240         ArrayList<Long> messageIds = setupAccountMailboxAndMessages(3);
    241         // Setup our adapter and parser
    242         setupSyncParserAndAdapter(mAccount, mMailbox);
    243 
    244         // Delete two of the messages, change one
    245         long id = messageIds.get(0);
    246         mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, id),
    247                 null, null);
    248         mSyncAdapter.mDeletedIdList.add(id);
    249         id = messageIds.get(1);
    250         mMockResolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
    251                 id), null, null);
    252         mSyncAdapter.mDeletedIdList.add(id);
    253         id = messageIds.get(2);
    254         ContentValues cv = new ContentValues();
    255         cv.put(Message.FLAG_READ, 0);
    256         mMockResolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,
    257                 id), cv, null, null);
    258         mSyncAdapter.mUpdatedIdList.add(id);
    259 
    260         // The changed message should still exist
    261         assertEquals(1, EmailContent.count(mMockContext, Message.CONTENT_URI, null, null));
    262 
    263         // As well, the two deletions and one update
    264         assertEquals(2, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
    265         assertEquals(1, EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, null, null));
    266 
    267         // Cleanup (i.e. after sync); should remove items from delete/update tables
    268         mSyncAdapter.cleanup();
    269 
    270         // The three should be gone
    271         assertEquals(0, EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, null, null));
    272         assertEquals(0, EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, null, null));
    273     }
    274 }
    275