Home | History | Annotate | Download | only in activity
      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.email.activity;
     18 
     19 import com.android.email.activity.ContactStatusLoader.Result;
     20 import com.android.mail.utils.MatrixCursorWithCachedColumns;
     21 
     22 import android.content.Context;
     23 import android.content.pm.ProviderInfo;
     24 import android.database.Cursor;
     25 import android.database.MatrixCursor;
     26 import android.graphics.Bitmap;
     27 import android.net.Uri;
     28 import android.provider.ContactsContract;
     29 import android.provider.ContactsContract.StatusUpdates;
     30 import android.test.ProviderTestCase2;
     31 import android.test.mock.MockContentProvider;
     32 
     33 import java.io.ByteArrayOutputStream;
     34 import java.util.ArrayList;
     35 import java.util.Queue;
     36 import java.util.concurrent.LinkedBlockingQueue;
     37 
     38 import junit.framework.Assert;
     39 
     40 /**
     41  * Test for {@link ContactStatusLoader}
     42  *
     43  * Unfortunately this doesn't check {@link ContactStatusLoader.Result#mLookupUri}, because we don't
     44  * (shouldn't) know how {@link android.provider.ContactsContract.Data#getContactLookupUri} is
     45  * implemented.
     46  */
     47 public class ContactStatusLoaderTest
     48         extends ProviderTestCase2<ContactStatusLoaderTest.MockContactProvider> {
     49     private static final String EMAIL = "a (at) b.c";
     50 
     51     private MockContactProvider mProvider;
     52 
     53     public ContactStatusLoaderTest() {
     54         super(MockContactProvider.class, ContactsContract.AUTHORITY);
     55     }
     56 
     57     @Override
     58     protected void setUp() throws Exception {
     59         super.setUp();
     60         mProvider = getProvider();
     61     }
     62 
     63     // Contact doesn't exist
     64     public void testContactNotFound() {
     65         // Insert empty cursor
     66         mProvider.mCursors.offer(new MatrixCursorWithCachedColumns(
     67                 ContactStatusLoader.PROJECTION_PHOTO_ID_PRESENCE));
     68 
     69         // Load!
     70         ContactStatusLoader l = new ContactStatusLoader(getMockContext(), EMAIL);
     71         Result r = l.loadInBackground();
     72 
     73         // Check input to the provider
     74         assertEquals(1, mProvider.mUris.size());
     75         assertEquals("content://com.android.contacts/data/emails/lookup/a%40b.c",
     76                 mProvider.mUris.get(0));
     77 
     78         // Check result
     79         assertNull(r.mPhoto);
     80         assertEquals(ContactStatusLoader.PRESENCE_UNKNOWN_RESOURCE_ID, r.mPresenceResId);
     81     }
     82 
     83     // Contact doesn't exist -- provider returns null for the first query
     84     public void testNull() {
     85         // No cursor prepared. (Mock provider will return null)
     86 
     87         // Load!
     88         ContactStatusLoader l = new ContactStatusLoader(getMockContext(), EMAIL);
     89         Result r = l.loadInBackground();
     90 
     91         // Check result
     92         assertNull(r.mPhoto);
     93         assertEquals(ContactStatusLoader.PRESENCE_UNKNOWN_RESOURCE_ID, r.mPresenceResId);
     94     }
     95 
     96     // Contact exists, but no photo
     97     public void testNoPhoto() {
     98         // Result for the first query (the one for photo-id)
     99         MatrixCursor cursor1 =
    100                 new MatrixCursorWithCachedColumns(ContactStatusLoader.PROJECTION_PHOTO_ID_PRESENCE);
    101         cursor1.addRow(new Object[]{12345, StatusUpdates.AWAY});
    102         mProvider.mCursors.offer(cursor1);
    103 
    104         // Empty cursor for the second query
    105         mProvider.mCursors.offer(
    106                 new MatrixCursorWithCachedColumns(ContactStatusLoader.PHOTO_PROJECTION));
    107 
    108         // Load!
    109         ContactStatusLoader l = new ContactStatusLoader(getMockContext(), EMAIL);
    110         Result r = l.loadInBackground();
    111 
    112         // Check input to the provider
    113         // We should have had at least two queries from loadInBackground.
    114         // There can be extra queries from getContactLookupUri(), but this test shouldn't know
    115         // the details, so use ">= 2".
    116         assertTrue(mProvider.mUris.size() >= 2);
    117         assertEquals("content://com.android.contacts/data/emails/lookup/a%40b.c",
    118                 mProvider.mUris.get(0));
    119         assertEquals("content://com.android.contacts/data/12345",
    120                 mProvider.mUris.get(1));
    121 
    122         // Check result
    123         assertNull(r.mPhoto); // no photo
    124         assertEquals(android.R.drawable.presence_away, r.mPresenceResId);
    125     }
    126 
    127     // Contact exists, but no photo (provider returns null for the second query)
    128     public void testNull2() {
    129         // Result for the first query (the one for photo-id)
    130         MatrixCursor cursor1 =
    131                 new MatrixCursorWithCachedColumns(ContactStatusLoader.PROJECTION_PHOTO_ID_PRESENCE);
    132         cursor1.addRow(new Object[]{12345, StatusUpdates.AWAY});
    133         mProvider.mCursors.offer(cursor1);
    134 
    135         // No cursor for the second query
    136 
    137         // Load!
    138         ContactStatusLoader l = new ContactStatusLoader(getMockContext(), EMAIL);
    139         Result r = l.loadInBackground();
    140 
    141         // Check result
    142         assertNull(r.mPhoto); // no photo
    143         assertEquals(android.R.drawable.presence_away, r.mPresenceResId);
    144     }
    145 
    146     // Contact exists, with a photo
    147     public void testWithPhoto() {
    148         // Result for the first query (the one for photo-id)
    149         MatrixCursor cursor1 =
    150                 new MatrixCursorWithCachedColumns(ContactStatusLoader.PROJECTION_PHOTO_ID_PRESENCE);
    151         cursor1.addRow(new Object[]{12345, StatusUpdates.AWAY});
    152         mProvider.mCursors.offer(cursor1);
    153 
    154         // Prepare for the second query.
    155         MatrixCursor cursor2 = new PhotoCursor(createJpegData(10, 20));
    156         mProvider.mCursors.offer(cursor2);
    157 
    158         // Load!
    159         ContactStatusLoader l = new ContactStatusLoader(getMockContext(), EMAIL);
    160         Result r = l.loadInBackground();
    161 
    162         // Check result
    163         assertNotNull(r.mPhoto);
    164         assertEquals(10, r.mPhoto.getWidth());
    165         assertEquals(android.R.drawable.presence_away, r.mPresenceResId);
    166     }
    167 
    168     private static byte[] createJpegData(int width, int height) {
    169         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    170         ByteArrayOutputStream out = new ByteArrayOutputStream();
    171         bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
    172         return out.toByteArray();
    173     }
    174 
    175     // MatrixCursor doesn't support getBlob, so use this...
    176     private static class PhotoCursor extends MatrixCursorWithCachedColumns {
    177         private final byte[] mBlob;
    178 
    179         public PhotoCursor(byte[] blob) {
    180             super(ContactStatusLoader.PHOTO_PROJECTION);
    181             mBlob = blob;
    182             addRow(new Object[] {null}); // Add dummy row
    183         }
    184 
    185         @Override
    186         public byte[] getBlob(int column) {
    187             Assert.assertEquals(0, column);
    188             return mBlob;
    189         }
    190     }
    191 
    192     public static class MockContactProvider extends MockContentProvider {
    193         public ArrayList<String> mUris = new ArrayList<String>();
    194 
    195         public final Queue<Cursor> mCursors = new LinkedBlockingQueue<Cursor>();
    196 
    197         @Override
    198         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
    199                 String sortOrder) {
    200             mUris.add(uri.toString());
    201             return mCursors.poll();
    202         }
    203 
    204         @Override
    205         public void attachInfo(Context context, ProviderInfo info) {
    206         }
    207     }
    208 }
    209