• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 package com.android.vcard.tests;
17 
18 import com.android.vcard.VCardConfig;
19 import com.android.vcard.VCardConstants;
20 import com.android.vcard.VCardEntry;
21 import com.android.vcard.VCardEntry.AndroidCustomData;
22 import com.android.vcard.VCardEntry.AnniversaryData;
23 import com.android.vcard.VCardEntry.BirthdayData;
24 import com.android.vcard.VCardEntry.EmailData;
25 import com.android.vcard.VCardEntry.EntryElement;
26 import com.android.vcard.VCardEntry.EntryLabel;
27 import com.android.vcard.VCardEntry.ImData;
28 import com.android.vcard.VCardEntry.NameData;
29 import com.android.vcard.VCardEntry.NicknameData;
30 import com.android.vcard.VCardEntry.NoteData;
31 import com.android.vcard.VCardEntry.OrganizationData;
32 import com.android.vcard.VCardEntry.PhoneData;
33 import com.android.vcard.VCardEntry.PhotoData;
34 import com.android.vcard.VCardEntry.PostalData;
35 import com.android.vcard.VCardEntry.SipData;
36 import com.android.vcard.VCardEntryConstructor;
37 import com.android.vcard.VCardEntryHandler;
38 import com.android.vcard.VCardInterpreter;
39 import com.android.vcard.VCardProperty;
40 
41 import android.accounts.Account;
42 import android.content.ContentProviderOperation;
43 import android.content.ContentResolver;
44 import android.provider.ContactsContract.CommonDataKinds.Email;
45 import android.provider.ContactsContract.CommonDataKinds.Im;
46 import android.provider.ContactsContract.CommonDataKinds.Organization;
47 import android.provider.ContactsContract.CommonDataKinds.Phone;
48 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
49 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
50 import android.test.AndroidTestCase;
51 
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57 
58 public class VCardEntryTests extends AndroidTestCase {
59     private class MockVCardEntryHandler implements VCardEntryHandler {
60         private List<VCardEntry> mEntries = new ArrayList<VCardEntry>();
61         private boolean mOnStartCalled;
62         private boolean mOnEndCalled;
63 
64         @Override
onStart()65         public void onStart() {
66             assertFalse(mOnStartCalled);
67             mOnStartCalled = true;
68         }
69 
70         @Override
onEntryCreated(VCardEntry entry)71         public void onEntryCreated(VCardEntry entry) {
72             assertTrue(mOnStartCalled);
73             assertFalse(mOnEndCalled);
74             mEntries.add(entry);
75         }
76 
77         @Override
onEnd()78         public void onEnd() {
79             assertTrue(mOnStartCalled);
80             assertFalse(mOnEndCalled);
81             mOnEndCalled = true;
82         }
83 
getEntries()84         public List<VCardEntry> getEntries() {
85             return mEntries;
86         }
87     }
88 
89     /**
90      * Tests VCardEntry and related clasess can handle nested classes given
91      * {@link VCardInterpreter} is called appropriately.
92      *
93      * This test manually calls VCardInterpreter's callback mechanism and checks
94      * {@link VCardEntryConstructor} constructs {@link VCardEntry} per given calls.
95      *
96      * Intended vCard is as follows:
97      * <code>
98      * BEGIN:VCARD
99      * N:test1
100      * BEGIN:VCARD
101      * N:test2
102      * END:VCARD
103      * TEL:1
104      * END:VCARD
105      * </code>
106      */
testNestHandling()107     public void testNestHandling() {
108         VCardEntryConstructor entryConstructor = new VCardEntryConstructor();
109         MockVCardEntryHandler entryHandler = new MockVCardEntryHandler();
110         entryConstructor.addEntryHandler(entryHandler);
111 
112         entryConstructor.onVCardStarted();
113         entryConstructor.onEntryStarted();
114         VCardProperty property = new VCardProperty();
115         property.setName(VCardConstants.PROPERTY_N);
116         property.setValues("test1");
117         entryConstructor.onPropertyCreated(property);
118 
119         entryConstructor.onEntryStarted();  // begin nest
120         property = new VCardProperty();
121         property.setName(VCardConstants.PROPERTY_N);
122         property.setValues("test2");
123         entryConstructor.onPropertyCreated(property);
124         entryConstructor.onEntryEnded();  // end nest
125 
126         property = new VCardProperty();
127         property.setName(VCardConstants.PROPERTY_TEL);
128         property.setValues("1");
129         entryConstructor.onPropertyCreated(property);
130         entryConstructor.onEntryEnded();
131         entryConstructor.onVCardEnded();
132 
133         List<VCardEntry> entries = entryHandler.getEntries();
134         assertEquals(2, entries.size());
135         VCardEntry parent = entries.get(1);
136         VCardEntry child = entries.get(0);
137         assertEquals("test1", parent.getDisplayName());
138         assertEquals("test2", child.getDisplayName());
139         List<VCardEntry.PhoneData> phoneList = parent.getPhoneList();
140         assertNotNull(phoneList);
141         assertEquals(1, phoneList.size());
142         assertEquals("1", phoneList.get(0).getNumber());
143     }
144 
145     private class MockEntryElementIterator implements VCardEntry.EntryElementIterator {
146         private boolean mStartCalled;
147         private boolean mEndCalled;
148         private EntryLabel mLabel;
149         private final Map<EntryLabel, EntryElement> mExpectedElements =
150                 new HashMap<EntryLabel, EntryElement>();
151 
addExpectedElement(EntryElement elem)152         public void addExpectedElement(EntryElement elem) {
153             mExpectedElements.put(elem.getEntryLabel(), elem);
154         }
155 
156         @Override
onIterationStarted()157         public void onIterationStarted() {
158             assertFalse(mStartCalled);
159             assertFalse(mEndCalled);
160             assertNull(mLabel);
161             mStartCalled = true;
162         }
163 
164         @Override
onIterationEnded()165         public void onIterationEnded() {
166             assertTrue(mStartCalled);
167             assertFalse(mEndCalled);
168             assertNull(mLabel);
169             assertTrue("Expected Elements remaining: " +
170                     Arrays.toString(mExpectedElements.values().toArray()),
171                     mExpectedElements.isEmpty());
172         }
173 
174         @Override
onElementGroupStarted(EntryLabel label)175         public void onElementGroupStarted(EntryLabel label) {
176             assertTrue(mStartCalled);
177             assertFalse(mEndCalled);
178             assertNull(mLabel);
179             mLabel = label;
180         }
181 
182         @Override
onElementGroupEnded()183         public void onElementGroupEnded() {
184             assertTrue(mStartCalled);
185             assertFalse(mEndCalled);
186             assertNotNull(mLabel);
187             mLabel = null;
188         }
189 
190         @Override
onElement(EntryElement elem)191         public boolean onElement(EntryElement elem) {
192             EntryElement expectedElem = mExpectedElements.remove(elem.getEntryLabel());
193             assertNotNull("Unexpected elem: " + elem.toString(), expectedElem);
194             assertEquals(expectedElem, elem);
195             return true;
196         }
197     }
198 
199     /**
200      * Tests every element in VCardEntry is iterated by
201      * {@link VCardEntry#iterateAllData(com.android.vcard.VCardEntry.EntryElementIterator)}.
202      */
testEntryElementIterator()203     public void testEntryElementIterator() {
204         VCardEntry entry = new VCardEntry();
205         MockEntryElementIterator iterator = new MockEntryElementIterator();
206 
207         VCardProperty property = new VCardProperty();
208         property.setName("N");
209         property.setValues("family", "given", "middle", "prefix", "suffix");
210         entry.addProperty(property);
211         NameData nameData = new NameData();
212         nameData.setFamily("family");
213         nameData.setGiven("given");
214         nameData.setMiddle("middle");
215         nameData.setPrefix("prefix");
216         nameData.setSuffix("suffix");
217         iterator.addExpectedElement(nameData);
218 
219         property = new VCardProperty();
220         property.setName("TEL");
221         property.setParameter("TYPE", "HOME");
222         property.setValues("1");
223         entry.addProperty(property);
224         PhoneData phoneData = new PhoneData("1", Phone.TYPE_HOME, null, false);
225         iterator.addExpectedElement(phoneData);
226 
227         property = new VCardProperty();
228         property.setName("EMAIL");
229         property.setParameter("TYPE", "WORK");
230         property.setValues("email");
231         entry.addProperty(property);
232         EmailData emailData = new EmailData("email", Email.TYPE_WORK, null, false);
233         iterator.addExpectedElement(emailData);
234 
235         property = new VCardProperty();
236         property.setName("ADR");
237         property.setParameter("TYPE", "HOME");
238         property.setValues(null, null, "street");
239         entry.addProperty(property);
240         PostalData postalData = new PostalData(null, null, "street", null, null, null,
241                 null, StructuredPostal.TYPE_HOME, null, false,
242                 VCardConfig.VCARD_TYPE_DEFAULT);
243         iterator.addExpectedElement(postalData);
244 
245         property = new VCardProperty();
246         property.setName("ORG");
247         property.setValues("organization", "depertment");
248         entry.addProperty(property);
249         OrganizationData organizationData = new OrganizationData(
250                 "organization", "depertment", null, null, Organization.TYPE_WORK, false);
251         iterator.addExpectedElement(organizationData);
252 
253         property = new VCardProperty();
254         property.setName("X-GOOGLE-TALK");
255         property.setParameter("TYPE", "WORK");
256         property.setValues("googletalk");
257         entry.addProperty(property);
258         ImData imData = new ImData(
259                 Im.PROTOCOL_GOOGLE_TALK, null, "googletalk", Im.TYPE_WORK, false);
260         iterator.addExpectedElement(imData);
261 
262         property = new VCardProperty();
263         property.setName("PHOTO");
264         property.setParameter("TYPE", "PNG");
265         byte[] photoBytes = new byte[] {1};
266         property.setByteValue(photoBytes);
267         entry.addProperty(property);
268         PhotoData photoData = new PhotoData("PNG", photoBytes, false);
269         iterator.addExpectedElement(photoData);
270 
271         property = new VCardProperty();
272         property.setName("X-SIP");
273         property.setValues("sipdata");
274         entry.addProperty(property);
275         SipData sipData = new SipData("sip:sipdata", SipAddress.TYPE_OTHER, null, false);
276         iterator.addExpectedElement(sipData);
277 
278         property = new VCardProperty();
279         property.setName("NICKNAME");
280         property.setValues("nickname");
281         entry.addProperty(property);
282         NicknameData nicknameData = new NicknameData("nickname");
283         iterator.addExpectedElement(nicknameData);
284 
285         property = new VCardProperty();
286         property.setName("NOTE");
287         property.setValues("note");
288         entry.addProperty(property);
289         NoteData noteData = new NoteData("note");
290         iterator.addExpectedElement(noteData);
291 
292         property = new VCardProperty();
293         property.setName("BDAY");
294         property.setValues("birthday");
295         entry.addProperty(property);
296         BirthdayData birthdayData = new BirthdayData("birthday");
297         iterator.addExpectedElement(birthdayData);
298 
299         property = new VCardProperty();
300         property.setName("ANNIVERSARY");
301         property.setValues("anniversary");
302         entry.addProperty(property);
303         AnniversaryData anniversaryData = new AnniversaryData("anniversary");
304         iterator.addExpectedElement(anniversaryData);
305 
306         property = new VCardProperty();
307         property.setName("X-ANDROID-CUSTOM");
308         property.setValues("mime;value");
309         entry.addProperty(property);
310         AndroidCustomData androidCustom = new AndroidCustomData("mime", Arrays.asList("value"));
311         iterator.addExpectedElement(androidCustom);
312 
313         entry.iterateAllData(iterator);
314     }
315 
testToString()316     public void testToString() {
317         VCardEntry entry = new VCardEntry();
318         VCardProperty property = new VCardProperty();
319         property.setName("N");
320         property.setValues("Family", "Given", "Middle", "Prefix", "Suffix");
321         entry.addProperty(property);
322         entry.consolidateFields();
323 
324         String result = entry.toString();
325         assertNotNull(result);
326 
327         assertTrue(result.contains(String.valueOf(entry.hashCode())));
328         assertTrue(result.contains(VCardEntry.EntryLabel.NAME.toString()));
329         assertTrue(result.contains("Family"));
330         assertTrue(result.contains("Given"));
331         assertTrue(result.contains("Middle"));
332         assertTrue(result.contains("Prefix"));
333         assertTrue(result.contains("Suffix"));
334     }
335 
336     /**
337      * Tests that VCardEntry emits correct insert operation for name field.
338      */
testConstructInsertOperationsInsertName()339     public void testConstructInsertOperationsInsertName() {
340         VCardEntry entry = new VCardEntry();
341         VCardProperty property = new VCardProperty();
342         property.setName("N");
343         property.setValues("Family", "Given", "Middle", "Prefix", "Suffix");
344         entry.addProperty(property);
345         entry.consolidateFields();
346 
347         NameData nameData = entry.getNameData();
348         assertEquals("Family", nameData.getFamily());
349         assertEquals("Given", nameData.getGiven());
350         assertEquals("Middle", nameData.getMiddle());
351         assertEquals("Prefix", nameData.getPrefix());
352         assertEquals("Suffix", nameData.getSuffix());
353 
354         ContentResolver resolver = getContext().getContentResolver();
355         ArrayList<ContentProviderOperation> operationList =
356                 new ArrayList<ContentProviderOperation>();
357         entry.constructInsertOperations(resolver, operationList);
358 
359         // Need too many details for testing these. Just check basics.
360         // TODO: introduce nice-to-test mechanism here.
361         assertEquals(2, operationList.size());
362         assertEquals(ContentProviderOperation.TYPE_INSERT, operationList.get(0).getType());
363         assertEquals(ContentProviderOperation.TYPE_INSERT, operationList.get(1).getType());
364     }
365 
366     /**
367      * Tests that VCardEntry refrains from emitting unnecessary insert operation.
368      */
testConstructInsertOperationsEmptyData()369     public void testConstructInsertOperationsEmptyData() {
370         VCardEntry entry = new VCardEntry();
371         ContentResolver resolver = getContext().getContentResolver();
372         ArrayList<ContentProviderOperation> operationList =
373                 new ArrayList<ContentProviderOperation>();
374         entry.constructInsertOperations(resolver, operationList);
375         assertEquals(0, operationList.size());
376     }
377 
378     /**
379      * Tests that VCardEntry can add an account via the constructor
380      */
testConstructor_withAccount_canGetAccount()381     public void testConstructor_withAccount_canGetAccount() {
382         Account account = new Account("test-type", "test-name");
383         VCardEntry entry = new VCardEntry(VCardConfig.VCARD_TYPE_V21_GENERIC, account);
384         assertEquals(entry.getAccount(), account);
385     }
386 
387     /**
388      * Tests that VCardEntry can add a null account via the constructor
389      */
testConstructor_withNullAccount_canGetNullAccount()390     public void testConstructor_withNullAccount_canGetNullAccount() {
391         VCardEntry entry = new VCardEntry(VCardConfig.VCARD_TYPE_V21_GENERIC, null);
392         assertEquals(entry.getAccount(), null);
393     }
394 
395     /**
396      * Tests that VCardEntry can add an account via the setter, updating a null account to a value
397      */
testSetAccount_fromNullToValue_canGetAccount()398     public void testSetAccount_fromNullToValue_canGetAccount() {
399         Account account = new Account("test-type", "test-name");
400         VCardEntry entry = new VCardEntry();
401         assertEquals(entry.getAccount(), null);
402         entry.setAccount(account);
403         assertEquals(entry.getAccount(), account);
404     }
405 
406     /**
407      * Tests that VCardEntry can add an account via the setter, changing one account to another
408      */
testSetAccount_fromToNewValue_canGetAccount()409     public void testSetAccount_fromToNewValue_canGetAccount() {
410         Account account1 = new Account("test-type-1", "test-name-1");
411         VCardEntry entry = new VCardEntry(VCardConfig.VCARD_TYPE_V21_GENERIC, account1);
412         assertEquals(entry.getAccount(), account1);
413 
414         Account account2 = new Account("test-type-2", "test-name-2");
415         entry.setAccount(account2);
416         assertEquals(entry.getAccount(), account2);
417     }
418 
419     /**
420      * Tests that VCardEntry can add an account via the setter, changing one account to another
421      */
testSetAccount_setValueTwice_canGetAccount()422     public void testSetAccount_setValueTwice_canGetAccount() {
423         VCardEntry entry = new VCardEntry();
424         assertEquals(entry.getAccount(), null);
425 
426         Account account1 = new Account("test-type-1", "test-name-1");
427         entry.setAccount(account1);
428         assertEquals(entry.getAccount(), account1);
429 
430         Account account2 = new Account("test-type-2", "test-name-2");
431         entry.setAccount(account2);
432         assertEquals(entry.getAccount(), account2);
433     }
434 
435     // TODO: add bunch of test for constructInsertOperations..
436 }
437