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 17package com.android.settings.core; 18 19import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS; 20 21import static com.google.common.truth.Truth.assertThat; 22 23import android.content.Context; 24import android.content.res.XmlResourceParser; 25import android.os.Bundle; 26import android.text.TextUtils; 27import android.util.AttributeSet; 28import android.util.Xml; 29 30import com.android.settings.R; 31import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag; 32import com.android.settings.testutils.SettingsRobolectricTestRunner; 33 34import org.junit.Before; 35import org.junit.Test; 36import org.junit.runner.RunWith; 37import org.robolectric.RuntimeEnvironment; 38import org.robolectric.annotation.Config; 39import org.xmlpull.v1.XmlPullParser; 40import org.xmlpull.v1.XmlPullParserException; 41 42import java.io.IOException; 43import java.util.List; 44 45/** 46 * These tests use a series of preferences that have specific attributes which are sometimes 47 * uncommon (such as summaryOn). 48 * 49 * If changing a preference file breaks a test in this test file, please replace its reference 50 * with another preference with a matchin replacement attribute. 51 */ 52@RunWith(SettingsRobolectricTestRunner.class) 53public class PreferenceXmlParserUtilsTest { 54 55 private Context mContext; 56 57 @Before 58 public void setUp() { 59 mContext = RuntimeEnvironment.application; 60 } 61 62 @Test 63 public void testDataTitleValid_ReturnsPreferenceTitle() { 64 XmlResourceParser parser = getChildByType(R.xml.display_settings, 65 "com.android.settings.TimeoutListPreference"); 66 final AttributeSet attrs = Xml.asAttributeSet(parser); 67 String title = PreferenceXmlParserUtils.getDataTitle(mContext, attrs); 68 String expTitle = mContext.getString(R.string.screen_timeout); 69 assertThat(title).isEqualTo(expTitle); 70 } 71 72 @Test 73 public void testDataKeywordsValid_ReturnsPreferenceKeywords() { 74 XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings); 75 final AttributeSet attrs = Xml.asAttributeSet(parser); 76 String keywords = PreferenceXmlParserUtils.getDataKeywords(mContext, attrs); 77 String expKeywords = mContext.getString(R.string.keywords_display); 78 assertThat(keywords).isEqualTo(expKeywords); 79 } 80 81 @Test 82 public void testDataKeyValid_ReturnsPreferenceKey() { 83 XmlResourceParser parser = getChildByType(R.xml.display_settings, 84 "com.android.settings.TimeoutListPreference"); 85 final AttributeSet attrs = Xml.asAttributeSet(parser); 86 String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs); 87 String expKey = "screen_timeout"; 88 assertThat(key).isEqualTo(expKey); 89 } 90 91 @Test 92 public void testDataSummaryValid_ReturnsPreferenceSummary() { 93 XmlResourceParser parser = getChildByType(R.xml.display_settings, 94 "com.android.settings.TimeoutListPreference"); 95 final AttributeSet attrs = Xml.asAttributeSet(parser); 96 String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs); 97 String expSummary = mContext.getString(R.string.summary_placeholder); 98 assertThat(summary).isEqualTo(expSummary); 99 } 100 101 @Test 102 @Config(qualifiers = "mcc999") 103 public void testDataSummaryOnOffValid_ReturnsPreferenceSummaryOnOff() { 104 XmlResourceParser parser = getChildByType(R.xml.display_settings, "CheckBoxPreference"); 105 final AttributeSet attrs = Xml.asAttributeSet(parser); 106 107 assertThat(PreferenceXmlParserUtils.getDataSummaryOn(mContext, attrs)) 108 .isEqualTo("summary_on"); 109 assertThat(PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs)) 110 .isEqualTo("summary_off"); 111 } 112 113 @Test 114 @Config(qualifiers = "mcc999") 115 public void testDataEntriesValid_ReturnsPreferenceEntries() { 116 XmlResourceParser parser = getChildByType(R.xml.display_settings, "ListPreference"); 117 final AttributeSet attrs = Xml.asAttributeSet(parser); 118 String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs); 119 String[] expEntries = mContext.getResources() 120 .getStringArray(R.array.app_install_location_entries); 121 for (String expEntry : expEntries) { 122 assertThat(entries).contains(expEntry); 123 } 124 } 125 126 // Null checks 127 @Test 128 @Config(qualifiers = "mcc999") 129 public void testDataKeyInvalid_ReturnsNull() { 130 XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings); 131 final AttributeSet attrs = Xml.asAttributeSet(parser); 132 String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs); 133 assertThat(key).isNull(); 134 } 135 136 @Test 137 @Config(qualifiers = "mcc999") 138 public void testControllerAttribute_returnsValidData() { 139 XmlResourceParser parser = getChildByType(R.xml.about_legal, "Preference"); 140 final AttributeSet attrs = Xml.asAttributeSet(parser); 141 142 String controller = PreferenceXmlParserUtils.getController(mContext, attrs); 143 assertThat(controller).isEqualTo("mind_flayer"); 144 } 145 146 @Test 147 public void testDataSummaryInvalid_ReturnsNull() { 148 XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings); 149 final AttributeSet attrs = Xml.asAttributeSet(parser); 150 String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs); 151 assertThat(summary).isNull(); 152 } 153 154 @Test 155 public void testDataSummaryOffInvalid_ReturnsNull() { 156 XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings); 157 final AttributeSet attrs = Xml.asAttributeSet(parser); 158 String summaryOff = PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs); 159 assertThat(summaryOff).isNull(); 160 } 161 162 @Test 163 public void testDataEntriesInvalid_ReturnsNull() { 164 XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings); 165 final AttributeSet attrs = Xml.asAttributeSet(parser); 166 String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs); 167 assertThat(entries).isNull(); 168 } 169 170 @Test 171 @Config(qualifiers = "mcc999") 172 public void extractMetadata_shouldContainKeyAndControllerName() 173 throws IOException, XmlPullParserException { 174 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 175 R.xml.location_settings, 176 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER); 177 178 assertThat(metadata).isNotEmpty(); 179 for (Bundle bundle : metadata) { 180 assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_KEY)).isNotNull(); 181 assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_CONTROLLER)).isNotNull(); 182 } 183 } 184 185 @Test 186 @Config(qualifiers = "mcc999") 187 public void extractMetadata_requestTitle_shouldContainTitle() 188 throws IOException, XmlPullParserException { 189 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 190 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_TITLE); 191 for (Bundle bundle : metadata) { 192 assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_TITLE)).isNotNull(); 193 } 194 } 195 196 @Test 197 @Config(qualifiers = "mcc999") 198 public void extractMetadata_requestSummary_shouldContainSummary() 199 throws IOException, XmlPullParserException { 200 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 201 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_SUMMARY); 202 for (Bundle bundle : metadata) { 203 assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_SUMMARY)).isNotNull(); 204 } 205 } 206 207 @Test 208 @Config(qualifiers = "mcc999") 209 public void extractMetadata_requestIcon_shouldContainIcon() 210 throws IOException, XmlPullParserException { 211 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 212 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_ICON); 213 for (Bundle bundle : metadata) { 214 assertThat(bundle.getInt(PreferenceXmlParserUtils.METADATA_ICON)).isNotEqualTo(0); 215 } 216 } 217 218 @Test 219 @Config(qualifiers = "mcc999") 220 public void extractMetadata_requestPrefType_shouldContainPrefType() 221 throws IOException, XmlPullParserException { 222 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 223 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_TYPE); 224 for (Bundle bundle : metadata) { 225 assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE)).isNotNull(); 226 } 227 } 228 229 @Test 230 @Config(qualifiers = "mcc999") 231 public void extractMetadata_requestIncludeScreen_shouldContainScreen() 232 throws IOException, XmlPullParserException { 233 List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 234 R.xml.location_settings, 235 MetadataFlag.FLAG_NEED_PREF_TYPE | MetadataFlag.FLAG_INCLUDE_PREF_SCREEN); 236 237 boolean hasPreferenceScreen = false; 238 for (Bundle bundle : metadata) { 239 if (TextUtils.equals(bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE), 240 PreferenceXmlParserUtils.PREF_SCREEN_TAG)) { 241 hasPreferenceScreen = true; 242 break; 243 } 244 } 245 246 assertThat(hasPreferenceScreen).isTrue(); 247 } 248 249 @Test 250 @Config(qualifiers = "mcc999") 251 public void extractMetadata_requestIncludesKeywords_shouldContainKeywords() 252 throws IOException, XmlPullParserException { 253 final String expectedKeywords = "a, b, c"; 254 final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, 255 R.xml.location_settings, 256 MetadataFlag.FLAG_NEED_PREF_TYPE | MetadataFlag.FLAG_NEED_KEYWORDS); 257 final Bundle bundle = metadata.get(0); 258 259 final String keywords = bundle.getString(METADATA_KEYWORDS); 260 261 assertThat(keywords).isEqualTo(expectedKeywords); 262 } 263 264 /** 265 * @param resId the ID for the XML preference 266 * @return an XML resource parser that points to the start tag 267 */ 268 private XmlResourceParser getParentPrimedParser(int resId) { 269 XmlResourceParser parser = null; 270 try { 271 parser = mContext.getResources().getXml(resId); 272 273 int type; 274 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 275 && type != XmlPullParser.START_TAG) { 276 } 277 } catch (Exception e) { 278 279 } 280 return parser; 281 } 282 283 private XmlResourceParser getChildByType(int resId, String xmlType) { 284 XmlResourceParser parser = null; 285 try { 286 parser = mContext.getResources().getXml(resId); 287 288 int type; 289 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 290 && type != XmlPullParser.START_TAG) { 291 } 292 while (parser.getName() != xmlType && parser.next() != XmlPullParser.END_DOCUMENT) { 293 } 294 } catch (Exception e) { 295 296 } 297 return parser; 298 } 299} 300