Merge "Remove suggestion UI v1 codes."
This commit is contained in:
committed by
Android (Google) Code Review
commit
b832f737c3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +16,8 @@
|
||||
package com.android.settings.dashboard;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
@@ -30,14 +28,14 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
@@ -47,7 +45,6 @@ import com.android.settings.dashboard.suggestions.SuggestionAdapter;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -58,6 +55,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -81,8 +79,6 @@ public class DashboardAdapterTest {
|
||||
private Resources mResources;
|
||||
private FakeFeatureFactory mFactory;
|
||||
private DashboardAdapter mDashboardAdapter;
|
||||
private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder;
|
||||
private DashboardData.SuggestionConditionHeaderData mSuggestionHeaderData;
|
||||
private List<Condition> mConditionList;
|
||||
|
||||
@Before
|
||||
@@ -98,30 +94,17 @@ public class DashboardAdapterTest {
|
||||
mConditionList = new ArrayList<>();
|
||||
mConditionList.add(mCondition);
|
||||
when(mCondition.shouldShow()).thenReturn(true);
|
||||
mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null);
|
||||
mSuggestionHeaderData = new DashboardData.SuggestionConditionHeaderData(mConditionList, 1);
|
||||
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||
mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
when(mView.getTag()).thenReturn(mCondition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionsLogs_nullSuggestionsList_shouldNotCrash() {
|
||||
setupSuggestions(makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4", "pkg5"));
|
||||
mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
|
||||
|
||||
// set suggestions to null
|
||||
final DashboardData prevData = mDashboardAdapter.mDashboardData;
|
||||
mDashboardAdapter.mDashboardData = new DashboardData.Builder(prevData)
|
||||
.setSuggestions(null)
|
||||
.build();
|
||||
|
||||
mSuggestionHolder.itemView.callOnClick();
|
||||
// no crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
|
||||
final DashboardAdapter adapter =
|
||||
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /*
|
||||
lifecycle */));
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
|
||||
adapter.setSuggestions(suggestions);
|
||||
|
||||
@@ -130,18 +113,18 @@ public class DashboardAdapterTest {
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.data)).thenReturn(data);
|
||||
final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapter.SuggestionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionContainerHolder(itemView);
|
||||
|
||||
adapter.onBindConditionAndSuggestion(
|
||||
holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
|
||||
adapter.onBindSuggestion(holder, 0);
|
||||
|
||||
final DashboardData dashboardData = adapter.mDashboardData;
|
||||
reset(adapter); // clear interactions tracking
|
||||
|
||||
final Suggestion suggestionToRemove = suggestions.get(1);
|
||||
adapter.onSuggestionDismissed(suggestionToRemove);
|
||||
adapter.onSuggestionClosed(suggestionToRemove);
|
||||
|
||||
assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
|
||||
assertThat(suggestions.size()).isEqualTo(2);
|
||||
@@ -150,25 +133,25 @@ public class DashboardAdapterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionDismissed_moreThanTwoSuggestions_defaultMode_shouldNotCrash() {
|
||||
public void testSuggestionDismissed_moreThanTwoSuggestions_shouldNotCrash() {
|
||||
final RecyclerView data = new RecyclerView(RuntimeEnvironment.application);
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.data)).thenReturn(data);
|
||||
final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapter.SuggestionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionContainerHolder(itemView);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4");
|
||||
final DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null /*savedInstance */,
|
||||
null /* conditions */,
|
||||
null /* suggestionControllerMixin */, null /* callback */));
|
||||
final DashboardAdapter adapter = spy(new DashboardAdapter(mContext,
|
||||
null /*savedInstance */, null /* conditions */,
|
||||
null /* suggestionControllerMixin */,
|
||||
null /* lifecycle */));
|
||||
adapter.setSuggestions(suggestions);
|
||||
adapter.onBindConditionAndSuggestion(
|
||||
holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
|
||||
// default mode, only displaying 2 suggestions
|
||||
adapter.onBindSuggestion(holder, 0);
|
||||
|
||||
adapter.onSuggestionDismissed(suggestions.get(1));
|
||||
adapter.onSuggestionClosed(suggestions.get(1));
|
||||
|
||||
// verify operations that access the lists will not cause ConcurrentModificationException
|
||||
assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(1);
|
||||
assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(3);
|
||||
adapter.setSuggestions(suggestions);
|
||||
// should not crash
|
||||
}
|
||||
@@ -176,42 +159,25 @@ public class DashboardAdapterTest {
|
||||
@Test
|
||||
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
|
||||
DashboardAdapter adapter =
|
||||
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /*
|
||||
lifecycle */));
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
adapter.setSuggestions(suggestions);
|
||||
final DashboardData dashboardData = adapter.mDashboardData;
|
||||
reset(adapter); // clear interactions tracking
|
||||
|
||||
adapter.onSuggestionDismissed(suggestions.get(0));
|
||||
adapter.onSuggestionClosed(suggestions.get(0));
|
||||
|
||||
assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
|
||||
verify(adapter).notifyDashboardDataChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCategories_iconTinted() {
|
||||
TypedArray mockTypedArray = mock(TypedArray.class);
|
||||
doReturn(mockTypedArray).when(mContext).obtainStyledAttributes(any(int[].class));
|
||||
doReturn(0x89000000).when(mockTypedArray).getColor(anyInt(), anyInt());
|
||||
|
||||
final DashboardCategory category = new DashboardCategory();
|
||||
final Icon mockIcon = mock(Icon.class);
|
||||
final Tile tile = new Tile();
|
||||
tile.isIconTintable = true;
|
||||
tile.icon = mockIcon;
|
||||
category.addTile(tile);
|
||||
|
||||
mDashboardAdapter.setCategory(category);
|
||||
|
||||
verify(mockIcon).setTint(eq(0x89000000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindConditionAndSuggestion_v2_shouldSetSuggestionAdapterAndNoCrash() {
|
||||
mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null);
|
||||
public void testBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
||||
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
final DashboardCategory category = new DashboardCategory();
|
||||
category.addTile(mock(Tile.class));
|
||||
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
@@ -220,17 +186,88 @@ public class DashboardAdapterTest {
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.data)).thenReturn(data);
|
||||
final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapter.SuggestionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionContainerHolder(itemView);
|
||||
|
||||
mDashboardAdapter.onBindConditionAndSuggestion(
|
||||
holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(data).setAdapter(any(SuggestionAdapter.class));
|
||||
// should not crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindSuggestion_shouldSetSummary() {
|
||||
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
final RecyclerView data = mock(RecyclerView.class);
|
||||
when(data.getResources()).thenReturn(mResources);
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
final TextView summary = mock(TextView.class);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(summary);
|
||||
final DashboardAdapter.SuggestionContainerHolder holder =
|
||||
new DashboardAdapter.SuggestionContainerHolder(itemView);
|
||||
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(summary).setText("1");
|
||||
|
||||
suggestions.addAll(makeSuggestionsV2("pkg2", "pkg3", "pkg4"));
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(summary).setText("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindTile_internalTile_shouldNotUseGenericBackgroundIcon() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
|
||||
final DashboardAdapter.DashboardItemHolder holder =
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
final Tile tile = new Tile();
|
||||
tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
|
||||
final DashboardAdapter.IconCache iconCache = mock(DashboardAdapter.IconCache.class);
|
||||
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
|
||||
|
||||
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||
mDashboardAdapter.onBindTile(holder, tile);
|
||||
|
||||
verify(iconCache, never()).updateIcon(any(Icon.class), any(Drawable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindTile_externalTile_shouldNotUseGenericBackgroundIcon() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
|
||||
final DashboardAdapter.DashboardItemHolder holder =
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
final Tile tile = new Tile();
|
||||
tile.icon = mock(Icon.class);
|
||||
when(tile.icon.getResPackage()).thenReturn("another.package");
|
||||
|
||||
final DashboardAdapter.IconCache iconCache = mock(DashboardAdapter.IconCache.class);
|
||||
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
|
||||
|
||||
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||
mDashboardAdapter.onBindTile(holder, tile);
|
||||
|
||||
verify(iconCache).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
|
||||
}
|
||||
|
||||
private List<Suggestion> makeSuggestionsV2(String... pkgNames) {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
for (String pkgName : pkgNames) {
|
||||
@@ -245,8 +282,5 @@ public class DashboardAdapterTest {
|
||||
private void setupSuggestions(List<Suggestion> suggestions) {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = new DashboardAdapter.SuggestionAndConditionHeaderHolder(
|
||||
LayoutInflater.from(context).inflate(
|
||||
R.layout.suggestion_condition_header, new RelativeLayout(context), true));
|
||||
}
|
||||
}
|
||||
|
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.dashboard;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.conditional.Condition;
|
||||
import com.android.settings.dashboard.suggestions.SuggestionAdapterV2;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH,
|
||||
sdk = TestConfig.SDK_VERSION,
|
||||
shadows = {
|
||||
SettingsShadowResources.class,
|
||||
SettingsShadowResources.SettingsShadowTheme.class,
|
||||
})
|
||||
public class DashboardAdapterV2Test {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private SettingsActivity mContext;
|
||||
@Mock
|
||||
private View mView;
|
||||
@Mock
|
||||
private Condition mCondition;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
private FakeFeatureFactory mFactory;
|
||||
private DashboardAdapterV2 mDashboardAdapter;
|
||||
private List<Condition> mConditionList;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mFactory = FakeFeatureFactory.setupForTest();
|
||||
when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true);
|
||||
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getQuantityString(any(int.class), any(int.class), any()))
|
||||
.thenReturn("");
|
||||
|
||||
mConditionList = new ArrayList<>();
|
||||
mConditionList.add(mCondition);
|
||||
when(mCondition.shouldShow()).thenReturn(true);
|
||||
mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
|
||||
mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
when(mView.getTag()).thenReturn(mCondition);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
|
||||
final DashboardAdapterV2 adapter =
|
||||
spy(new DashboardAdapterV2(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /*
|
||||
lifecycle */));
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
|
||||
adapter.setSuggestions(suggestions);
|
||||
|
||||
final RecyclerView data = mock(RecyclerView.class);
|
||||
when(data.getResources()).thenReturn(mResources);
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapterV2.SuggestionContainerHolder holder =
|
||||
new DashboardAdapterV2.SuggestionContainerHolder(itemView);
|
||||
|
||||
adapter.onBindSuggestion(holder, 0);
|
||||
|
||||
final DashboardDataV2 dashboardData = adapter.mDashboardData;
|
||||
reset(adapter); // clear interactions tracking
|
||||
|
||||
final Suggestion suggestionToRemove = suggestions.get(1);
|
||||
adapter.onSuggestionClosed(suggestionToRemove);
|
||||
|
||||
assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
|
||||
assertThat(suggestions.size()).isEqualTo(2);
|
||||
assertThat(suggestions.contains(suggestionToRemove)).isFalse();
|
||||
verify(adapter, never()).notifyDashboardDataChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionDismissed_moreThanTwoSuggestions_shouldNotCrash() {
|
||||
final RecyclerView data = new RecyclerView(RuntimeEnvironment.application);
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapterV2.SuggestionContainerHolder holder =
|
||||
new DashboardAdapterV2.SuggestionContainerHolder(itemView);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4");
|
||||
final DashboardAdapterV2 adapter = spy(new DashboardAdapterV2(mContext,
|
||||
null /*savedInstance */, null /* conditions */,
|
||||
null /* suggestionControllerMixin */,
|
||||
null /* lifecycle */));
|
||||
adapter.setSuggestions(suggestions);
|
||||
adapter.onBindSuggestion(holder, 0);
|
||||
|
||||
adapter.onSuggestionClosed(suggestions.get(1));
|
||||
|
||||
// verify operations that access the lists will not cause ConcurrentModificationException
|
||||
assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(3);
|
||||
adapter.setSuggestions(suggestions);
|
||||
// should not crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
|
||||
DashboardAdapterV2 adapter =
|
||||
spy(new DashboardAdapterV2(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /*
|
||||
lifecycle */));
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
adapter.setSuggestions(suggestions);
|
||||
final DashboardDataV2 dashboardData = adapter.mDashboardData;
|
||||
reset(adapter); // clear interactions tracking
|
||||
|
||||
adapter.onSuggestionClosed(suggestions.get(0));
|
||||
|
||||
assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
|
||||
verify(adapter).notifyDashboardDataChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
||||
mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
final RecyclerView data = mock(RecyclerView.class);
|
||||
when(data.getResources()).thenReturn(mResources);
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
|
||||
final DashboardAdapterV2.SuggestionContainerHolder holder =
|
||||
new DashboardAdapterV2.SuggestionContainerHolder(itemView);
|
||||
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(data).setAdapter(any(SuggestionAdapterV2.class));
|
||||
// should not crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindSuggestion_shouldSetSummary() {
|
||||
mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
|
||||
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
final RecyclerView data = mock(RecyclerView.class);
|
||||
when(data.getResources()).thenReturn(mResources);
|
||||
when(data.getContext()).thenReturn(mContext);
|
||||
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||
final View itemView = mock(View.class);
|
||||
when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
|
||||
final TextView summary = mock(TextView.class);
|
||||
when(itemView.findViewById(android.R.id.summary)).thenReturn(summary);
|
||||
final DashboardAdapterV2.SuggestionContainerHolder holder =
|
||||
new DashboardAdapterV2.SuggestionContainerHolder(itemView);
|
||||
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(summary).setText("1");
|
||||
|
||||
suggestions.addAll(makeSuggestionsV2("pkg2", "pkg3", "pkg4"));
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
|
||||
mDashboardAdapter.onBindSuggestion(holder, 0);
|
||||
|
||||
verify(summary).setText("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindTile_internalTile_shouldNotUseGenericBackgroundIcon() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
|
||||
final DashboardAdapterV2.DashboardItemHolder holder =
|
||||
new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
final Tile tile = new Tile();
|
||||
tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
|
||||
final DashboardAdapterV2.IconCache iconCache = mock(DashboardAdapterV2.IconCache.class);
|
||||
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
|
||||
|
||||
mDashboardAdapter = new DashboardAdapterV2(context, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||
mDashboardAdapter.onBindTile(holder, tile);
|
||||
|
||||
verify(iconCache, never()).updateIcon(any(Icon.class), any(Drawable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindTile_externalTile_shouldNotUseGenericBackgroundIcon() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
|
||||
final DashboardAdapterV2.DashboardItemHolder holder =
|
||||
new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
final Tile tile = new Tile();
|
||||
tile.icon = mock(Icon.class);
|
||||
when(tile.icon.getResPackage()).thenReturn("another.package");
|
||||
|
||||
final DashboardAdapterV2.IconCache iconCache = mock(DashboardAdapterV2.IconCache.class);
|
||||
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
|
||||
|
||||
mDashboardAdapter = new DashboardAdapterV2(context, null /* savedInstanceState */,
|
||||
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
|
||||
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
|
||||
mDashboardAdapter.onBindTile(holder, tile);
|
||||
|
||||
verify(iconCache).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
|
||||
}
|
||||
|
||||
private List<Suggestion> makeSuggestionsV2(String... pkgNames) {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
for (String pkgName : pkgNames) {
|
||||
final Suggestion suggestion = new Suggestion.Builder(pkgName)
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.build();
|
||||
suggestions.add(suggestion);
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
private void setupSuggestions(List<Suggestion> suggestions) {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
mDashboardAdapter.setSuggestions(suggestions);
|
||||
}
|
||||
}
|
@@ -17,8 +17,9 @@
|
||||
package com.android.settings.dashboard;
|
||||
|
||||
import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER;
|
||||
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER;
|
||||
import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_FOOTER;
|
||||
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER;
|
||||
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_DIVIDER;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -103,14 +104,14 @@ public class DashboardDataTest {
|
||||
.setConditions(oneItemConditions)
|
||||
.setCategory(mDashboardCategory)
|
||||
.setSuggestions(suggestions)
|
||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
||||
.setConditionExpanded(true)
|
||||
.build();
|
||||
|
||||
mDashboardDataWithTwoConditions = new DashboardData.Builder()
|
||||
.setConditions(twoItemsConditions)
|
||||
.setCategory(mDashboardCategory)
|
||||
.setSuggestions(suggestions)
|
||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
|
||||
.setConditionExpanded(true)
|
||||
.build();
|
||||
|
||||
mDashboardDataWithNoItems = new DashboardData.Builder()
|
||||
@@ -124,21 +125,23 @@ public class DashboardDataTest {
|
||||
public void testBuildItemsData_shouldSetstableId() {
|
||||
final List<DashboardData.Item> items = mDashboardDataWithOneConditions.getItemList();
|
||||
|
||||
// Header, suggestion, condition, footer, 1 tile
|
||||
assertThat(items).hasSize(4);
|
||||
// suggestion, seperator, condition, footer, 1 tile
|
||||
assertThat(items).hasSize(5);
|
||||
|
||||
assertThat(items.get(0).id).isEqualTo(STABLE_ID_SUGGESTION_CONTAINER);
|
||||
assertThat(items.get(1).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
|
||||
assertThat(items.get(2).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_FOOTER);
|
||||
assertThat(items.get(3).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
|
||||
assertThat(items.get(1).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_DIVIDER);
|
||||
assertThat(items.get(2).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
|
||||
assertThat(items.get(3).id).isEqualTo(STABLE_ID_CONDITION_FOOTER);
|
||||
assertThat(items.get(4).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildItemsData_containsAllData() {
|
||||
final Object[] expectedObjects = {
|
||||
mDashboardDataWithOneConditions.getSuggestions(),
|
||||
null /* divider */,
|
||||
mDashboardDataWithOneConditions.getConditions(),
|
||||
null, mTestCategoryTile};
|
||||
null /* footer */, mTestCategoryTile};
|
||||
final int expectedSize = expectedObjects.length;
|
||||
|
||||
assertThat(mDashboardDataWithOneConditions.getItemList()).hasSize(expectedSize);
|
||||
@@ -147,14 +150,13 @@ public class DashboardDataTest {
|
||||
final Object item = mDashboardDataWithOneConditions.getItemEntityByPosition(i);
|
||||
if (item instanceof List) {
|
||||
assertThat(item).isEqualTo(expectedObjects[i]);
|
||||
} else if (item instanceof DashboardData.SuggestionConditionHeaderData) {
|
||||
DashboardData.SuggestionConditionHeaderData i1 =
|
||||
(DashboardData.SuggestionConditionHeaderData) item;
|
||||
DashboardData.SuggestionConditionHeaderData i2 =
|
||||
(DashboardData.SuggestionConditionHeaderData) expectedObjects[i];
|
||||
} else if (item instanceof DashboardData.ConditionHeaderData) {
|
||||
DashboardData.ConditionHeaderData i1 =
|
||||
(DashboardData.ConditionHeaderData) item;
|
||||
DashboardData.ConditionHeaderData i2 =
|
||||
(DashboardData.ConditionHeaderData) expectedObjects[i];
|
||||
assertThat(i1.title).isEqualTo(i2.title);
|
||||
assertThat(i1.conditionCount).isEqualTo(i2.conditionCount);
|
||||
assertThat(i1.hiddenSuggestionCount).isEqualTo(i2.hiddenSuggestionCount);
|
||||
} else {
|
||||
assertThat(item).isSameAs(expectedObjects[i]);
|
||||
}
|
||||
@@ -209,10 +211,10 @@ public class DashboardDataTest {
|
||||
public void testDiffUtil_InsertOneCondition_ResultDataOneChanged() {
|
||||
//Build testResultData
|
||||
final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
|
||||
// Item in position 2 is the condition container containing the list of conditions, which
|
||||
// Item in position 3 is the condition container containing the list of conditions, which
|
||||
// gets 1 more item
|
||||
testResultData.add(new ListUpdateResult.ResultData(
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
|
||||
|
||||
testDiffUtil(mDashboardDataWithOneConditions,
|
||||
mDashboardDataWithTwoConditions, testResultData);
|
||||
@@ -222,10 +224,11 @@ public class DashboardDataTest {
|
||||
public void testDiffUtil_RemoveOneSuggestion_causeItemRemoveAndChange() {
|
||||
//Build testResultData
|
||||
final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
|
||||
// removed suggestion and the divider
|
||||
testResultData.add(new ListUpdateResult.ResultData(
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 1));
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 2));
|
||||
testResultData.add(new ListUpdateResult.ResultData(
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
|
||||
// Build DashboardData
|
||||
final List<Condition> oneItemConditions = new ArrayList<>();
|
||||
when(mTestCondition.shouldShow()).thenReturn(true);
|
||||
@@ -237,13 +240,13 @@ public class DashboardDataTest {
|
||||
.setConditions(oneItemConditions)
|
||||
.setCategory(mDashboardCategory)
|
||||
.setSuggestions(suggestions)
|
||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
|
||||
.setConditionExpanded(false)
|
||||
.build();
|
||||
final DashboardData newData = new DashboardData.Builder()
|
||||
.setConditions(oneItemConditions)
|
||||
.setSuggestions(null)
|
||||
.setCategory(mDashboardCategory)
|
||||
.setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
|
||||
.setConditionExpanded(false)
|
||||
.build();
|
||||
|
||||
testDiffUtil(oldData, newData, testResultData);
|
||||
@@ -254,7 +257,7 @@ public class DashboardDataTest {
|
||||
//Build testResultData
|
||||
final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
|
||||
testResultData.add(new ListUpdateResult.ResultData(
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 4));
|
||||
ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 5));
|
||||
|
||||
testDiffUtil(mDashboardDataWithOneConditions, mDashboardDataWithNoItems, testResultData);
|
||||
}
|
||||
|
@@ -164,10 +164,4 @@ public class DashboardSummaryTest {
|
||||
mSummary.onCategoriesChanged();
|
||||
verify(mSummary).rebuildUI();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSuggestionDismissed_shouldNotRebuildUI() {
|
||||
mSummary.onSuggestionDismissed(mock(Suggestion.class));
|
||||
verify(mSummary, never()).rebuildUI();
|
||||
}
|
||||
}
|
@@ -15,6 +15,11 @@
|
||||
*/
|
||||
package com.android.settings.dashboard.conditional;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -22,13 +27,9 @@ import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.DashboardAdapter;
|
||||
import com.android.settings.dashboard.DashboardData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -38,9 +39,8 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
@@ -70,35 +70,23 @@ public class ConditionAdapterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_notFullyExpanded_shouldReturn0() {
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_DEFAULT);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
||||
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
||||
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_COLLAPSED);
|
||||
public void getItemCount_notExpanded_shouldReturn0() {
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, false);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_fullyExpanded_shouldReturnListSize() {
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_FULLY_EXPANDED);
|
||||
public void getItemCount_expanded_shouldReturnListSize() {
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
|
||||
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mTwoConditions, DashboardData.HEADER_MODE_FULLY_EXPANDED);
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemViewType_shouldReturnConditionTile() {
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mTwoConditions, DashboardData.HEADER_MODE_FULLY_EXPANDED);
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
|
||||
assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
|
||||
}
|
||||
|
||||
@@ -108,8 +96,7 @@ public class ConditionAdapterTest {
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
||||
|
||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||
final View card = view.findViewById(R.id.content);
|
||||
@@ -122,8 +109,7 @@ public class ConditionAdapterTest {
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
||||
|
||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||
final View card = view.findViewById(R.id.content);
|
||||
@@ -137,9 +123,8 @@ public class ConditionAdapterTest {
|
||||
final View view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapter.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapter(
|
||||
mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
|
||||
new DashboardAdapter.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
|
||||
mConditionAdapter.addDismissHandling(recyclerView);
|
||||
|
||||
// do not bind viewholder to simulate the null condition scenario
|
||||
|
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.dashboard.conditional;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.DashboardAdapterV2;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class ConditionAdapterV2Test {
|
||||
@Mock
|
||||
private Condition mCondition1;
|
||||
@Mock
|
||||
private Condition mCondition2;
|
||||
|
||||
private Context mContext;
|
||||
private ConditionAdapterV2 mConditionAdapter;
|
||||
private List<Condition> mOneCondition;
|
||||
private List<Condition> mTwoConditions;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
final CharSequence[] actions = new CharSequence[2];
|
||||
when(mCondition1.getActions()).thenReturn(actions);
|
||||
when(mCondition1.shouldShow()).thenReturn(true);
|
||||
mOneCondition = new ArrayList<>();
|
||||
mOneCondition.add(mCondition1);
|
||||
mTwoConditions = new ArrayList<>();
|
||||
mTwoConditions.add(mCondition1);
|
||||
mTwoConditions.add(mCondition2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_notExpanded_shouldReturn0() {
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, false);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_expanded_shouldReturnListSize() {
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
|
||||
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mTwoConditions, true);
|
||||
assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemViewType_shouldReturnConditionTile() {
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mTwoConditions, true);
|
||||
assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_shouldSetListener() {
|
||||
final View view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapterV2.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
|
||||
|
||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||
final View card = view.findViewById(R.id.content);
|
||||
assertThat(card.hasOnClickListeners()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void viewClick_shouldInvokeConditionPrimaryClick() {
|
||||
final View view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapterV2.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
|
||||
|
||||
mConditionAdapter.onBindViewHolder(viewHolder, 0);
|
||||
final View card = view.findViewById(R.id.content);
|
||||
card.performClick();
|
||||
verify(mCondition1).onPrimaryClick();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSwiped_nullCondition_shouldNotCrash() {
|
||||
final RecyclerView recyclerView = new RecyclerView(mContext);
|
||||
final View view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.condition_tile, new LinearLayout(mContext), true);
|
||||
final DashboardAdapterV2.DashboardItemHolder viewHolder =
|
||||
new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
|
||||
mConditionAdapter.addDismissHandling(recyclerView);
|
||||
|
||||
// do not bind viewholder to simulate the null condition scenario
|
||||
mConditionAdapter.mSwipeCallback.onSwiped(viewHolder, 0);
|
||||
// no crash
|
||||
}
|
||||
|
||||
}
|
@@ -16,12 +16,19 @@
|
||||
package com.android.settings.dashboard.suggestions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -46,6 +53,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -87,20 +95,21 @@ public class SuggestionAdapterTest {
|
||||
@Test
|
||||
public void getItemCount_shouldReturnListSize() {
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
mOneSuggestion, new ArrayList<>());
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1);
|
||||
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
mTwoSuggestions, new ArrayList<>());
|
||||
mSuggestionAdapter.setSuggestions(mTwoSuggestions);
|
||||
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemViewType_shouldReturnSuggestionTile() {
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
mOneSuggestion, new ArrayList<>());
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
assertThat(mSuggestionAdapter.getItemViewType(0))
|
||||
.isEqualTo(R.layout.suggestion_tile);
|
||||
.isEqualTo(R.layout.suggestion_tile);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,19 +121,21 @@ public class SuggestionAdapterTest {
|
||||
.setSummary("456")
|
||||
.build());
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
suggestions, new ArrayList<>());
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
|
||||
assertThat(mSuggestionAdapter.getItemViewType(0))
|
||||
.isEqualTo(R.layout.suggestion_tile_with_button);
|
||||
.isEqualTo(R.layout.suggestion_tile_with_button);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_shouldLog() {
|
||||
final View view = spy(LayoutInflater.from(mContext).inflate(
|
||||
R.layout.suggestion_tile, new LinearLayout(mContext), true));
|
||||
R.layout.suggestion_tile, new LinearLayout(mContext), true));
|
||||
mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
mOneSuggestion, new ArrayList<>());
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
|
||||
// Bind twice
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
@@ -149,6 +160,31 @@ public class SuggestionAdapterTest {
|
||||
verify(suggestions.get(0).getPendingIntent()).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_hasButton_buttonShouldHandleClick()
|
||||
throws PendingIntent.CanceledException {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
final PendingIntent pendingIntent = mock(PendingIntent.class);
|
||||
suggestions.add(new Suggestion.Builder("id")
|
||||
.setFlags(Suggestion.FLAG_HAS_BUTTON)
|
||||
.setTitle("123")
|
||||
.setSummary("456")
|
||||
.setPendingIntent(pendingIntent)
|
||||
.build());
|
||||
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.findViewById(android.R.id.primary).performClick();
|
||||
|
||||
verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
|
||||
verify(pendingIntent).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSuggestions_shouldReturnSuggestionWhenMatch() {
|
||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||
@@ -157,9 +193,92 @@ public class SuggestionAdapterTest {
|
||||
assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_closeButtonShouldHandleClick()
|
||||
throws PendingIntent.CanceledException {
|
||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||
final SuggestionAdapter.Callback callback = mock(SuggestionAdapter.Callback.class);
|
||||
mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, callback, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
|
||||
|
||||
final Suggestion suggestion = suggestions.get(0);
|
||||
verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
|
||||
mActivity, mSuggestionControllerMixin, suggestion);
|
||||
verify(callback).onSuggestionClosed(suggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_differentPackage_shouldNotTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
when(icon.getResPackage()).thenReturn("pkg1");
|
||||
when(mActivity.getPackageName()).thenReturn("pkg2");
|
||||
final Suggestion suggestion = new Suggestion.Builder("pkg1")
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable, never()).setTint(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_samePackage_shouldTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
final String packageName = "pkg1";
|
||||
when(icon.getResPackage()).thenReturn(packageName);
|
||||
when(mActivity.getPackageName()).thenReturn(packageName);
|
||||
final Suggestion suggestion = new Suggestion.Builder(packageName)
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
TypedArray typedArray = mock(TypedArray.class);
|
||||
final int colorAccent = 1234;
|
||||
when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
|
||||
when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable).setTint(colorAccent);
|
||||
}
|
||||
|
||||
private void setupSuggestions(Context context, List<Suggestion> suggestions) {
|
||||
mSuggestionAdapter = new SuggestionAdapter(context, mSuggestionControllerMixin,
|
||||
suggestions, new ArrayList<>());
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
|
@@ -1,297 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.dashboard.suggestions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.DashboardAdapterV2;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.suggestions.SuggestionControllerMixin;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class SuggestionAdapterV2Test {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private SettingsActivity mActivity;
|
||||
@Mock
|
||||
private SuggestionControllerMixin mSuggestionControllerMixin;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private Context mContext;
|
||||
private SuggestionAdapterV2 mSuggestionAdapter;
|
||||
private DashboardAdapterV2.DashboardItemHolder mSuggestionHolder;
|
||||
private List<Suggestion> mOneSuggestion;
|
||||
private List<Suggestion> mTwoSuggestions;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
|
||||
final Suggestion suggestion1 = new Suggestion.Builder("id1")
|
||||
.setTitle("Test suggestion 1")
|
||||
.build();
|
||||
final Suggestion suggestion2 = new Suggestion.Builder("id2")
|
||||
.setTitle("Test suggestion 2")
|
||||
.build();
|
||||
mOneSuggestion = new ArrayList<>();
|
||||
mOneSuggestion.add(suggestion1);
|
||||
mTwoSuggestions = new ArrayList<>();
|
||||
mTwoSuggestions.add(suggestion1);
|
||||
mTwoSuggestions.add(suggestion2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_shouldReturnListSize() {
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1);
|
||||
|
||||
mSuggestionAdapter.setSuggestions(mTwoSuggestions);
|
||||
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemViewType_shouldReturnSuggestionTile() {
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
assertThat(mSuggestionAdapter.getItemViewType(0))
|
||||
.isEqualTo(R.layout.suggestion_tile_v2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemType_hasButton_shouldReturnSuggestionWithButton() {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(new Suggestion.Builder("id")
|
||||
.setFlags(Suggestion.FLAG_HAS_BUTTON)
|
||||
.setTitle("123")
|
||||
.setSummary("456")
|
||||
.build());
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
|
||||
assertThat(mSuggestionAdapter.getItemViewType(0))
|
||||
.isEqualTo(R.layout.suggestion_tile_with_button_v2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_shouldLog() {
|
||||
final View view = spy(LayoutInflater.from(mContext).inflate(
|
||||
R.layout.suggestion_tile, new LinearLayout(mContext), true));
|
||||
mSuggestionHolder = new DashboardAdapterV2.DashboardItemHolder(view);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(mOneSuggestion);
|
||||
|
||||
// Bind twice
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
// Log once
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(
|
||||
mContext, MetricsProto.MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
|
||||
mOneSuggestion.get(0).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_itemViewShouldHandleClick()
|
||||
throws PendingIntent.CanceledException {
|
||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||
setupSuggestions(mActivity, suggestions);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.performClick();
|
||||
|
||||
verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
|
||||
verify(suggestions.get(0).getPendingIntent()).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_hasButton_buttonShouldHandleClick()
|
||||
throws PendingIntent.CanceledException {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
final PendingIntent pendingIntent = mock(PendingIntent.class);
|
||||
suggestions.add(new Suggestion.Builder("id")
|
||||
.setFlags(Suggestion.FLAG_HAS_BUTTON)
|
||||
.setTitle("123")
|
||||
.setSummary("456")
|
||||
.setPendingIntent(pendingIntent)
|
||||
.build());
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.findViewById(android.R.id.primary).performClick();
|
||||
|
||||
verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
|
||||
verify(pendingIntent).send();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSuggestions_shouldReturnSuggestionWhenMatch() {
|
||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||
setupSuggestions(mActivity, suggestions);
|
||||
|
||||
assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_closeButtonShouldHandleClick()
|
||||
throws PendingIntent.CanceledException {
|
||||
final List<Suggestion> suggestions = makeSuggestions("pkg1");
|
||||
final SuggestionAdapterV2.Callback callback = mock(SuggestionAdapterV2.Callback.class);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, callback, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
|
||||
|
||||
final Suggestion suggestion = suggestions.get(0);
|
||||
verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
|
||||
mActivity, mSuggestionControllerMixin, suggestion);
|
||||
verify(callback).onSuggestionClosed(suggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_differentPackage_shouldNotTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
when(icon.getResPackage()).thenReturn("pkg1");
|
||||
when(mActivity.getPackageName()).thenReturn("pkg2");
|
||||
final Suggestion suggestion = new Suggestion.Builder("pkg1")
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable, never()).setTint(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_samePackage_shouldTintIcon()
|
||||
throws PendingIntent.CanceledException {
|
||||
final Icon icon = mock(Icon.class);
|
||||
final String packageName = "pkg1";
|
||||
when(icon.getResPackage()).thenReturn(packageName);
|
||||
when(mActivity.getPackageName()).thenReturn(packageName);
|
||||
final Suggestion suggestion = new Suggestion.Builder(packageName)
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.setIcon(icon)
|
||||
.build();
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
suggestions.add(suggestion);
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
TypedArray typedArray = mock(TypedArray.class);
|
||||
final int colorAccent = 1234;
|
||||
when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
|
||||
when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable).setTint(colorAccent);
|
||||
}
|
||||
|
||||
private void setupSuggestions(Context context, List<Suggestion> suggestions) {
|
||||
mSuggestionAdapter = new SuggestionAdapterV2(context, mSuggestionControllerMixin,
|
||||
null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
|
||||
mSuggestionAdapter.setSuggestions(suggestions);
|
||||
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
|
||||
new FrameLayout(RuntimeEnvironment.application),
|
||||
mSuggestionAdapter.getItemViewType(0));
|
||||
}
|
||||
|
||||
private List<Suggestion> makeSuggestions(String... pkgNames) {
|
||||
final List<Suggestion> suggestions = new ArrayList<>();
|
||||
for (String pkgName : pkgNames) {
|
||||
final Suggestion suggestion = new Suggestion.Builder(pkgName)
|
||||
.setPendingIntent(mock(PendingIntent.class))
|
||||
.build();
|
||||
suggestions.add(suggestion);
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
}
|
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.dashboard.suggestions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.suggestions.SuggestionControllerMixin;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class SuggestionDismissControllerTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Context mContext;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private RecyclerView mRecyclerView;
|
||||
@Mock
|
||||
private SuggestionControllerMixin mSuggestionControllerMixin;
|
||||
@Mock
|
||||
private SuggestionDismissController.Callback mCallback;
|
||||
|
||||
private FakeFeatureFactory mFactory;
|
||||
private SuggestionDismissController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mFactory = FakeFeatureFactory.setupForTest();
|
||||
|
||||
when(mRecyclerView.getResources().getDimension(anyInt())).thenReturn(50F);
|
||||
|
||||
mController = new SuggestionDismissController(mContext, mRecyclerView,
|
||||
mSuggestionControllerMixin, mCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMove_alwaysReturnTrue() {
|
||||
assertThat(mController.onMove(null, null, null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSwipeDirs_isSuggestionTile_shouldReturnDirection() {
|
||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile);
|
||||
|
||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||
.isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSwipeDirs_isSuggestionTileCard_shouldReturnDirection() {
|
||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||
when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_with_button);
|
||||
|
||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||
.isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSwipeDirs_isNotSuggestionTile_shouldReturn0() {
|
||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||
when(vh.getItemViewType()).thenReturn(R.layout.condition_tile);
|
||||
|
||||
assertThat(mController.getSwipeDirs(mRecyclerView, vh))
|
||||
.isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSwiped_shouldTriggerDismissSuggestion() {
|
||||
final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
|
||||
when(mCallback.getSuggestionAt(anyInt())).thenReturn(
|
||||
new Suggestion.Builder("id").build());
|
||||
|
||||
mController.onSwiped(vh, ItemTouchHelper.START);
|
||||
|
||||
verify(mFactory.suggestionsFeatureProvider).dismissSuggestion(
|
||||
eq(mContext), eq(mSuggestionControllerMixin), nullable(Suggestion.class));
|
||||
verify(mCallback).onSuggestionDismissed(nullable(Suggestion.class));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user