1 package com.android.settings.search;
3 import android.content.Context;
4 import android.provider.SearchIndexableResource;
5 import android.util.ArraySet;
6 import com.android.settings.DateTimeSettings;
7 import com.android.settings.R;
8 import com.android.settings.SecuritySettings;
9 import com.android.settings.testutils.SettingsRobolectricTestRunner;
10 import com.android.settings.TestConfig;
11 import com.android.settings.core.codeinspection.CodeInspector;
12 import com.android.settings.datausage.DataUsageSummary;
13 import com.android.settings.testutils.XmlTestUtils;
14 import com.android.settings.testutils.shadow.SettingsShadowResources;
15 import org.junit.Test;
16 import org.junit.runner.RunWith;
17 import org.robolectric.RuntimeEnvironment;
18 import org.robolectric.annotation.Config;
20 import java.util.ArrayList;
21 import java.util.List;
24 import static com.google.common.truth.Truth.assertThat;
26 @RunWith(SettingsRobolectricTestRunner.class)
27 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
28 assetDir = "/tests/robotests/assets")
29 public class DataIntegrityTest {
33 SettingsShadowResources.class,
34 SettingsShadowResources.SettingsShadowTheme.class,
36 public void testIndexableResources_uniqueKeys() {
37 final Context context = RuntimeEnvironment.application;
38 // Aggregation of all keys
39 final Set<String> masterKeys = new ArraySet<>();
40 // Aggregation of the incorrectly duplicate keys
41 final Set<String> duplicateKeys = new ArraySet<>();
42 // Keys for a specific page
43 final Set<String> pageKeys = new ArraySet<>();
44 // List of all Xml preferences
45 final Set<Integer> xmlList = new ArraySet<>();
46 // Duplicates we know about.
47 List<String> grandfatheredKeys = new ArrayList<>();
48 CodeInspector.initializeGrandfatherList(grandfatheredKeys,
49 "whitelist_duplicate_index_key");
51 // Get a list of all Xml.
52 for (SearchIndexableResource val : SearchIndexableResources.values()) {
53 final int xmlResId = val.xmlResId;
55 xmlList.add(xmlResId);
57 // Take class and get all keys
58 final Class clazz = DatabaseIndexingUtils.getIndexableClass(val.className);
60 // Skip classes that are invalid or cannot be mocked. Add them as special Xml below.
62 || clazz == DateTimeSettings.class
63 || clazz == DataUsageSummary.class
64 || clazz == SecuritySettings.class) {
68 Indexable.SearchIndexProvider provider = DatabaseIndexingUtils
69 .getSearchIndexProvider(clazz);
71 if (provider == null) {
75 List<SearchIndexableResource> subXml =
76 provider.getXmlResourcesToIndex(context, true);
81 for (SearchIndexableResource resource : subXml) {
82 final int subXmlResId = resource.xmlResId;
83 if (subXmlResId != 0) {
84 xmlList.add(subXmlResId);
89 addSpecialXml(xmlList);
91 // Get keys from all Xml and check for duplicates.
92 for (Integer xmlResId : xmlList) {
93 // Get all keys to be indexed
94 final List<String> prefKeys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlResId);
95 pageKeys.addAll(prefKeys);
96 // Find all already-existing keys.
97 pageKeys.retainAll(masterKeys);
98 // Keep list of offending duplicate keys.
99 duplicateKeys.addAll(pageKeys);
100 // Add all keys to master key list.
101 masterKeys.addAll(prefKeys);
104 assertThat(duplicateKeys).containsExactlyElementsIn(grandfatheredKeys);
108 * Add XML preferences from Fragments which have issues being instantiated in robolectric.
110 private void addSpecialXml(Set<Integer> xmlList) {
111 xmlList.add(R.xml.date_time_prefs);
112 xmlList.add(R.xml.data_usage);
113 xmlList.add(R.xml.data_usage_cellular);
114 xmlList.add(R.xml.data_usage_wifi);
115 xmlList.add(R.xml.security_settings_misc);