Handle contacts without contact details

1. Disable call_action_id button for contacts without phone numbers.
2. Disable show_contact_detail_id button for contact that don't have
contact details to show.
3. Add configuration to determine whether to show the action buttons
as disabled states or not show them.
4. Make sure call_action_id and show_contact_detail_id can still be
swapped.
5. Fix and add unit tests
6. Use ViewUtils to setOnClickListener

Bug: 145825866
Test: manually
Change-Id: I0833b39754213ca69b9c98e9f32e2de564f5faa7
diff --git a/res/layout/contact_user_profile.xml b/res/layout/contact_user_profile.xml
index aa6e1d8..0bad55b 100644
--- a/res/layout/contact_user_profile.xml
+++ b/res/layout/contact_user_profile.xml
@@ -79,24 +79,35 @@
         app:layout_constraintStart_toStartOf="@id/contact_list_guideline_begin"
         app:layout_constraintEnd_toEndOf="@id/contact_list_guideline_end"/>
 
-    <ImageView
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/show_contact_detail_id"
         android:layout_width="0dp"
         android:layout_height="match_parent"
-        android:src="@drawable/ic_arrow_right"
-        android:scaleType="center"
-        android:tint="@color/secondary_icon_color"
-        android:background="?android:attr/selectableItemBackground"
+        app:layout_constraintStart_toStartOf="@id/contact_list_guideline_end"
+        app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@id/contact_list_guideline_end"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintBottom_toBottomOf="parent">
 
-    <View
-        android:layout_width="@dimen/vertical_divider_width"
-        android:layout_height="match_parent"
-        android:background="@color/divider_color"
-        android:layout_marginTop="@dimen/vertical_divider_inset"
-        android:layout_marginBottom="@dimen/vertical_divider_inset"
-        app:layout_constraintStart_toStartOf="@id/contact_list_guideline_end"/>
+        <View
+            android:layout_width="@dimen/vertical_divider_width"
+            android:layout_height="match_parent"
+            android:background="@color/divider_color"
+            android:layout_marginTop="@dimen/vertical_divider_inset"
+            android:layout_marginBottom="@dimen/vertical_divider_inset"
+            app:layout_constraintStart_toStartOf="parent"/>
+
+        <ImageView
+            android:id="@+id/contact_list_button"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_arrow_right"
+            android:background="?android:attr/selectableItemBackground"
+            android:duplicateParentState="true"
+            android:scaleType="center"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toEndOf="@id/contact_list_guideline_end"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/values/configs.xml b/res/values/configs.xml
index 8bbe3cb..273e312 100644
--- a/res/values/configs.xml
+++ b/res/values/configs.xml
@@ -31,6 +31,11 @@
     "false" will make divider and button invisible for non contacts. -->
     <bool name="config_show_calllog_action_button_for_non_contact">false</bool>
 
+    <!-- A config determines whether to show divider and the button on the right side for contacts
+    without any contact details. "true" will show divider and button as disable state and "false"
+    will make divider and button invisible for empty contacts. -->
+    <bool name="config_show_contact_detail_button_for_empty_contact">false</bool>
+
     <!-- A config determines whether to show postal address in contact details page. -->
     <bool name="config_show_postal_address">false</bool>
     <!-- A config determines whether to show the action bar view in the contact details page.-->
diff --git a/src/com/android/car/dialer/ui/calllog/CallLogAdapter.java b/src/com/android/car/dialer/ui/calllog/CallLogAdapter.java
index ffa8490..c0e4369 100644
--- a/src/com/android/car/dialer/ui/calllog/CallLogAdapter.java
+++ b/src/com/android/car/dialer/ui/calllog/CallLogAdapter.java
@@ -111,7 +111,7 @@
     @Override
     public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
         if (holder instanceof CallLogViewHolder) {
-            ((CallLogViewHolder) holder).onRecycle();
+            ((CallLogViewHolder) holder).recycle();
         }
     }
 
diff --git a/src/com/android/car/dialer/ui/calllog/CallLogViewHolder.java b/src/com/android/car/dialer/ui/calllog/CallLogViewHolder.java
index 677f750..bef477b 100644
--- a/src/com/android/car/dialer/ui/calllog/CallLogViewHolder.java
+++ b/src/com/android/car/dialer/ui/calllog/CallLogViewHolder.java
@@ -96,14 +96,18 @@
             mTextView.setTextAppearance(R.style.TextAppearance_CallLogTimestampDefault);
         }
 
