1 /*
2  * Copyright (C) 2015 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.providers.contacts;
18 
19 import android.content.Context;
20 import android.test.AndroidTestCase;
21 import android.test.suitebuilder.annotation.SmallTest;
22 import com.android.providers.contacts.MetadataEntryParser.AggregationData;
23 import com.android.providers.contacts.MetadataEntryParser.FieldData;
24 import com.android.providers.contacts.MetadataEntryParser.MetadataEntry;
25 import com.android.providers.contacts.MetadataEntryParser.RawContactInfo;
26 import com.android.providers.contacts.MetadataEntryParser.UsageStats;
27 import org.json.JSONException;
28 
29 import java.io.ByteArrayOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.util.ArrayList;
33 
34 /**
35  * Unit tests for {@link MetadataEntryParser}.
36  *
37  * Run the test like this:
38  * <code>
39  adb shell am instrument -e class com.android.providers.contacts.MetadataEntryParserTest -w \
40          com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
41  * </code>
42  */
43 @SmallTest
44 public class MetadataEntryParserTest extends AndroidTestCase {
45 
testErrorForEmptyInput()46     public void testErrorForEmptyInput() {
47         try {
48             MetadataEntryParser.parseDataToMetaDataEntry("");
49         } catch (IllegalArgumentException e) {
50             // Expected.
51         }
52     }
53 
testParseDataToMetadataEntry()54     public void testParseDataToMetadataEntry() throws IOException {
55         String contactBackupId = "1111111";
56         String accountType = "facebook";
57         String accountName = "android-test";
58         String dataSet = null;
59         int sendToVoicemail = 1;
60         int starred = 0;
61         int pinned = 2;
62         String dataHashId1 = "1001";
63         String usageType1_1 = "CALL";
64         long lastTimeUsed1_1 = 10000001;
65         int timesUsed1_1 = 10;
66         String usageType1_2 = "SHORT_TEXT";
67         long lastTimeUsed1_2 = 20000002;
68         int timesUsed1_2 = 20;
69         String dataHashId2 = "1002";
70         String usageType2 = "LONG_TEXT";
71         long lastTimeUsed2 = 30000003;
72         int timesUsed2 = 30;
73         String aggregationContactBackupId1 = "2222222";
74         String aggregationAccountType1 = "com.google";
75         String aggregationAccountName1 = "android-test2";
76         String aggregationDataSet1 = "plus";
77         String aggregationContactBackupId2 = "3333333";
78         String aggregationAccountType2 = "com.google";
79         String aggregationAccountName2 = "android-test3";
80         String aggregationDataSet2 = "custom type";
81         String type = "TOGETHER";
82         String inputFile = "test1/testFileDeviceContactMetadataJSON.txt";
83 
84         RawContactInfo rawContactInfo = new RawContactInfo(
85                 contactBackupId, accountType, accountName, dataSet);
86         RawContactInfo aggregationContact1 = new RawContactInfo(aggregationContactBackupId1,
87                 aggregationAccountType1, aggregationAccountName1, aggregationDataSet1);
88         RawContactInfo aggregationContact2 = new RawContactInfo(aggregationContactBackupId2,
89                 aggregationAccountType2, aggregationAccountName2, aggregationDataSet2);
90         AggregationData aggregationData = new AggregationData(
91                 aggregationContact1, aggregationContact2, type);
92         ArrayList<AggregationData> aggregationDataList = new ArrayList<>();
93         aggregationDataList.add(aggregationData);
94 
95         UsageStats usageStats1_1 = new UsageStats(usageType1_1, lastTimeUsed1_1, timesUsed1_1);
96         UsageStats usageStats1_2 = new UsageStats(usageType1_2, lastTimeUsed1_2, timesUsed1_2);
97         UsageStats usageStats2 = new UsageStats(usageType2, lastTimeUsed2, timesUsed2);
98 
99         ArrayList<UsageStats> usageStats1List = new ArrayList<>();
100         usageStats1List.add(usageStats1_1);
101         usageStats1List.add(usageStats1_2);
102         FieldData fieldData1 = new FieldData(dataHashId1, true, true, usageStats1List);
103 
104         ArrayList<UsageStats> usageStats2List = new ArrayList<>();
105         usageStats2List.add(usageStats2);
106         FieldData fieldData2 = new FieldData(dataHashId2, false, false, usageStats2List);
107 
108         ArrayList<FieldData> fieldDataList = new ArrayList<>();
109         fieldDataList.add(fieldData1);
110         fieldDataList.add(fieldData2);
111 
112         MetadataEntry expectedResult = new MetadataEntry(rawContactInfo,
113                 sendToVoicemail, starred, pinned, fieldDataList, aggregationDataList);
114 
115         String inputJson = readAssetAsString(inputFile);
116         MetadataEntry metadataEntry = MetadataEntryParser.parseDataToMetaDataEntry(
117                 inputJson.toString());
118         assertMetaDataEntry(expectedResult, metadataEntry);
119     }
120 
testErrorForMissingContactId()121     public void testErrorForMissingContactId() {
122         String input = "{\"unique_contact_id\": {\n" +
123                 "    \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
124                 "    \"custom_account_type\": \"facebook\",\n" +
125                 "    \"account_name\": \"android-test\"\n" +
126                 "  }}";
127         try {
128             MetadataEntryParser.parseDataToMetaDataEntry(input);
129         } catch (IllegalArgumentException e) {
130             // Expected.
131         }
132     }
133 
testErrorForNullContactId()134     public void testErrorForNullContactId() throws JSONException {
135         String input = "{\"unique_contact_id\": {\n" +
136                 "    \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
137                 "    \"custom_account_type\": \"facebook\",\n" +
138                 "    \"account_name\": \"android-test\",\n" +
139                 "    \"contact_id\": \"\"\n" +
140                 "  }}";
141         try {
142             MetadataEntryParser.parseDataToMetaDataEntry(input);
143         } catch (IllegalArgumentException e) {
144             // Expected.
145         }
146     }
147 
testErrorForNullAccountType()148     public void testErrorForNullAccountType() throws JSONException {
149         String input = "{\"unique_contact_id\": {\n" +
150                 "    \"account_type\": \"\",\n" +
151                 "    \"custom_account_type\": \"facebook\",\n" +
152                 "    \"account_name\": \"android-test\",\n" +
153                 "    \"contact_id\": \"\"\n" +
154                 "  }}";
155         try {
156             MetadataEntryParser.parseDataToMetaDataEntry(input);
157         } catch (IllegalArgumentException e) {
158             // Expected.
159         }
160     }
161 
testErrorForNullAccountName()162     public void testErrorForNullAccountName() throws JSONException {
163         String input = "{\"unique_contact_id\": {\n" +
164                 "    \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
165                 "    \"custom_account_type\": \"facebook\",\n" +
166                 "    \"account_name\": \"\",\n" +
167                 "    \"contact_id\": \"1111111\"\n" +
168                 "  }}";
169         try {
170             MetadataEntryParser.parseDataToMetaDataEntry(input);
171         } catch (IllegalArgumentException e) {
172             // Expected.
173         }
174     }
175 
testErrorForNullFieldDataId()176     public void testErrorForNullFieldDataId() throws JSONException {
177         String input = "{\"unique_contact_id\": {\n" +
178                 "    \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
179                 "    \"custom_account_type\": \"facebook\",\n" +
180                 "    \"account_name\": \"android-test\",\n" +
181                 "    \"contact_id\": \"1111111\"\n" +
182                 "  },\n" +
183                 "    \"contact_prefs\": {\n" +
184                 "    \"send_to_voicemail\": true,\n" +
185                 "    \"starred\": false,\n" +
186                 "    \"pinned\": 2\n" +
187                 "  }," +
188                 "    \"field_data\": [{\n" +
189                 "      \"field_data_id\": \"\"}]" +
190                 "}";
191         try {
192             MetadataEntryParser.parseDataToMetaDataEntry(input);
193         } catch (IllegalArgumentException e) {
194             // Expected.
195         }
196     }
197 
testErrorForNullAggregationType()198     public void testErrorForNullAggregationType() throws JSONException {
199         String input = "{\n" +
200                 "  \"unique_contact_id\": {\n" +
201                 "    \"account_type\": \"CUSTOM_ACCOUNT\",\n" +
202                 "    \"custom_account_type\": \"facebook\",\n" +
203                 "    \"account_name\": \"android-test\",\n" +
204                 "    \"contact_id\": \"1111111\"\n" +
205                 "  },\n" +
206                 "  \"contact_prefs\": {\n" +
207                 "    \"send_to_voicemail\": true,\n" +
208                 "    \"starred\": false,\n" +
209                 "    \"pinned\": 2\n" +
210                 "  },\n" +
211                 "  \"aggregation_data\": [\n" +
212                 "    {\n" +
213                 "      \"type\": \"\",\n" +
214                 "      \"contact_ids\": [\n" +
215                 "        {\n" +
216                 "          \"contact_id\": \"2222222\"\n" +
217                 "        },\n" +
218                 "        {\n" +
219                 "          \"contact_id\": \"3333333\"\n" +
220                 "        }\n" +
221                 "      ]\n" +
222                 "    }\n" +
223                 "  ]}";
224         try {
225             MetadataEntryParser.parseDataToMetaDataEntry(input);
226         } catch (IllegalArgumentException e) {
227             // Expected.
228         }
229     }
230 
readAssetAsString(String fileName)231     private String readAssetAsString(String fileName) throws IOException {
232         Context context = getTestContext();
233         InputStream input = context.getAssets().open(fileName);
234         ByteArrayOutputStream contents = new ByteArrayOutputStream();
235         int len;
236         byte[] data = new byte[1024];
237         do {
238             len = input.read(data);
239             if (len > 0) contents.write(data, 0, len);
240         } while (len == data.length);
241         return contents.toString();
242     }
243 
assertMetaDataEntry(MetadataEntry entry1, MetadataEntry entry2)244     private void assertMetaDataEntry(MetadataEntry entry1, MetadataEntry entry2) {
245         assertRawContactInfoEquals(entry1.mRawContactInfo, entry2.mRawContactInfo);
246         assertEquals(entry1.mSendToVoicemail, entry2.mSendToVoicemail);
247         assertEquals(entry1.mStarred, entry2.mStarred);
248         assertEquals(entry1.mPinned, entry2.mPinned);
249         assertAggregationDataListEquals(entry1.mAggregationDatas, entry2.mAggregationDatas);
250         assertFieldDataListEquals(entry1.mFieldDatas, entry2.mFieldDatas);
251     }
252 
assertRawContactInfoEquals(RawContactInfo contact1, RawContactInfo contact2)253     private void assertRawContactInfoEquals(RawContactInfo contact1, RawContactInfo contact2) {
254         assertEquals(contact1.mBackupId, contact2.mBackupId);
255         assertEquals(contact1.mAccountType, contact2.mAccountType);
256         assertEquals(contact1.mAccountName, contact2.mAccountName);
257         assertEquals(contact1.mDataSet, contact2.mDataSet);
258     }
259 
assertAggregationDataListEquals(ArrayList<AggregationData> aggregationList1, ArrayList<AggregationData> aggregationList2)260     private void assertAggregationDataListEquals(ArrayList<AggregationData> aggregationList1,
261             ArrayList<AggregationData> aggregationList2) {
262         assertEquals(aggregationList1.size(), aggregationList2.size());
263         for (int i = 0; i < aggregationList1.size(); i++) {
264             assertAggregationDataEquals(aggregationList1.get(i), aggregationList2.get(i));
265         }
266     }
267 
assertAggregationDataEquals(AggregationData aggregationData1, AggregationData aggregationData2)268     private void assertAggregationDataEquals(AggregationData aggregationData1,
269             AggregationData aggregationData2) {
270         assertRawContactInfoEquals(aggregationData1.mRawContactInfo1,
271                 aggregationData2.mRawContactInfo1);
272         assertRawContactInfoEquals(aggregationData1.mRawContactInfo2,
273                 aggregationData2.mRawContactInfo2);
274         assertEquals(aggregationData1.mType, aggregationData2.mType);
275     }
276 
assertFieldDataListEquals(ArrayList<FieldData> fieldDataList1, ArrayList<FieldData> fieldDataList2)277     private void assertFieldDataListEquals(ArrayList<FieldData> fieldDataList1,
278             ArrayList<FieldData> fieldDataList2) {
279         assertEquals(fieldDataList1.size(), fieldDataList2.size());
280         for (int i = 0; i < fieldDataList1.size(); i++) {
281             assertFieldDataEquals(fieldDataList1.get(i), fieldDataList2.get(i));
282         }
283     }
284 
assertFieldDataEquals(FieldData fieldData1, FieldData fieldData2)285     private void assertFieldDataEquals(FieldData fieldData1, FieldData fieldData2) {
286         assertEquals(fieldData1.mDataHashId, fieldData2.mDataHashId);
287         assertEquals(fieldData1.mIsPrimary, fieldData2.mIsPrimary);
288         assertEquals(fieldData1.mIsSuperPrimary, fieldData2.mIsSuperPrimary);
289         assertUsageStatsListEquals(fieldData1.mUsageStatsList, fieldData2.mUsageStatsList);
290     }
291 
assertUsageStatsListEquals(ArrayList<UsageStats> usageStatsList1, ArrayList<UsageStats> usageStatsList2)292     private void assertUsageStatsListEquals(ArrayList<UsageStats> usageStatsList1,
293             ArrayList<UsageStats> usageStatsList2) {
294         assertEquals(usageStatsList1.size(), usageStatsList2.size());
295         for (int i = 0; i < usageStatsList1.size(); i++) {
296             assertUsageStatsEquals(usageStatsList1.get(i), usageStatsList2.get(i));
297         }
298     }
299 
assertUsageStatsEquals(UsageStats usageStats1, UsageStats usageStats2)300     private void assertUsageStatsEquals(UsageStats usageStats1, UsageStats usageStats2) {
301         assertEquals(usageStats1.mUsageType, usageStats2.mUsageType);
302         assertEquals(usageStats1.mLastTimeUsed, usageStats2.mLastTimeUsed);
303         assertEquals(usageStats1.mTimesUsed, usageStats2.mTimesUsed);
304     }
305 }
306