1 /* 2 * Copyright (C) 2020 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 android.ext.services.autofill; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.testng.Assert.assertThrows; 23 24 import android.app.PendingIntent; 25 import android.app.slice.Slice; 26 import android.app.slice.SliceSpec; 27 import android.content.Intent; 28 import android.content.IntentSender; 29 import android.net.Uri; 30 import android.os.Bundle; 31 import android.service.autofill.InlinePresentation; 32 import android.util.Size; 33 import android.view.View; 34 import android.widget.inline.InlinePresentationSpec; 35 36 import androidx.autofill.inline.UiVersions; 37 import androidx.autofill.inline.UiVersions.StylesBuilder; 38 import androidx.autofill.inline.v1.InlineSuggestionUi; 39 import androidx.autofill.inline.v1.InlineSuggestionUi.Content; 40 import androidx.test.core.app.ApplicationProvider; 41 42 import org.junit.Test; 43 import org.mockito.Mockito; 44 45 /** 46 * Contains the base tests that does not rely on the specific algorithm implementation. 47 */ 48 public class InlineSuggestionRenderServiceImplTest { 49 // TODO(b/187376476): improve naming and add more tests for Slice with correct version but 50 // no PendingIntent. 51 // Different inline presentation use cases. 52 private static final InlinePresentation INLINE_PRESENTATION_WITH_STYLE_AND_INTENT = 53 new InlinePresentation(createAttributionIntentSlice(), 54 createSpecWithStyle(), true); 55 private static final InlinePresentation INLINE_PRESENTATION_WITH_STYLE_NO_INTENT = 56 new InlinePresentation(createNoAttributionIntentSlice(), 57 createSpecWithStyle(), true); 58 private static final InlinePresentation INLINE_PRESENTATION_NO_STYLE_NO_INTENT = 59 new InlinePresentation(createNoAttributionIntentSlice(), 60 createSpecWithoutStyle(), true); 61 private static final InlinePresentation INLINE_PRESENTATION_NO_STYLE_WITH_INTENT = 62 new InlinePresentation(createAttributionIntentSlice(), 63 createSpecWithoutStyle(), true); 64 65 private final InlineSuggestionRenderServiceImpl mService = 66 new InlineSuggestionRenderServiceImpl(); 67 68 @Test testOnGetInlineSuggestionsRendererInfo()69 public void testOnGetInlineSuggestionsRendererInfo() { 70 assertThat(mService.onGetInlineSuggestionsRendererInfo()).isNotNull(); 71 } 72 73 @Test testOnRenderSuggestion_nullPresentation()74 public void testOnRenderSuggestion_nullPresentation() { 75 assertThrows(NullPointerException.class, 76 () -> mService.onRenderSuggestion(/* presentation */ null, 0, 0)); 77 } 78 79 @Test testOnRenderSuggestion_hasStyleHasAttributionIntentInlinePresentation()80 public void testOnRenderSuggestion_hasStyleHasAttributionIntentInlinePresentation() { 81 InlineSuggestionRenderServiceImpl spyService = Mockito.spy(mService); 82 spyService.attachBaseContext(ApplicationProvider.getApplicationContext()); 83 84 View view = spyService.onRenderSuggestion( 85 INLINE_PRESENTATION_WITH_STYLE_AND_INTENT, /* width= */ 0, /* height= */ 0); 86 assertThat(view).isNotNull(); 87 88 view.performLongClick(); 89 // TODO(b/187376476): verify startIntentSender() parameter value. 90 Mockito.verify(spyService, Mockito.times(1)).startIntentSender(any(IntentSender.class)); 91 } 92 93 @Test testOnRenderSuggestion_noStyleNoAttributionIntentInlinePresentation()94 public void testOnRenderSuggestion_noStyleNoAttributionIntentInlinePresentation() { 95 assertThat(mService.onRenderSuggestion(INLINE_PRESENTATION_NO_STYLE_NO_INTENT, /* width= */ 96 0, /* height= */0)).isNull(); 97 } 98 99 @Test testOnRenderSuggestion_noStyleHasAttributionIntentInlinePresentation()100 public void testOnRenderSuggestion_noStyleHasAttributionIntentInlinePresentation() { 101 assertThat( 102 mService.onRenderSuggestion(INLINE_PRESENTATION_NO_STYLE_WITH_INTENT, /* width= */ 103 0, /* height= */0)).isNull(); 104 } 105 106 @Test testOnRenderSuggestion_hasStyleNoAttributionIntentInlinePresentation()107 public void testOnRenderSuggestion_hasStyleNoAttributionIntentInlinePresentation() { 108 assertThat( 109 mService.onRenderSuggestion(INLINE_PRESENTATION_WITH_STYLE_NO_INTENT, /* width= */ 110 0, /* height= */ 0)).isNull(); 111 } 112 createSpecWithoutStyle()113 private static InlinePresentationSpec createSpecWithoutStyle() { 114 return createInlinePresentationSpec(null); 115 } 116 createSpecWithStyle()117 private static InlinePresentationSpec createSpecWithStyle() { 118 StylesBuilder stylesBuilder = UiVersions.newStylesBuilder(); 119 stylesBuilder.addStyle(InlineSuggestionUi.newStyleBuilder().build()); 120 return createInlinePresentationSpec(stylesBuilder.build()); 121 } 122 createInlinePresentationSpec(Bundle styles)123 private static InlinePresentationSpec createInlinePresentationSpec(Bundle styles) { 124 InlinePresentationSpec.Builder specBuilder = new InlinePresentationSpec.Builder( 125 new Size(100, 100), new Size(400, 100)); 126 if (styles != null) { 127 specBuilder.setStyle(styles); 128 } 129 return specBuilder.build(); 130 } 131 createNoAttributionIntentSlice()132 private static Slice createNoAttributionIntentSlice() { 133 return new Slice.Builder(Uri.parse("testuri"), new SliceSpec("type", 1)).build(); 134 } 135 createAttributionIntentSlice()136 private static Slice createAttributionIntentSlice() { 137 PendingIntent attribution = createAttribution(); 138 Content.Builder builder = InlineSuggestionUi.newContentBuilder(attribution); 139 builder.setTitle("title").setSubtitle("subtitle"); 140 return builder.build().getSlice(); 141 } 142 createAttribution()143 private static PendingIntent createAttribution() { 144 PendingIntent pendingIntent = PendingIntent.getActivity( 145 ApplicationProvider.getApplicationContext(), 0, new Intent(), 146 PendingIntent.FLAG_MUTABLE); 147 return pendingIntent; 148 } 149 } 150