-        mPlaceCallView.setOnClickListener(
+        ViewUtils.setOnClickListener(mPlaceCallView,
                 view -> UiCallManager.get().placeCall(uiCallLog.getNumber()));
 
         setUpActionButton(uiCallLog);
     }
 
-    public void onRecycle() {
+    /**
+     * Recycles views.
+     */
+    public void recycle() {
         mCallTypeIconsView.clear();
+        ViewUtils.setOnClickListener(mPlaceCallView, null);
     }
 
     private void setUpActionButton(UiCallLog uiCallLog) {
@@ -122,6 +126,8 @@
         if (contact != null) {
             ViewUtils.setOnClickListener(mActionButton,
                     view -> mOnShowContactDetailListener.onShowContactDetail(contact));
+        } else {
+            ViewUtils.setOnClickListener(mActionButton, null);
         }
     }
 }
diff --git a/src/com/android/car/dialer/ui/contact/ContactListAdapter.java b/src/com/android/car/dialer/ui/contact/ContactListAdapter.java
index 67b7242..17a9076 100644
--- a/src/com/android/car/dialer/ui/contact/ContactListAdapter.java
+++ b/src/com/android/car/dialer/ui/contact/ContactListAdapter.java
@@ -32,7 +32,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/** Adapter for contact list. */
+/**
+ * Adapter for contact list.
+ */
 public class ContactListAdapter extends RecyclerView.Adapter<ContactListViewHolder> {
     private static final String TAG = "CD.ContactListAdapter";
 
@@ -79,7 +81,7 @@
 
         boolean showHeader = position == 0
                 || (!header.equals(getHeader(mContactList.get(position - 1))));
-        holder.onBind(contact, showHeader, header);
+        holder.bind(contact, showHeader, header);
     }
 
     @Override
@@ -87,6 +89,12 @@
         return mContactList.size();
     }
 
