• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.core;
18 
19 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_APPEND;
20 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
21 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
22 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SEARCHABLE;
23 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_UNAVAILABLE_SLICE_SUBTITLE;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import android.content.Context;
28 import android.content.res.XmlResourceParser;
29 import android.os.Bundle;
30 import android.text.TextUtils;
31 import android.util.AttributeSet;
32 import android.util.Xml;
33 
34 import com.android.settings.R;
35 import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
36 
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.robolectric.RobolectricTestRunner;
41 import org.robolectric.RuntimeEnvironment;
42 import org.robolectric.annotation.Config;
43 import org.xmlpull.v1.XmlPullParser;
44 import org.xmlpull.v1.XmlPullParserException;
45 
46 import java.io.IOException;
47 import java.util.List;
48 import java.util.Objects;
49 
50 /**
51  * These tests use a series of preferences that have specific attributes which are sometimes
52  * uncommon (such as summaryOn).
53  *
54  * If changing a preference file breaks a test in this test file, please replace its reference
55  * with another preference with a matchin replacement attribute.
56  */
57 @RunWith(RobolectricTestRunner.class)
58 public class PreferenceXmlParserUtilsTest {
59 
60     private Context mContext;
61 
62     @Before
setUp()63     public void setUp() {
64         mContext = RuntimeEnvironment.application;
65     }
66 
67     @Test
testDataTitleValid_ReturnsPreferenceTitle()68     public void testDataTitleValid_ReturnsPreferenceTitle() {
69         XmlResourceParser parser = getChildByType(R.xml.display_settings,
70                 "com.android.settings.display.TimeoutListPreference");
71         final AttributeSet attrs = Xml.asAttributeSet(parser);
72         String title = PreferenceXmlParserUtils.getDataTitle(mContext, attrs);
73         String expTitle = mContext.getString(R.string.screen_timeout);
74         assertThat(title).isEqualTo(expTitle);
75     }
76 
77     @Test
testDataKeywordsValid_ReturnsPreferenceKeywords()78     public void testDataKeywordsValid_ReturnsPreferenceKeywords() {
79         XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
80         final AttributeSet attrs = Xml.asAttributeSet(parser);
81         String keywords = PreferenceXmlParserUtils.getDataKeywords(mContext, attrs);
82         String expKeywords = mContext.getString(R.string.keywords_display);
83         assertThat(keywords).isEqualTo(expKeywords);
84     }
85 
86     @Test
testDataKeyValid_ReturnsPreferenceKey()87     public void testDataKeyValid_ReturnsPreferenceKey() {
88         XmlResourceParser parser = getChildByType(R.xml.display_settings,
89                 "com.android.settings.display.TimeoutListPreference");
90         final AttributeSet attrs = Xml.asAttributeSet(parser);
91         String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs);
92         String expKey = "screen_timeout";
93         assertThat(key).isEqualTo(expKey);
94     }
95 
96     @Test
testDataSummaryValid_ReturnsPreferenceSummary()97     public void testDataSummaryValid_ReturnsPreferenceSummary() {
98         XmlResourceParser parser = getChildByType(R.xml.display_settings,
99                 "com.android.settings.display.TimeoutListPreference");
100         final AttributeSet attrs = Xml.asAttributeSet(parser);
101         String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs);
102         String expSummary = mContext.getString(R.string.summary_placeholder);
103         assertThat(summary).isEqualTo(expSummary);
104     }
105 
106     @Test
107     @Config(qualifiers = "mcc999")
testDataSummaryOnOffValid_ReturnsPreferenceSummaryOnOff()108     public void testDataSummaryOnOffValid_ReturnsPreferenceSummaryOnOff() {
109         XmlResourceParser parser = getChildByType(R.xml.display_settings, "CheckBoxPreference");
110         final AttributeSet attrs = Xml.asAttributeSet(parser);
111 
112         assertThat(PreferenceXmlParserUtils.getDataSummaryOn(mContext, attrs))
113                 .isEqualTo("summary_on");
114         assertThat(PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs))
115                 .isEqualTo("summary_off");
116     }
117 
118     @Test
119     @Config(qualifiers = "mcc999")
testDataEntriesValid_ReturnsPreferenceEntries()120     public void testDataEntriesValid_ReturnsPreferenceEntries() {
121         XmlResourceParser parser = getChildByType(R.xml.display_settings, "ListPreference");
122         final AttributeSet attrs = Xml.asAttributeSet(parser);
123         String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs);
124         String[] expEntries = mContext.getResources()
125                 .getStringArray(R.array.app_install_location_entries);
126         for (String expEntry : expEntries) {
127             assertThat(entries).contains(expEntry);
128         }
129     }
130 
131     // Null checks
132     @Test
133     @Config(qualifiers = "mcc999")
testDataKeyInvalid_ReturnsNull()134     public void testDataKeyInvalid_ReturnsNull() {
135         XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
136         final AttributeSet attrs = Xml.asAttributeSet(parser);
137         String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs);
138         assertThat(key).isNull();
139     }
140 
141     @Test
142     @Config(qualifiers = "mcc999")
testControllerAttribute_returnsValidData()143     public void testControllerAttribute_returnsValidData() {
144         XmlResourceParser parser = getChildByType(R.xml.about_legal, "Preference");
145         final AttributeSet attrs = Xml.asAttributeSet(parser);
146 
147         String controller = PreferenceXmlParserUtils.getController(mContext, attrs);
148         assertThat(controller).isEqualTo("mind_flayer");
149     }
150 
151     @Test
testDataSummaryInvalid_ReturnsNull()152     public void testDataSummaryInvalid_ReturnsNull() {
153         XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
154         final AttributeSet attrs = Xml.asAttributeSet(parser);
155         String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs);
156         assertThat(summary).isNull();
157     }
158 
159     @Test
testDataSummaryOffInvalid_ReturnsNull()160     public void testDataSummaryOffInvalid_ReturnsNull() {
161         XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
162         final AttributeSet attrs = Xml.asAttributeSet(parser);
163         String summaryOff = PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs);
164         assertThat(summaryOff).isNull();
165     }
166 
167     @Test
testDataEntriesInvalid_ReturnsNull()168     public void testDataEntriesInvalid_ReturnsNull() {
169         XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
170         final AttributeSet attrs = Xml.asAttributeSet(parser);
171         String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs);
172         assertThat(entries).isNull();
173     }
174 
175     @Test
176     @Config(qualifiers = "mcc999")
extractMetadata_shouldContainKeyAndControllerName()177     public void extractMetadata_shouldContainKeyAndControllerName()
178             throws IOException, XmlPullParserException {
179         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
180                 R.xml.location_settings,
181                 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
182 
183         assertThat(metadata).isNotEmpty();
184         for (Bundle bundle : metadata) {
185             assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_KEY)).isNotNull();
186             assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_CONTROLLER)).isNotNull();
187         }
188     }
189 
190     @Test
191     @Config(qualifiers = "mcc999")
extractMetadata_requestTitle_shouldContainTitle()192     public void extractMetadata_requestTitle_shouldContainTitle()
193             throws IOException, XmlPullParserException {
194         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
195                 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_TITLE);
196         for (Bundle bundle : metadata) {
197             assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_TITLE)).isNotNull();
198         }
199     }
200 
201     @Test
202     @Config(qualifiers = "mcc999")
extractMetadata_requestSummary_shouldContainSummary()203     public void extractMetadata_requestSummary_shouldContainSummary()
204             throws IOException, XmlPullParserException {
205         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
206                 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_SUMMARY);
207         for (Bundle bundle : metadata) {
208             assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_SUMMARY)).isNotNull();
209         }
210     }
211 
212     @Test
213     @Config(qualifiers = "mcc999")
extractMetadata_requestIcon_shouldContainIcon()214     public void extractMetadata_requestIcon_shouldContainIcon()
215             throws IOException, XmlPullParserException {
216         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
217                 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_ICON);
218         for (Bundle bundle : metadata) {
219             assertThat(bundle.getInt(PreferenceXmlParserUtils.METADATA_ICON)).isNotEqualTo(0);
220         }
221     }
222 
223     @Test
224     @Config(qualifiers = "mcc999")
extractMetadata_requestPrefType_shouldContainPrefType()225     public void extractMetadata_requestPrefType_shouldContainPrefType()
226             throws IOException, XmlPullParserException {
227         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
228                 R.xml.location_settings, MetadataFlag.FLAG_NEED_PREF_TYPE);
229         for (Bundle bundle : metadata) {
230             assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE)).isNotNull();
231         }
232     }
233 
234     @Test
235     @Config(qualifiers = "mcc999")
extractMetadata_requestIncludeScreen_shouldContainScreen()236     public void extractMetadata_requestIncludeScreen_shouldContainScreen()
237             throws IOException, XmlPullParserException {
238         List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
239                 R.xml.location_settings,
240                 MetadataFlag.FLAG_NEED_PREF_TYPE | MetadataFlag.FLAG_INCLUDE_PREF_SCREEN);
241 
242         boolean hasPreferenceScreen = false;
243         for (Bundle bundle : metadata) {
244             if (TextUtils.equals(bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE),
245                     PreferenceXmlParserUtils.PREF_SCREEN_TAG)) {
246                 hasPreferenceScreen = true;
247                 break;
248             }
249         }
250 
251         assertThat(hasPreferenceScreen).isTrue();
252     }
253 
254     @Test
255     @Config(qualifiers = "mcc999")
extractMetadata_requestIncludesKeywords_shouldContainKeywords()256     public void extractMetadata_requestIncludesKeywords_shouldContainKeywords() throws Exception {
257         final String expectedKeywords = "a, b, c";
258         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
259                 R.xml.location_settings,
260                 MetadataFlag.FLAG_NEED_PREF_TYPE | MetadataFlag.FLAG_NEED_KEYWORDS);
261         final Bundle bundle = metadata.get(0);
262 
263         final String keywords = bundle.getString(METADATA_KEYWORDS);
264 
265         assertThat(keywords).isEqualTo(expectedKeywords);
266     }
267 
268     @Test
269     @Config(qualifiers = "mcc998")
extractMetadata_requestSearchable_shouldDefaultToTrue()270     public void extractMetadata_requestSearchable_shouldDefaultToTrue() throws Exception {
271         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
272                 R.xml.location_settings, MetadataFlag.FLAG_NEED_SEARCHABLE);
273         for (Bundle bundle : metadata) {
274             assertThat(bundle.getBoolean(METADATA_SEARCHABLE)).isTrue();
275         }
276     }
277 
278     @Test
279     @Config(qualifiers = "mcc999")
extractMetadata_requestSearchable_shouldReturnAttributeValue()280     public void extractMetadata_requestSearchable_shouldReturnAttributeValue() throws Exception {
281         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
282                 R.xml.display_settings,
283                 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_SEARCHABLE);
284         boolean foundKey = false;
285         for (Bundle bundle : metadata) {
286             if (TextUtils.equals(bundle.getString(METADATA_KEY), "pref_key_5")) {
287                 assertThat(bundle.getBoolean(METADATA_SEARCHABLE)).isFalse();
288                 foundKey = true;
289                 break;
290             }
291         }
292         assertThat(foundKey).isTrue();
293     }
294 
295     @Test
296     @Config(qualifiers = "mcc999")
extractMetadata_requestAppendProperty_shouldDefaultToFalse()297     public void extractMetadata_requestAppendProperty_shouldDefaultToFalse()
298             throws Exception {
299         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
300                 R.xml.display_settings,
301                 MetadataFlag.FLAG_INCLUDE_PREF_SCREEN | MetadataFlag.FLAG_NEED_PREF_APPEND);
302 
303         for (Bundle bundle : metadata) {
304             assertThat(bundle.getBoolean(METADATA_APPEND)).isFalse();
305         }
306     }
307 
308     @Test
309     @Config(qualifiers = "mcc999")
extractMetadata_requestAppendProperty_shouldReturnCorrectValue()310     public void extractMetadata_requestAppendProperty_shouldReturnCorrectValue()
311             throws Exception {
312         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
313                 R.xml.battery_saver_schedule_settings,
314                 MetadataFlag.FLAG_INCLUDE_PREF_SCREEN | MetadataFlag.FLAG_NEED_PREF_APPEND);
315 
316         for (Bundle bundle : metadata) {
317             assertThat(bundle.getBoolean(METADATA_APPEND)).isTrue();
318         }
319     }
320 
321     @Test
322     @Config(qualifiers = "mcc999")
extractMetadata_requestUnavailableSliceSubtitle_shouldDefaultNull()323     public void extractMetadata_requestUnavailableSliceSubtitle_shouldDefaultNull()
324             throws Exception {
325         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
326                 R.xml.night_display_settings,
327                 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_UNAVAILABLE_SLICE_SUBTITLE);
328 
329         boolean bundleWithKey1Found = false;
330         for (Bundle bundle : metadata) {
331             if (bundle.getString(METADATA_KEY).equals("key1")) {
332                 assertThat(bundle.getString(METADATA_UNAVAILABLE_SLICE_SUBTITLE)).isNull();
333                 bundleWithKey1Found = true;
334                 break;
335             }
336         }
337         assertThat(bundleWithKey1Found).isTrue();
338     }
339 
340     @Test
341     @Config(qualifiers = "mcc999")
extractMetadata_requestUnavailableSliceSubtitle_shouldReturnAttributeValue()342     public void extractMetadata_requestUnavailableSliceSubtitle_shouldReturnAttributeValue()
343             throws Exception {
344         final String expectedSubtitle = "subtitleOfUnavailable";
345         final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
346                 R.xml.night_display_settings,
347                 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_UNAVAILABLE_SLICE_SUBTITLE);
348 
349         boolean bundleWithKey2Found = false;
350         for (Bundle bundle : metadata) {
351             if (bundle.getString(METADATA_KEY).equals("key2")) {
352                 assertThat(bundle.getString(METADATA_UNAVAILABLE_SLICE_SUBTITLE)).isEqualTo(
353                         expectedSubtitle);
354                 bundleWithKey2Found = true;
355                 break;
356             }
357         }
358         assertThat(bundleWithKey2Found).isTrue();
359     }
360 
361     /**
362      * @param resId the ID for the XML preference
363      * @return an XML resource parser that points to the start tag
364      */
getParentPrimedParser(int resId)365     private XmlResourceParser getParentPrimedParser(int resId) {
366         XmlResourceParser parser = null;
367         try {
368             parser = mContext.getResources().getXml(resId);
369 
370             int type;
371             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
372                     && type != XmlPullParser.START_TAG) {
373             }
374         } catch (Exception e) {
375 
376         }
377         return parser;
378     }
379 
getChildByType(int resId, String xmlType)380     private XmlResourceParser getChildByType(int resId, String xmlType) {
381         XmlResourceParser parser = null;
382         try {
383             parser = mContext.getResources().getXml(resId);
384 
385             int type;
386             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
387                     && type != XmlPullParser.START_TAG) {
388             }
389             while (true) {
390                 if (Objects.equals(parser.getName(), xmlType)) {
391                     break;
392                 }
393                 final int nextEvent = parser.next();
394                 if (nextEvent == XmlPullParser.END_DOCUMENT) {
395                     break;
396                 }
397             }
398         } catch (Exception e) {
399 
400         }
401         return parser;
402     }
403 }
404