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