+    @Override
+    public void onViewRecycled(@NonNull ContactListViewHolder holder) {
+        super.onViewRecycled(holder);
+        holder.recycle();
+    }
+
     private String getHeader(Contact contact) {
         String label;
         if (mSortMethod.equals(ContactSortingInfo.SORT_BY_LAST_NAME)) {
diff --git a/src/com/android/car/dialer/ui/contact/ContactListViewHolder.java b/src/com/android/car/dialer/ui/contact/ContactListViewHolder.java
index 60d909f..8a35f87 100644
--- a/src/com/android/car/dialer/ui/contact/ContactListViewHolder.java
+++ b/src/com/android/car/dialer/ui/contact/ContactListViewHolder.java
@@ -64,7 +64,7 @@
     /**
      * Binds the view holder with relevant data.
      */
-    public void onBind(Contact contact, boolean showHeader, String header) {
+    public void bind(Contact contact, boolean showHeader, String header) {
         TelecomUtils.setContactBitmapAsync(mAvatarView.getContext(), mAvatarView, contact);
         ViewUtils.setVisible(mHeaderView, showHeader);
         if (showHeader) {
@@ -72,13 +72,11 @@
         }
         mTitleView.setText(contact.getDisplayName());
         setLabelText(contact);
-        mShowContactDetailView.setOnClickListener(
-                view -> mOnShowContactDetailListener.onShowContactDetail(contact));
-        mCallActionView.setOnClickListener(view -> {
-            DialerUtils.promptForPrimaryNumber(itemView.getContext(), contact,
-                    (phoneNumber, always) -> UiCallManager.get().placeCall(
-                            phoneNumber.getRawNumber()));
-        });
+
+        boolean forceShowButton = itemView.getResources().getBoolean(
+                R.bool.config_show_contact_detail_button_for_empty_contact);
+        setCallActionView(contact, forceShowButton);
+        setShowContactDetailView(contact, forceShowButton);
     }
 
     private void setLabelText(Contact contact) {
@@ -101,4 +99,58 @@
 
         mTextView.setText(readableLabel);
     }
+
+    private void setCallActionView(Contact contact, boolean forceShowButton) {
+        if (mCallActionView == null) {
+            return;
+        }
+
+        boolean hasPhoneNumbers = contact != null && !contact.getNumbers().isEmpty();
+
+        ViewUtils.setEnabled(mCallActionView, hasPhoneNumbers);
+        ViewUtils.setVisible(mCallActionView, hasPhoneNumbers || forceShowButton);
+
+        if (hasPhoneNumbers) {
+            ViewUtils.setOnClickListener(mCallActionView, view -> {
+                DialerUtils.promptForPrimaryNumber(itemView.getContext(), contact,
+                        (phoneNumber, always) -> UiCallManager.get().placeCall(
+                                phoneNumber.getRawNumber()));
+            });
+        }  else {
+            ViewUtils.setOnClickListener(mCallActionView, null);
+        }
+    }
+
+    private void setShowContactDetailView(Contact contact, boolean forceShowButton) {
+        if (mShowContactDetailView == null) {
+            return;
+        }
+
+        boolean hasContactDetail = contact != null
+                && (!contact.getNumbers().isEmpty() || hasPostalAddress(contact));
+
+        ViewUtils.setEnabled(mShowContactDetailView, hasContactDetail);
+        ViewUtils.setVisible(mShowContactDetailView, hasContactDetail || forceShowButton);
+
+        if (hasContactDetail) {
+            ViewUtils.setOnClickListener(mShowContactDetailView,
+                    view -> mOnShowContactDetailListener.onShowContactDetail(contact));
+        } else {
+            ViewUtils.setOnClickListener(mShowContactDetailView, null);
+        }
+    }
+
+    private boolean hasPostalAddress(@NonNull Contact contact) {
+        boolean showPostalAddress = itemView.getResources().getBoolean(
+                R.bool.config_show_postal_address);
+        return showPostalAddress && (!contact.getPostalAddresses().isEmpty());
+    }
+
+    /**
+     * Recycles views.
+     */
+    public void recycle() {
+        ViewUtils.setOnClickListener(mCallActionView, null);
+        ViewUtils.setOnClickListener(mShowContactDetailView, null);
+    }
 }
diff --git a/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListFragmentTest.java b/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListFragmentTest.java
index 83cfb3e..1ae465b 100644
--- a/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListFragmentTest.java
+++ b/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListFragmentTest.java
@@ -41,6 +41,7 @@
 import com.android.car.dialer.ui.favorite.FavoriteViewModel;
 import com.android.car.telephony.common.Contact;
 import com.android.car.telephony.common.PhoneNumber;
+import com.android.car.telephony.common.PostalAddress;
 import com.android.car.ui.recyclerview.CarUiRecyclerView;
 
 import org.junit.Before;
@@ -53,6 +54,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowAlertDialog;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -80,6 +82,8 @@
     private Contact mMockContact3;
     @Mock
     private PhoneNumber mMockPhoneNumber;
+    @Mock
+    private PostalAddress mMockPostalAddress;
 
     @Before
     public void setUp() {
@@ -135,7 +139,22 @@
     }
 
     @Test
-    public void testClickShowContactDetailView_showContactDetail() {
+    public void testClickCallActionButton_ContactHasNoNumbers_callActionButtonNotEnabled() {
+        when(mMockContact1.getNumbers()).thenReturn(new ArrayList<>());
+        setUpFragment();
+
+        View callActionView = mViewHolder.itemView.findViewById(R.id.call_action_id);
+
+        assertThat(callActionView.isEnabled()).isFalse();
+        assertThat(callActionView.getVisibility() == View.VISIBLE).isEqualTo(
+                mViewHolder.itemView.getResources().getBoolean(
+                        R.bool.config_show_contact_detail_button_for_empty_contact));
+    }
+
+    @Test
+    public void testClickShowContactDetailView_withPhoneNumberAndAddress_showContactDetail() {
+        when(mMockContact1.getNumbers()).thenReturn(Arrays.asList(mMockPhoneNumber));
+        when(mMockContact1.getPostalAddresses()).thenReturn(Arrays.asList(mMockPostalAddress));
         setUpFragment();
 
         View showContactDetailActionView = mViewHolder.itemView.findViewById(
@@ -148,6 +167,46 @@
         verifyShowContactDetail();
     }
 
+    @Test
+    public void testClickShowContactDetailView_withAddressButNoPhoneNumber_dependOnConfig() {
+        when(mMockContact1.getPostalAddresses()).thenReturn(Arrays.asList(mMockPostalAddress));
+        setUpFragment();
+
+        View showContactDetailActionView = mViewHolder.itemView.findViewById(
+                R.id.show_contact_detail_id);
+
+        boolean showPostalAddress = mViewHolder.itemView.getResources().getBoolean(
+                R.bool.config_show_postal_address);
+        boolean forceShowButton = mViewHolder.itemView.getResources().getBoolean(
+                R.bool.config_show_contact_detail_button_for_empty_contact);
+
+        assertThat(showContactDetailActionView.isEnabled()).isEqualTo(showPostalAddress);
+        assertThat(showContactDetailActionView.getVisibility() == View.VISIBLE)
+                .isEqualTo(showPostalAddress || forceShowButton);
+
+        if (showPostalAddress) {
+            assertThat(showContactDetailActionView.hasOnClickListeners()).isTrue();
+
+            showContactDetailActionView.performClick();
+
+            // verify contact detail is shown.
+            verifyShowContactDetail();
+        }
+    }
+
+    @Test
+    public void testClickShowContactDetailView_NoPhoneNumberAndNoAddress_NotEnabled() {
+        setUpFragment();
+
+        View showContactDetailActionView = mViewHolder.itemView.findViewById(
+                R.id.show_contact_detail_id);
+
+        assertThat(showContactDetailActionView.isEnabled()).isFalse();
+        assertThat(showContactDetailActionView.getVisibility() == View.VISIBLE).isEqualTo(
+                mViewHolder.itemView.getResources().getBoolean(
+                        R.bool.config_show_contact_detail_button_for_empty_contact));
+    }
+
     private void setUpFragment() {
         mContactListFragment = ContactListFragment.newInstance();
         mFragmentTestActivity = Robolectric.buildActivity(
diff --git a/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListViewHolderTest.java b/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListViewHolderTest.java
index 5ec96e0..47f1cc8 100644
--- a/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListViewHolderTest.java
+++ b/tests/robotests/src/com/android/car/dialer/ui/contact/ContactListViewHolderTest.java
@@ -35,6 +35,7 @@
 import com.android.car.dialer.telecom.UiCallManager;
 import com.android.car.telephony.common.Contact;
 import com.android.car.telephony.common.PhoneNumber;
+import com.android.car.telephony.common.PostalAddress;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -81,7 +82,7 @@
     @Test
     public void testDisplayName() {
         when(mMockContact.getDisplayName()).thenReturn(DISPLAY_NAME);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.title)).getText()).isEqualTo(
                 DISPLAY_NAME);
@@ -92,7 +93,7 @@
         PhoneNumber phoneNumber = PhoneNumber.newInstance(mContext, PHONE_NUMBER_1, 0, LABEL_1,
                 false, 0, null, null, 0);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber));
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(LABEL_1);
     }
@@ -102,7 +103,7 @@
         PhoneNumber phoneNumber = PhoneNumber.newInstance(mContext, PHONE_NUMBER_1, TYPE, null,
                 false, 0, null, null, 0);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber));
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(
                 mContext.getResources().getText(
@@ -116,7 +117,7 @@
         PhoneNumber phoneNumber = mock(PhoneNumber.class);
         when(phoneNumber.getLabel()).thenReturn(null);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber));
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo("");
     }
