1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.settings.search; 16 17 import static org.mockito.ArgumentMatchers.any; 18 import static org.mockito.ArgumentMatchers.eq; 19 import static org.mockito.Mockito.atLeast; 20 import static org.mockito.Mockito.doAnswer; 21 import static org.mockito.Mockito.doNothing; 22 import static org.mockito.Mockito.doReturn; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.times; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.app.Activity; 30 import android.content.ContentResolver; 31 import android.net.Uri; 32 33 import com.android.settings.slices.SettingsSliceProvider; 34 import com.android.settings.testutils.FakeFeatureFactory; 35 import com.android.settings.testutils.SettingsRobolectricTestRunner; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 import org.mockito.invocation.InvocationOnMock; 41 import org.mockito.stubbing.Answer; 42 import org.robolectric.Robolectric; 43 44 import java.util.ArrayList; 45 import java.util.List; 46 47 import androidx.slice.Slice; 48 import androidx.slice.SliceViewManager; 49 import androidx.slice.SliceMetadata; 50 51 @RunWith(SettingsRobolectricTestRunner.class) 52 public class DeviceIndexUpdateJobServiceTest { 53 private static final Uri BASE_URI = new Uri.Builder() 54 .scheme(ContentResolver.SCHEME_CONTENT) 55 .authority(SettingsSliceProvider.SLICE_AUTHORITY) 56 .build(); 57 58 private Activity mActivity; 59 private DeviceIndexUpdateJobService mJob; 60 private SliceViewManager mSliceManager; 61 62 @Before setup()63 public void setup() { 64 FakeFeatureFactory.setupForTest(); 65 mActivity = spy(Robolectric.buildActivity(Activity.class).create().visible().get()); 66 mJob = spy(new DeviceIndexUpdateJobService()); 67 mSliceManager = mock(SliceViewManager.class); 68 69 doReturn(mActivity.getPackageName()).when(mJob).getPackageName(); 70 doReturn(mSliceManager).when(mJob).getSliceViewManager(); 71 doNothing().when(mJob).jobFinished(null, false); 72 } 73 74 @Test testGetsSlices()75 public void testGetsSlices() { 76 setSlices(); 77 78 mJob.updateIndex(null); 79 verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); 80 } 81 82 @Test testIndexesSlices()83 public void testIndexesSlices() { 84 setSlices(genSlice("path1"), genSlice("path2")); 85 86 mJob.mRunningJob = true; 87 mJob.updateIndex(null); 88 verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); 89 90 DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) 91 .getDeviceIndexFeatureProvider(); 92 verify(indexFeatureProvider, times(2)).index(any(), any(), any(), any(), any()); 93 } 94 95 @Test testDoNotIndexWithoutTitle()96 public void testDoNotIndexWithoutTitle() { 97 Slice testSlice = genSlice("path2"); 98 setSlices(genSlice("path1"), testSlice); 99 doReturn(null).when(mJob).findTitle(testSlice, mJob.getMetadata(testSlice)); 100 101 mJob.mRunningJob = true; 102 mJob.updateIndex(null); 103 verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); 104 105 DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) 106 .getDeviceIndexFeatureProvider(); 107 verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any()); 108 } 109 110 @Test testStopIndexing()111 public void testStopIndexing() { 112 Slice testSlice = genSlice("path1"); 113 setSlices(testSlice, genSlice("path2")); 114 mJob.mRunningJob = true; 115 116 doAnswer(invocation -> { 117 // Stop running after the first iteration 118 mJob.mRunningJob = false; 119 return testSlice; 120 }).when(mJob).bindSliceSynchronous(mSliceManager, testSlice.getUri()); 121 122 mJob.updateIndex(null); 123 verify(mSliceManager).getSliceDescendants(eq(BASE_URI)); 124 125 DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity) 126 .getDeviceIndexFeatureProvider(); 127 verify(indexFeatureProvider).clearIndex(any()); 128 verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any()); 129 } 130 genSlice(String path)131 private Slice genSlice(String path) { 132 return new Slice.Builder(BASE_URI.buildUpon().path(path).build()).build(); 133 } 134 setSlices(Slice... slice)135 private void setSlices(Slice... slice) { 136 List<Uri> mUris = new ArrayList<>(); 137 for (Slice slouse : slice) { 138 SliceMetadata m = mock(SliceMetadata.class); 139 mUris.add(slouse.getUri()); 140 doReturn(slouse).when(mJob).bindSliceSynchronous(mSliceManager, slouse.getUri()); 141 doReturn(m).when(mJob).getMetadata(slouse); 142 doReturn(slouse.getUri().getPath()).when(mJob).findTitle(slouse, m); 143 } 144 when(mSliceManager.getSliceDescendants(BASE_URI)).thenReturn(mUris); 145 } 146 147 } 148