1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.panel; 18 19 import static com.android.settings.panel.PanelContent.VIEW_TYPE_SLIDER; 20 import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES; 21 import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.content.Context; 34 import android.net.Uri; 35 import android.view.LayoutInflater; 36 import android.view.ViewGroup; 37 import android.widget.FrameLayout; 38 39 import androidx.lifecycle.LiveData; 40 import androidx.slice.Slice; 41 42 import com.android.settings.R; 43 import com.android.settings.panel.PanelSlicesAdapter.SliceRowViewHolder; 44 import com.android.settings.testutils.FakeFeatureFactory; 45 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.mockito.ArgumentCaptor; 50 import org.mockito.MockitoAnnotations; 51 import org.robolectric.Robolectric; 52 import org.robolectric.RobolectricTestRunner; 53 import org.robolectric.RuntimeEnvironment; 54 import org.robolectric.android.controller.ActivityController; 55 import org.robolectric.annotation.Config; 56 import org.robolectric.annotation.Implementation; 57 import org.robolectric.annotation.Implements; 58 59 import java.util.LinkedHashMap; 60 import java.util.Map; 61 62 @RunWith(RobolectricTestRunner.class) 63 @Config(shadows = PanelSlicesAdapterTest.ShadowLayoutInflater.class) 64 public class PanelSlicesAdapterTest { 65 66 private static LayoutInflater sLayoutInflater; 67 68 private Context mContext; 69 private PanelFragment mPanelFragment; 70 private PanelFeatureProvider mPanelFeatureProvider; 71 private FakeFeatureFactory mFakeFeatureFactory; 72 private FakePanelContent mFakePanelContent; 73 private Map<Uri, LiveData<Slice>> mData = new LinkedHashMap<>(); 74 75 @Before setUp()76 public void setUp() { 77 MockitoAnnotations.initMocks(this); 78 mContext = RuntimeEnvironment.application; 79 80 mPanelFeatureProvider = spy(new PanelFeatureProviderImpl()); 81 mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); 82 mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider; 83 mFakePanelContent = new FakePanelContent(); 84 doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any()); 85 86 ActivityController<FakeSettingsPanelActivity> activityController = 87 Robolectric.buildActivity(FakeSettingsPanelActivity.class); 88 activityController.setup(); 89 90 mPanelFragment = 91 spy((PanelFragment) 92 activityController 93 .get() 94 .getSupportFragmentManager() 95 .findFragmentById(R.id.main_content)); 96 97 } 98 addTestLiveData(Uri uri)99 private void addTestLiveData(Uri uri) { 100 // Create a slice to return for the LiveData 101 final Slice slice = spy(new Slice()); 102 doReturn(uri).when(slice).getUri(); 103 final LiveData<Slice> liveData = mock(LiveData.class); 104 when(liveData.getValue()).thenReturn(slice); 105 mData.put(uri, liveData); 106 } 107 108 @Test sizeOfAdapter_shouldNotExceedMaxNum()109 public void sizeOfAdapter_shouldNotExceedMaxNum() { 110 for (int i = 0; i < MAX_NUM_OF_SLICES + 2; i++) { 111 addTestLiveData(Uri.parse("uri" + i)); 112 } 113 114 assertThat(mData.size()).isEqualTo(MAX_NUM_OF_SLICES + 2); 115 116 final PanelSlicesAdapter adapter = 117 new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); 118 final ViewGroup view = new FrameLayout(mContext); 119 final SliceRowViewHolder viewHolder = 120 adapter.onCreateViewHolder(view, 0); 121 122 assertThat(adapter.getItemCount()).isEqualTo(MAX_NUM_OF_SLICES); 123 assertThat(adapter.getData().size()).isEqualTo(MAX_NUM_OF_SLICES); 124 } 125 126 @Test mediaOutputIndicatorSlice_notSliderPanel_noSliderLayout()127 public void mediaOutputIndicatorSlice_notSliderPanel_noSliderLayout() { 128 addTestLiveData(MEDIA_OUTPUT_INDICATOR_SLICE_URI); 129 130 final PanelSlicesAdapter adapter = 131 new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); 132 final int position = 0; 133 final ViewGroup view = new FrameLayout(mContext); 134 final SliceRowViewHolder viewHolder = 135 adapter.onCreateViewHolder(view, 0 /* view type*/); 136 137 adapter.onBindViewHolder(viewHolder, position); 138 139 assertThat(viewHolder.mSliceSliderLayout).isNull(); 140 } 141 142 @Test onCreateViewHolder_viewTypeSlider_verifyLayout()143 public void onCreateViewHolder_viewTypeSlider_verifyLayout() { 144 final PanelSlicesAdapter adapter = 145 new PanelSlicesAdapter(mPanelFragment, mData, 0); 146 final ViewGroup view = new FrameLayout(mContext); 147 final ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class); 148 149 adapter.onCreateViewHolder(view, VIEW_TYPE_SLIDER); 150 151 verify(sLayoutInflater).inflate(intArgumentCaptor.capture(), eq(view), eq(false)); 152 assertThat(intArgumentCaptor.getValue()).isEqualTo(R.layout.panel_slice_slider_row); 153 } 154 155 @Test onCreateViewHolder_viewTypeDefault_verifyLayout()156 public void onCreateViewHolder_viewTypeDefault_verifyLayout() { 157 final PanelSlicesAdapter adapter = 158 new PanelSlicesAdapter(mPanelFragment, mData, 0); 159 final ViewGroup view = new FrameLayout(mContext); 160 final ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class); 161 162 adapter.onCreateViewHolder(view, 0); 163 164 verify(sLayoutInflater).inflate(intArgumentCaptor.capture(), eq(view), eq(false)); 165 assertThat(intArgumentCaptor.getValue()).isEqualTo(R.layout.panel_slice_row); 166 } 167 168 @Implements(LayoutInflater.class) 169 public static class ShadowLayoutInflater { 170 171 @Implementation from(Context context)172 public static LayoutInflater from(Context context) { 173 final LayoutInflater inflater = 174 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 175 if (inflater == null) { 176 throw new AssertionError("LayoutInflater not found."); 177 } 178 sLayoutInflater = spy(inflater); 179 return sLayoutInflater; 180 } 181 } 182 } 183