1 /* 2 * Copyright (C) 2022 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.intentresolver 18 19 import com.google.common.truth.Truth.assertThat 20 import org.junit.Test 21 22 /** 23 * Unit tests for the various implementations of {@link TargetPresentationGetter}. 24 * 25 * TODO: consider expanding to cover icon logic (not just labels/sublabels). 26 * TODO: these are conceptually "acceptance tests" that provide comprehensive coverage of the 27 * apparent variations in the legacy implementation. The tests probably don't have to be so 28 * exhaustive if we're able to impose a simpler design on the implementation. 29 */ 30 class TargetPresentationGetterTest { makeResolveInfoPresentationGetternull31 fun makeResolveInfoPresentationGetter( 32 withSubstitutePermission: Boolean, 33 appLabel: String, 34 activityLabel: String, 35 resolveInfoLabel: String 36 ): TargetPresentationGetter { 37 val testPackageInfo = 38 ResolverDataProvider.createPackageManagerMockedInfo( 39 withSubstitutePermission, 40 appLabel, 41 activityLabel, 42 resolveInfoLabel 43 ) 44 val factory = TargetPresentationGetter.Factory(testPackageInfo.ctx, 100) 45 return factory.makePresentationGetter(testPackageInfo.resolveInfo) 46 } 47 makeActivityInfoPresentationGetternull48 fun makeActivityInfoPresentationGetter( 49 withSubstitutePermission: Boolean, 50 appLabel: String?, 51 activityLabel: String? 52 ): TargetPresentationGetter { 53 val testPackageInfo = 54 ResolverDataProvider.createPackageManagerMockedInfo( 55 withSubstitutePermission, 56 appLabel, 57 activityLabel, 58 "" 59 ) 60 val factory = TargetPresentationGetter.Factory(testPackageInfo.ctx, 100) 61 return factory.makePresentationGetter(testPackageInfo.activityInfo) 62 } 63 64 @Test testActivityInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabelnull65 fun testActivityInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabel() { 66 val presentationGetter = 67 makeActivityInfoPresentationGetter(false, "app_label", "activity_label") 68 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 69 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 70 } 71 72 @Test testActivityInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabelnull73 fun testActivityInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabel() { 74 val presentationGetter = makeActivityInfoPresentationGetter(false, "app_label", "app_label") 75 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 76 // Without the substitute permission, there's no logic to dedupe the labels. 77 // TODO: this matches our observations in the legacy code, but is it the right behavior? It 78 // seems like {@link ResolverListAdapter.ViewHolder#bindLabel()} has some logic to dedupe in 79 // the UI at least, but maybe that logic should be pulled back to the "presentation"? 80 assertThat(presentationGetter.getSubLabel()).isEqualTo("app_label") 81 } 82 83 @Test testActivityInfoLabels_noSubstitutePermission_nullRequestedLabelnull84 fun testActivityInfoLabels_noSubstitutePermission_nullRequestedLabel() { 85 val presentationGetter = makeActivityInfoPresentationGetter(false, null, "activity_label") 86 assertThat(presentationGetter.getLabel()).isNull() 87 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 88 } 89 90 @Test testActivityInfoLabels_noSubstitutePermission_emptyRequestedLabelnull91 fun testActivityInfoLabels_noSubstitutePermission_emptyRequestedLabel() { 92 val presentationGetter = makeActivityInfoPresentationGetter(false, "", "activity_label") 93 assertThat(presentationGetter.getLabel()).isEqualTo("") 94 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 95 } 96 97 @Test testActivityInfoLabels_noSubstitutePermission_emptyRequestedSublabelnull98 fun testActivityInfoLabels_noSubstitutePermission_emptyRequestedSublabel() { 99 val presentationGetter = makeActivityInfoPresentationGetter(false, "app_label", "") 100 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 101 // Without the substitute permission, empty sublabels are passed through as-is. 102 assertThat(presentationGetter.getSubLabel()).isEqualTo("") 103 } 104 105 @Test testActivityInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabelnull106 fun testActivityInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabel() { 107 val presentationGetter = 108 makeActivityInfoPresentationGetter(true, "app_label", "activity_label") 109 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 110 // With the substitute permission, the same ("activity") label is requested as both the 111 // label 112 // and sublabel, even though the other value ("app_label") was distinct. Thus this behaves 113 // the 114 // same as a dupe. 115 assertThat(presentationGetter.getSubLabel()).isEqualTo(null) 116 } 117 118 @Test testActivityInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabelnull119 fun testActivityInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabel() { 120 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", "app_label") 121 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 122 // With the substitute permission, duped sublabels get converted to nulls. 123 assertThat(presentationGetter.getSubLabel()).isNull() 124 } 125 126 @Test testActivityInfoLabels_withSubstitutePermission_nullRequestedLabelnull127 fun testActivityInfoLabels_withSubstitutePermission_nullRequestedLabel() { 128 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", null) 129 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 130 // With the substitute permission, null inputs are a special case that produces null outputs 131 // (i.e., they're not simply passed-through from the inputs). 132 assertThat(presentationGetter.getSubLabel()).isNull() 133 } 134 135 @Test testActivityInfoLabels_withSubstitutePermission_emptyRequestedLabelnull136 fun testActivityInfoLabels_withSubstitutePermission_emptyRequestedLabel() { 137 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", "") 138 // Empty "labels" are taken as-is and (unlike nulls) don't prompt a fallback to the 139 // sublabel. 140 // Thus (as in the previous case with substitute permission & "distinct" labels), this is 141 // treated as a dupe. 142 assertThat(presentationGetter.getLabel()).isEqualTo("") 143 assertThat(presentationGetter.getSubLabel()).isNull() 144 } 145 146 @Test testActivityInfoLabels_withSubstitutePermission_emptyRequestedSublabelnull147 fun testActivityInfoLabels_withSubstitutePermission_emptyRequestedSublabel() { 148 val presentationGetter = makeActivityInfoPresentationGetter(true, "", "activity_label") 149 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 150 // With the substitute permission, empty sublabels get converted to nulls. 151 assertThat(presentationGetter.getSubLabel()).isNull() 152 } 153 154 @Test testResolveInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabelnull155 fun testResolveInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabel() { 156 val presentationGetter = 157 makeResolveInfoPresentationGetter( 158 false, 159 "app_label", 160 "activity_label", 161 "resolve_info_label" 162 ) 163 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 164 assertThat(presentationGetter.getSubLabel()).isEqualTo("resolve_info_label") 165 } 166 167 @Test testResolveInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabelnull168 fun testResolveInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabel() { 169 val presentationGetter = 170 makeResolveInfoPresentationGetter(false, "app_label", "activity_label", "app_label") 171 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 172 // Without the substitute permission, there's no logic to dedupe the labels. 173 // TODO: this matches our observations in the legacy code, but is it the right behavior? It 174 // seems like {@link ResolverListAdapter.ViewHolder#bindLabel()} has some logic to dedupe in 175 // the UI at least, but maybe that logic should be pulled back to the "presentation"? 176 assertThat(presentationGetter.getSubLabel()).isEqualTo("app_label") 177 } 178 179 @Test testResolveInfoLabels_noSubstitutePermission_emptyRequestedSublabelnull180 fun testResolveInfoLabels_noSubstitutePermission_emptyRequestedSublabel() { 181 val presentationGetter = 182 makeResolveInfoPresentationGetter(false, "app_label", "activity_label", "") 183 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 184 // Without the substitute permission, empty sublabels are passed through as-is. 185 assertThat(presentationGetter.getSubLabel()).isEqualTo("") 186 } 187 188 @Test testResolveInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabelnull189 fun testResolveInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabel() { 190 val presentationGetter = 191 makeResolveInfoPresentationGetter( 192 true, 193 "app_label", 194 "activity_label", 195 "resolve_info_label" 196 ) 197 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 198 assertThat(presentationGetter.getSubLabel()).isEqualTo("resolve_info_label") 199 } 200 201 @Test testResolveInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabelnull202 fun testResolveInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabel() { 203 val presentationGetter = 204 makeResolveInfoPresentationGetter(true, "app_label", "activity_label", "activity_label") 205 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 206 // With the substitute permission, duped sublabels get converted to nulls. 207 assertThat(presentationGetter.getSubLabel()).isNull() 208 } 209 210 @Test testResolveInfoLabels_withSubstitutePermission_emptyRequestedSublabelnull211 fun testResolveInfoLabels_withSubstitutePermission_emptyRequestedSublabel() { 212 val presentationGetter = 213 makeResolveInfoPresentationGetter(true, "app_label", "activity_label", "") 214 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 215 // With the substitute permission, empty sublabels get converted to nulls. 216 assertThat(presentationGetter.getSubLabel()).isNull() 217 } 218 219 @Test testResolveInfoLabels_withSubstitutePermission_emptyRequestedLabelAndSublabelnull220 fun testResolveInfoLabels_withSubstitutePermission_emptyRequestedLabelAndSublabel() { 221 val presentationGetter = makeResolveInfoPresentationGetter(true, "app_label", "", "") 222 assertThat(presentationGetter.getLabel()).isEqualTo("") 223 // With the substitute permission, empty sublabels get converted to nulls. 224 assertThat(presentationGetter.getSubLabel()).isNull() 225 } 226 } 227