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