@@ -129,7 +130,7 @@
                 false, 0, null, null, 0);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(false);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(
                 mContext.getString(R.string.type_multiple));
@@ -144,7 +145,7 @@
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(true);
         when(mMockContact.getPrimaryPhoneNumber()).thenReturn(phoneNumber2);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(
                 mContext.getString(R.string.primary_number_description, LABEL_2));
@@ -159,7 +160,7 @@
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(true);
         when(mMockContact.getPrimaryPhoneNumber()).thenReturn(phoneNumber2);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(
                 mContext.getString(R.string.primary_number_description,
@@ -178,7 +179,7 @@
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(true);
         when(mMockContact.getPrimaryPhoneNumber()).thenReturn(phoneNumber2);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(((TextView) mItemView.findViewById(R.id.text)).getText()).isEqualTo(
                 mContext.getString(R.string.primary_number_description, "null"));
@@ -190,7 +191,7 @@
         PhoneNumber phoneNumber = PhoneNumber.newInstance(mContext, PHONE_NUMBER_1, 0, LABEL_1,
                 false, 0, null, null, 0);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber));
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         View callActionView = mItemView.findViewById(R.id.call_action_id);
         assertThat(callActionView.hasOnClickListeners()).isTrue();
@@ -211,7 +212,7 @@
                 false, 0, null, null, 0);
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(false);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNull();
         View callActionView = mItemView.findViewById(R.id.call_action_id);
