Home | History | Annotate | Download | only in search
      1 /*
      2  * Copyright (C) 2016 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 
     18 package com.android.settings.search;
     19 
     20 import static com.google.common.truth.Truth.assertThat;
     21 
     22 import static org.mockito.Matchers.any;
     23 import static org.mockito.Matchers.eq;
     24 import static org.mockito.Mockito.doReturn;
     25 import static org.mockito.Mockito.spy;
     26 import static org.mockito.Mockito.verify;
     27 import static org.mockito.Mockito.when;
     28 
     29 import android.content.ComponentName;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.content.pm.ApplicationInfo;
     33 import android.content.pm.PackageManager;
     34 import android.graphics.drawable.Drawable;
     35 import android.os.UserHandle;
     36 import android.util.Pair;
     37 import android.view.LayoutInflater;
     38 import android.view.View;
     39 
     40 import com.android.internal.logging.nano.MetricsProto;
     41 import com.android.settings.R;
     42 import com.android.settings.SettingsRobolectricTestRunner;
     43 import com.android.settings.TestConfig;
     44 import com.android.settings.search2.AppSearchResult;
     45 import com.android.settings.search2.IntentPayload;
     46 import com.android.settings.search2.IntentSearchViewHolder;
     47 import com.android.settings.search2.SearchFragment;
     48 import com.android.settings.search2.SearchResult;
     49 import com.android.settings.search2.SearchResult.Builder;
     50 import com.android.settings.testutils.FakeFeatureFactory;
     51 
     52 import org.junit.Before;
     53 import org.junit.Test;
     54 import org.junit.runner.RunWith;
     55 import org.mockito.Answers;
     56 import org.mockito.Mock;
     57 import org.mockito.MockitoAnnotations;
     58 import org.robolectric.RuntimeEnvironment;
     59 import org.robolectric.annotation.Config;
     60 
     61 import java.util.ArrayList;
     62 import java.util.List;
     63 
     64 @RunWith(SettingsRobolectricTestRunner.class)
     65 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
     66 public class IntentSearchViewHolderTest {
     67 
     68     private static final String TITLE = "title";
     69     private static final String SUMMARY = "summary";
     70     private static final int USER_ID = 10;
     71     private static final String BADGED_LABEL = "work title";
     72 
     73     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     74     private Context mContext;
     75     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     76     private SearchFragment mFragment;
     77     @Mock
     78     private PackageManager mPackageManager;
     79     private FakeFeatureFactory mFeatureFactory;
     80     private IntentSearchViewHolder mHolder;
     81     private Drawable mIcon;
     82     private Drawable mBadgedIcon;
     83 
     84     @Before
     85     public void setUp() {
     86         MockitoAnnotations.initMocks(this);
     87         FakeFeatureFactory.setupForTest(mContext);
     88         mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
     89 
     90         final Context context = RuntimeEnvironment.application;
     91         View view = LayoutInflater.from(context).inflate(R.layout.search_intent_item, null);
     92         mHolder = new IntentSearchViewHolder(view);
     93 
     94         mIcon = context.getDrawable(R.drawable.ic_search_history);
     95         mBadgedIcon = context.getDrawable(R.drawable.ic_add);
     96         when(mFragment.getActivity().getPackageManager()).thenReturn(mPackageManager);
     97     }
     98 
     99     @Test
    100     public void testConstructor_membersNotNull() {
    101         assertThat(mHolder.titleView).isNotNull();
    102         assertThat(mHolder.summaryView).isNotNull();
    103         assertThat(mHolder.iconView).isNotNull();
    104         assertThat(mHolder.breadcrumbView).isNotNull();
    105     }
    106 
    107     @Test
    108     public void testBindViewElements_allUpdated() {
    109         SearchResult result = getSearchResult(TITLE, SUMMARY, mIcon);
    110         mHolder.onBind(mFragment, result);
    111         mHolder.itemView.performClick();
    112 
    113         assertThat(mHolder.titleView.getText()).isEqualTo(TITLE);
    114         assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
    115         assertThat(mHolder.iconView.getDrawable()).isEqualTo(mIcon);
    116         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
    117         assertThat(mHolder.breadcrumbView.getVisibility()).isEqualTo(View.GONE);
    118 
    119         verify(mFragment).onSearchResultClicked();
    120         verify(mFragment).startActivity(any(Intent.class));
    121         verify(mFeatureFactory.metricsFeatureProvider).action(any(Context.class),
    122                 eq(MetricsProto.MetricsEvent.ACTION_CLICK_SETTINGS_SEARCH_RESULT),
    123                 eq(((IntentPayload)result.payload).intent.getComponent().flattenToString()),
    124                 any(Pair.class));
    125     }
    126 
    127     @Test
    128     public void testBindViewIcon_nullIcon_imageDrawableIsNull() {
    129         final SearchResult result = getSearchResult(TITLE, SUMMARY, null);
    130         mHolder.onBind(mFragment, result);
    131 
    132         assertThat(mHolder.iconView.getDrawable()).isNull();
    133     }
    134 
    135     @Test
    136     public void testBindViewElements_emptySummary_hideSummaryView() {
    137         final SearchResult result = new Builder()
    138                 .addTitle(TITLE)
    139                 .addRank(1)
    140                 .addPayload(new IntentPayload(null))
    141                 .addIcon(mIcon)
    142                 .build();
    143 
    144         mHolder.onBind(mFragment, result);
    145         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.GONE);
    146     }
    147 
    148     @Test
    149     public void testBindViewElements_withBreadcrumb_shouldFormatBreadcrumb() {
    150         final List<String> breadcrumbs = new ArrayList<>();
    151         breadcrumbs.add("a");
    152         breadcrumbs.add("b");
    153         breadcrumbs.add("c");
    154         final SearchResult result = new Builder()
    155                 .addTitle(TITLE)
    156                 .addRank(1)
    157                 .addPayload(new IntentPayload(null))
    158                 .addBreadcrumbs(breadcrumbs)
    159                 .addIcon(mIcon)
    160                 .build();
    161 
    162         mHolder.onBind(mFragment, result);
    163         assertThat(mHolder.breadcrumbView.getVisibility()).isEqualTo(View.VISIBLE);
    164         assertThat(mHolder.breadcrumbView.getText()).isEqualTo("a > b > c");
    165     }
    166 
    167     @Test
    168     public void testBindElements_placeholderSummary_visibilityIsGone() {
    169         String nonBreakingSpace = mContext.getString(R.string.summary_placeholder);
    170         SearchResult result = new Builder()
    171                 .addTitle(TITLE)
    172                 .addSummary(nonBreakingSpace)
    173                 .addPayload(new IntentPayload(null))
    174                 .build();
    175 
    176         mHolder.onBind(mFragment, result);
    177 
    178         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.GONE);
    179     }
    180 
    181     @Test
    182     public void testBindElements_dynamicSummary_visibilityIsGone() {
    183         String dynamicSummary = "%s";
    184         SearchResult result = new Builder()
    185                 .addTitle(TITLE)
    186                 .addSummary(dynamicSummary)
    187                 .addPayload(new IntentPayload(null))
    188                 .build();
    189 
    190         mHolder.onBind(mFragment, result);
    191 
    192         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.GONE);
    193     }
    194 
    195     public void testBindViewElements_appSearchResult() {
    196         when(mPackageManager.getUserBadgedLabel(any(CharSequence.class),
    197                 eq(new UserHandle(USER_ID)))).thenReturn(BADGED_LABEL);
    198 
    199         SearchResult result = getAppSearchResult(
    200                 TITLE, SUMMARY, mIcon, getApplicationInfo(USER_ID, TITLE, mIcon));
    201         mHolder.onBind(mFragment, result);
    202         mHolder.itemView.performClick();
    203 
    204         assertThat(mHolder.titleView.getText()).isEqualTo(TITLE);
    205         assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
    206         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
    207         assertThat(mHolder.breadcrumbView.getVisibility()).isEqualTo(View.GONE);
    208         assertThat(mHolder.titleView.getContentDescription()).isEqualTo(BADGED_LABEL);
    209 
    210         verify(mFragment).onSearchResultClicked();
    211         verify(mFragment.getActivity()).startActivityAsUser(
    212                 any(Intent.class), eq(new UserHandle(USER_ID)));
    213         verify(mFeatureFactory.metricsFeatureProvider).action(any(Context.class),
    214                 eq(MetricsProto.MetricsEvent.ACTION_CLICK_SETTINGS_SEARCH_RESULT),
    215                 eq(((IntentPayload)result.payload).intent.getComponent().flattenToString()),
    216                 any(Pair.class));
    217     }
    218 
    219     private SearchResult getSearchResult(String title, String summary, Drawable icon) {
    220         Builder builder = new Builder();
    221         builder.addTitle(title)
    222                 .addSummary(summary)
    223                 .addRank(1)
    224                 .addPayload(new IntentPayload(
    225                         new Intent().setComponent(new ComponentName("pkg", "class"))))
    226                 .addBreadcrumbs(new ArrayList<>())
    227                 .addIcon(icon);
    228 
    229         return builder.build();
    230     }
    231 
    232     private SearchResult getAppSearchResult(
    233             String title, String summary, Drawable icon, ApplicationInfo applicationInfo) {
    234         AppSearchResult.Builder builder = new AppSearchResult.Builder();
    235         builder.addTitle(title)
    236                 .addSummary(summary)
    237                 .addRank(1)
    238                 .addPayload(new IntentPayload(
    239                         new Intent().setComponent(new ComponentName("pkg", "class"))))
    240                 .addBreadcrumbs(new ArrayList<>())
    241                 .addIcon(icon);
    242         builder.setAppInfo(applicationInfo);
    243         return builder.build();
    244     }
    245 
    246     private ApplicationInfo getApplicationInfo(int userId, CharSequence appLabel, Drawable icon) {
    247         ApplicationInfo applicationInfo = spy(new ApplicationInfo());
    248         applicationInfo.uid = UserHandle.getUid(userId, 12345);
    249         doReturn(icon).when(applicationInfo).loadIcon(any(PackageManager.class));
    250         doReturn(appLabel).when(applicationInfo).loadLabel(any(PackageManager.class));
    251         return applicationInfo;
    252     }
    253 }
    254