1 /* 2 * Copyright (C) 2011 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.dialer.calllog; 18 19 import android.content.Context; 20 import android.database.MatrixCursor; 21 import android.support.v7.widget.RecyclerView.ViewHolder; 22 import android.test.AndroidTestCase; 23 import android.test.suitebuilder.annotation.SmallTest; 24 import android.view.View; 25 import android.widget.LinearLayout; 26 27 import com.android.dialer.contactinfo.ContactInfoCache; 28 import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener; 29 import com.google.common.collect.Lists; 30 31 import java.util.List; 32 33 /** 34 * Unit tests for {@link CallLogAdapter}. 35 */ 36 @SmallTest 37 public class CallLogAdapterTest extends AndroidTestCase { 38 private static final String TEST_NUMBER = "12345678"; 39 private static final String TEST_NAME = "name"; 40 private static final String TEST_NUMBER_LABEL = "label"; 41 private static final int TEST_NUMBER_TYPE = 1; 42 private static final String TEST_COUNTRY_ISO = "US"; 43 44 /** The object under test. */ 45 private TestCallLogAdapter mAdapter; 46 47 private MatrixCursor mCursor; 48 private View mView; 49 private ViewHolder mViewHolder; 50 51 @Override setUp()52 protected void setUp() throws Exception { 53 super.setUp(); 54 // Use a call fetcher that does not do anything. 55 CallLogAdapter.CallFetcher fakeCallFetcher = new CallLogAdapter.CallFetcher() { 56 @Override 57 public void fetchCalls() {} 58 }; 59 60 ContactInfoHelper fakeContactInfoHelper = 61 new ContactInfoHelper(getContext(), TEST_COUNTRY_ISO) { 62 @Override 63 public ContactInfo lookupNumber(String number, String countryIso) { 64 ContactInfo info = new ContactInfo(); 65 info.number = number; 66 info.formattedNumber = number; 67 return info; 68 } 69 }; 70 71 mAdapter = new TestCallLogAdapter(getContext(), fakeCallFetcher, fakeContactInfoHelper); 72 // The cursor used in the tests to store the entries to display. 73 mCursor = new MatrixCursor(CallLogQuery._PROJECTION); 74 mCursor.moveToFirst(); 75 // The views into which to store the data. 76 mView = new LinearLayout(getContext()); 77 mViewHolder = CallLogListItemViewHolder.createForTest(getContext()); 78 mView.setTag(mViewHolder); 79 } 80 81 @Override tearDown()82 protected void tearDown() throws Exception { 83 mAdapter = null; 84 mCursor = null; 85 mView = null; 86 super.tearDown(); 87 } 88 testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest()89 public void testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest() { 90 mCursor.addRow(createCallLogEntry()); 91 92 // Bind the views of a single row. 93 mAdapter.changeCursor(mCursor); 94 mAdapter.onBindViewHolder(mViewHolder, 0); 95 96 // There is one request for contact details. 97 assertEquals(1, mAdapter.getContactInfoCache().requests.size()); 98 99 TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0); 100 // It is for the number we need to show. 101 assertEquals(TEST_NUMBER, request.number); 102 // It has the right country. 103 assertEquals(TEST_COUNTRY_ISO, request.countryIso); 104 // Since there is nothing in the cache, it is an immediate request. 105 assertTrue("should be immediate", request.immediate); 106 } 107 testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest()108 public void testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest() { 109 mCursor.addRow(createCallLogEntryWithCachedValues()); 110 111 // Bind the views of a single row. 112 mAdapter.changeCursor(mCursor); 113 mAdapter.onBindViewHolder(mViewHolder, 0); 114 115 // There is one request for contact details. 116 assertEquals(1, mAdapter.getContactInfoCache().requests.size()); 117 118 TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0); 119 // The values passed to the request, match the ones in the call log cache. 120 assertEquals(TEST_NAME, request.callLogInfo.name); 121 assertEquals(1, request.callLogInfo.type); 122 assertEquals(TEST_NUMBER_LABEL, request.callLogInfo.label); 123 } 124 125 testBindView_NoCallLogButMemoryCache_EnqueueRequest()126 public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() { 127 mCursor.addRow(createCallLogEntry()); 128 mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo()); 129 130 // Bind the views of a single row. 131 mAdapter.changeCursor(mCursor); 132 mAdapter.onBindViewHolder(mViewHolder, 0); 133 134 // There is one request for contact details. 135 assertEquals(1, mAdapter.getContactInfoCache().requests.size()); 136 137 TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0); 138 // Since there is something in the cache, it is not an immediate request. 139 assertFalse("should not be immediate", request.immediate); 140 } 141 testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest()142 public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() { 143 mCursor.addRow(createCallLogEntryWithCachedValues()); 144 mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo()); 145 146 // Bind the views of a single row. 147 mAdapter.changeCursor(mCursor); 148 mAdapter.onBindViewHolder(mViewHolder, 0); 149 150 // Cache and call log are up-to-date: no need to request update. 151 assertEquals(0, mAdapter.getContactInfoCache().requests.size()); 152 } 153 testBindView_MismatchBetwenCallLogAndMemoryCache_EnqueueRequest()154 public void testBindView_MismatchBetwenCallLogAndMemoryCache_EnqueueRequest() { 155 mCursor.addRow(createCallLogEntryWithCachedValues()); 156 157 // Contact info contains a different name. 158 ContactInfo info = createContactInfo(); 159 info.name = "new name"; 160 mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info); 161 162 // Bind the views of a single row. 163 mAdapter.changeCursor(mCursor); 164 mAdapter.onBindViewHolder(mViewHolder, 0); 165 166 // There is one request for contact details. 167 assertEquals(1, mAdapter.getContactInfoCache().requests.size()); 168 169 TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0); 170 // Since there is something in the cache, it is not an immediate request. 171 assertFalse("should not be immediate", request.immediate); 172 } 173 174 /** Returns a contact info with default values. */ createContactInfo()175 private ContactInfo createContactInfo() { 176 ContactInfo info = new ContactInfo(); 177 info.number = TEST_NUMBER; 178 info.name = TEST_NAME; 179 info.type = TEST_NUMBER_TYPE; 180 info.label = TEST_NUMBER_LABEL; 181 return info; 182 } 183 184 /** Returns a call log entry without cached values. */ createCallLogEntry()185 private Object[] createCallLogEntry() { 186 Object[] values = CallLogQueryTestUtils.createTestValues(); 187 values[CallLogQuery.NUMBER] = TEST_NUMBER; 188 values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO; 189 return values; 190 } 191 192 /** Returns a call log entry with a cached values. */ createCallLogEntryWithCachedValues()193 private Object[] createCallLogEntryWithCachedValues() { 194 Object[] values = createCallLogEntry(); 195 values[CallLogQuery.CACHED_NAME] = TEST_NAME; 196 values[CallLogQuery.CACHED_NUMBER_TYPE] = TEST_NUMBER_TYPE; 197 values[CallLogQuery.CACHED_NUMBER_LABEL] = TEST_NUMBER_LABEL; 198 return values; 199 } 200 201 /** 202 * Subclass of {@link CallLogAdapter} used in tests to intercept certain calls. 203 */ 204 private static final class TestCallLogAdapter extends CallLogAdapter { TestCallLogAdapter(Context context, CallFetcher callFetcher, ContactInfoHelper contactInfoHelper)205 public TestCallLogAdapter(Context context, CallFetcher callFetcher, 206 ContactInfoHelper contactInfoHelper) { 207 super(context, callFetcher, contactInfoHelper, null, false); 208 mContactInfoCache = new TestContactInfoCache( 209 contactInfoHelper, mOnContactInfoChangedListener); 210 } 211 getContactInfoCache()212 public TestContactInfoCache getContactInfoCache() { 213 return (TestContactInfoCache) mContactInfoCache; 214 } 215 } 216 217 private static final class TestContactInfoCache extends ContactInfoCache { 218 public static class Request { 219 public final String number; 220 public final String countryIso; 221 public final ContactInfo callLogInfo; 222 public final boolean immediate; 223 Request(String number, String countryIso, ContactInfo callLogInfo, boolean immediate)224 public Request(String number, String countryIso, ContactInfo callLogInfo, 225 boolean immediate) { 226 this.number = number; 227 this.countryIso = countryIso; 228 this.callLogInfo = callLogInfo; 229 this.immediate = immediate; 230 } 231 } 232 233 public final List<Request> requests = Lists.newArrayList(); 234 TestContactInfoCache( ContactInfoHelper contactInfoHelper, OnContactInfoChangedListener listener)235 public TestContactInfoCache( 236 ContactInfoHelper contactInfoHelper, OnContactInfoChangedListener listener) { 237 super(contactInfoHelper, listener); 238 } 239 240 @Override enqueueRequest(String number, String countryIso, ContactInfo callLogInfo, boolean immediate)241 protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo, 242 boolean immediate) { 243 requests.add(new Request(number, countryIso, callLogInfo, immediate)); 244 } 245 } 246 } 247