@@ -231,7 +232,7 @@
         when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber1, phoneNumber2));
         when(mMockContact.hasPrimaryPhoneNumber()).thenReturn(true);
         when(mMockContact.getPrimaryPhoneNumber()).thenReturn(phoneNumber2);
-        mContactListViewHolder.onBind(mMockContact, false, "");
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         View callActionView = mItemView.findViewById(R.id.call_action_id);
         assertThat(callActionView.hasOnClickListeners()).isTrue();
@@ -244,8 +245,10 @@
     }
 
     @Test
-    public void testClickShowContactDetailView_showContactDetail() {
-        mContactListViewHolder.onBind(mMockContact, false, "");
+    public void testClickShowContactDetailView_hasContactDetail_showContactDetail() {
+        PhoneNumber phoneNumber = mock(PhoneNumber.class);
+        when(mMockContact.getNumbers()).thenReturn(Arrays.asList(phoneNumber));
+        mContactListViewHolder.bind(mMockContact, false, "");
 
         View showContactDetailActionView = mItemView.findViewById(R.id.show_contact_detail_id);
         assertThat(showContactDetailActionView.hasOnClickListeners()).isTrue();
@@ -256,4 +259,44 @@
         verify(mMockListener).onShowContactDetail(captor.capture());
         assertThat(captor.getValue()).isEqualTo(mMockContact);
     }
+
+    @Test
+    public void testClickShowContactDetailView_hasAddressButNoPhoneNumber_dependOnConfig() {
+        PostalAddress postalAddress = mock(PostalAddress.class);
+        when(mMockContact.getPostalAddresses()).thenReturn(Arrays.asList(postalAddress));
+        mContactListViewHolder.bind(mMockContact, false, "");
+
+        View showContactDetailActionView = mItemView.findViewById(R.id.show_contact_detail_id);
+
+        boolean showPostalAddress = mItemView.getResources().getBoolean(
+                R.bool.config_show_postal_address);
+        boolean forceShowButton = mItemView.getResources().getBoolean(
+                R.bool.config_show_contact_detail_button_for_empty_contact);
+
+        assertThat(showContactDetailActionView.isEnabled()).isEqualTo(showPostalAddress);
+        assertThat(showContactDetailActionView.getVisibility() == View.VISIBLE).isEqualTo(
+                showPostalAddress || forceShowButton);
+
+        if (showPostalAddress) {
+            assertThat(showContactDetailActionView.hasOnClickListeners()).isTrue();
+
+            showContactDetailActionView.performClick();
+
+            ArgumentCaptor<Contact> captor = ArgumentCaptor.forClass(Contact.class);
+            verify(mMockListener).onShowContactDetail(captor.capture());
+            assertThat(captor.getValue()).isEqualTo(mMockContact);
+        }
+    }
+
+    @Test
+    public void testClickShowContactDetailView_NoContactDetail_ContactDetailButtonNotEnabled() {
+        mContactListViewHolder.bind(mMockContact, false, "");
+
+        View showContactDetailActionView = mItemView.findViewById(R.id.show_contact_detail_id);
+
+        assertThat(showContactDetailActionView.isEnabled()).isFalse();
+        assertThat(showContactDetailActionView.getVisibility() == View.VISIBLE).isEqualTo(
+                mItemView.getResources().getBoolean(
+                        R.bool.config_show_contact_detail_button_for_empty_contact));
+    }
 }