/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.vcard.tests; import com.android.vcard.VCardConfig; import com.android.vcard.VCardConstants; import com.android.vcard.VCardEntry; import com.android.vcard.VCardEntry.AndroidCustomData; import com.android.vcard.VCardEntry.AnniversaryData; import com.android.vcard.VCardEntry.BirthdayData; import com.android.vcard.VCardEntry.EmailData; import com.android.vcard.VCardEntry.EntryElement; import com.android.vcard.VCardEntry.EntryLabel; import com.android.vcard.VCardEntry.ImData; import com.android.vcard.VCardEntry.NameData; import com.android.vcard.VCardEntry.NicknameData; import com.android.vcard.VCardEntry.NoteData; import com.android.vcard.VCardEntry.OrganizationData; import com.android.vcard.VCardEntry.PhoneData; import com.android.vcard.VCardEntry.PhotoData; import com.android.vcard.VCardEntry.PostalData; import com.android.vcard.VCardEntry.SipData; import com.android.vcard.VCardEntryConstructor; import com.android.vcard.VCardEntryHandler; import com.android.vcard.VCardInterpreter; import com.android.vcard.VCardProperty; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Im; import android.provider.ContactsContract.CommonDataKinds.Organization; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.SipAddress; import android.test.AndroidTestCase; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class VCardEntryTests extends AndroidTestCase { private class MockVCardEntryHandler implements VCardEntryHandler { private List mEntries = new ArrayList(); private boolean mOnStartCalled; private boolean mOnEndCalled; @Override public void onStart() { assertFalse(mOnStartCalled); mOnStartCalled = true; } @Override public void onEntryCreated(VCardEntry entry) { assertTrue(mOnStartCalled); assertFalse(mOnEndCalled); mEntries.add(entry); } @Override public void onEnd() { assertTrue(mOnStartCalled); assertFalse(mOnEndCalled); mOnEndCalled = true; } public List getEntries() { return mEntries; } } /** * Tests VCardEntry and related clasess can handle nested classes given * {@link VCardInterpreter} is called appropriately. * * This test manually calls VCardInterpreter's callback mechanism and checks * {@link VCardEntryConstructor} constructs {@link VCardEntry} per given calls. * * Intended vCard is as follows: * * BEGIN:VCARD * N:test1 * BEGIN:VCARD * N:test2 * END:VCARD * TEL:1 * END:VCARD * */ public void testNestHandling() { VCardEntryConstructor entryConstructor = new VCardEntryConstructor(); MockVCardEntryHandler entryHandler = new MockVCardEntryHandler(); entryConstructor.addEntryHandler(entryHandler); entryConstructor.onVCardStarted(); entryConstructor.onEntryStarted(); VCardProperty property = new VCardProperty(); property.setName(VCardConstants.PROPERTY_N); property.setValues("test1"); entryConstructor.onPropertyCreated(property); entryConstructor.onEntryStarted(); // begin nest property = new VCardProperty(); property.setName(VCardConstants.PROPERTY_N); property.setValues("test2"); entryConstructor.onPropertyCreated(property); entryConstructor.onEntryEnded(); // end nest property = new VCardProperty(); property.setName(VCardConstants.PROPERTY_TEL); property.setValues("1"); entryConstructor.onPropertyCreated(property); entryConstructor.onEntryEnded(); entryConstructor.onVCardEnded(); List entries = entryHandler.getEntries(); assertEquals(2, entries.size()); VCardEntry parent = entries.get(1); VCardEntry child = entries.get(0); assertEquals("test1", parent.getDisplayName()); assertEquals("test2", child.getDisplayName()); List phoneList = parent.getPhoneList(); assertNotNull(phoneList); assertEquals(1, phoneList.size()); assertEquals("1", phoneList.get(0).getNumber()); } private class MockEntryElementIterator implements VCardEntry.EntryElementIterator { private boolean mStartCalled; private boolean mEndCalled; private EntryLabel mLabel; private final Map mExpectedElements = new HashMap(); public void addExpectedElement(EntryElement elem) { mExpectedElements.put(elem.getEntryLabel(), elem); } @Override public void onIterationStarted() { assertFalse(mStartCalled); assertFalse(mEndCalled); assertNull(mLabel); mStartCalled = true; } @Override public void onIterationEnded() { assertTrue(mStartCalled); assertFalse(mEndCalled); assertNull(mLabel); assertTrue("Expected Elements remaining: " + Arrays.toString(mExpectedElements.values().toArray()), mExpectedElements.isEmpty()); } @Override public void onElementGroupStarted(EntryLabel label) { assertTrue(mStartCalled); assertFalse(mEndCalled); assertNull(mLabel); mLabel = label; } @Override public void onElementGroupEnded() { assertTrue(mStartCalled); assertFalse(mEndCalled); assertNotNull(mLabel); mLabel = null; } @Override public boolean onElement(EntryElement elem) { EntryElement expectedElem = mExpectedElements.remove(elem.getEntryLabel()); assertNotNull("Unexpected elem: " + elem.toString(), expectedElem); assertEquals(expectedElem, elem); return true; } } /** * Tests every element in VCardEntry is iterated by * {@link VCardEntry#iterateAllData(com.android.vcard.VCardEntry.EntryElementIterator)}. */ public void testEntryElementIterator() { VCardEntry entry = new VCardEntry(); MockEntryElementIterator iterator = new MockEntryElementIterator(); VCardProperty property = new VCardProperty(); property.setName("N"); property.setValues("family", "given", "middle", "prefix", "suffix"); entry.addProperty(property); NameData nameData = new NameData(); nameData.setFamily("family"); nameData.setGiven("given"); nameData.setMiddle("middle"); nameData.setPrefix("prefix"); nameData.setSuffix("suffix"); iterator.addExpectedElement(nameData); property = new VCardProperty(); property.setName("TEL"); property.setParameter("TYPE", "HOME"); property.setValues("1"); entry.addProperty(property); PhoneData phoneData = new PhoneData("1", Phone.TYPE_HOME, null, false); iterator.addExpectedElement(phoneData); property = new VCardProperty(); property.setName("EMAIL"); property.setParameter("TYPE", "WORK"); property.setValues("email"); entry.addProperty(property); EmailData emailData = new EmailData("email", Email.TYPE_WORK, null, false); iterator.addExpectedElement(emailData); property = new VCardProperty(); property.setName("ADR"); property.setParameter("TYPE", "HOME"); property.setValues(null, null, "street"); entry.addProperty(property); PostalData postalData = new PostalData(null, null, "street", null, null, null, null, StructuredPostal.TYPE_HOME, null, false, VCardConfig.VCARD_TYPE_DEFAULT); iterator.addExpectedElement(postalData); property = new VCardProperty(); property.setName("ORG"); property.setValues("organization", "depertment"); entry.addProperty(property); OrganizationData organizationData = new OrganizationData( "organization", "depertment", null, null, Organization.TYPE_WORK, false); iterator.addExpectedElement(organizationData); property = new VCardProperty(); property.setName("X-GOOGLE-TALK"); property.setParameter("TYPE", "WORK"); property.setValues("googletalk"); entry.addProperty(property); ImData imData = new ImData( Im.PROTOCOL_GOOGLE_TALK, null, "googletalk", Im.TYPE_WORK, false); iterator.addExpectedElement(imData); property = new VCardProperty(); property.setName("PHOTO"); property.setParameter("TYPE", "PNG"); byte[] photoBytes = new byte[] {1}; property.setByteValue(photoBytes); entry.addProperty(property); PhotoData photoData = new PhotoData("PNG", photoBytes, false); iterator.addExpectedElement(photoData); property = new VCardProperty(); property.setName("X-SIP"); property.setValues("sipdata"); entry.addProperty(property); SipData sipData = new SipData("sip:sipdata", SipAddress.TYPE_OTHER, null, false); iterator.addExpectedElement(sipData); property = new VCardProperty(); property.setName("NICKNAME"); property.setValues("nickname"); entry.addProperty(property); NicknameData nicknameData = new NicknameData("nickname"); iterator.addExpectedElement(nicknameData); property = new VCardProperty(); property.setName("NOTE"); property.setValues("note"); entry.addProperty(property); NoteData noteData = new NoteData("note"); iterator.addExpectedElement(noteData); property = new VCardProperty(); property.setName("BDAY"); property.setValues("birthday"); entry.addProperty(property); BirthdayData birthdayData = new BirthdayData("birthday"); iterator.addExpectedElement(birthdayData); property = new VCardProperty(); property.setName("ANNIVERSARY"); property.setValues("anniversary"); entry.addProperty(property); AnniversaryData anniversaryData = new AnniversaryData("anniversary"); iterator.addExpectedElement(anniversaryData); property = new VCardProperty(); property.setName("X-ANDROID-CUSTOM"); property.setValues("mime;value"); entry.addProperty(property); AndroidCustomData androidCustom = new AndroidCustomData("mime", Arrays.asList("value")); iterator.addExpectedElement(androidCustom); entry.iterateAllData(iterator); } public void testToString() { VCardEntry entry = new VCardEntry(); VCardProperty property = new VCardProperty(); property.setName("N"); property.setValues("Family", "Given", "Middle", "Prefix", "Suffix"); entry.addProperty(property); entry.consolidateFields(); String result = entry.toString(); assertNotNull(result); assertTrue(result.contains(String.valueOf(entry.hashCode()))); assertTrue(result.contains(VCardEntry.EntryLabel.NAME.toString())); assertTrue(result.contains("Family")); assertTrue(result.contains("Given")); assertTrue(result.contains("Middle")); assertTrue(result.contains("Prefix")); assertTrue(result.contains("Suffix")); } /** * Tests that VCardEntry emits correct insert operation for name field. */ public void testConstructInsertOperationsInsertName() { VCardEntry entry = new VCardEntry(); VCardProperty property = new VCardProperty(); property.setName("N"); property.setValues("Family", "Given", "Middle", "Prefix", "Suffix"); entry.addProperty(property); entry.consolidateFields(); NameData nameData = entry.getNameData(); assertEquals("Family", nameData.getFamily()); assertEquals("Given", nameData.getGiven()); assertEquals("Middle", nameData.getMiddle()); assertEquals("Prefix", nameData.getPrefix()); assertEquals("Suffix", nameData.getSuffix()); ContentResolver resolver = getContext().getContentResolver(); ArrayList operationList = new ArrayList(); entry.constructInsertOperations(resolver, operationList); // Need too many details for testing these. Just check basics. // TODO: introduce nice-to-test mechanism here. assertEquals(2, operationList.size()); assertEquals(ContentProviderOperation.TYPE_INSERT, operationList.get(0).getType()); assertEquals(ContentProviderOperation.TYPE_INSERT, operationList.get(1).getType()); } /** * Tests that VCardEntry refrains from emitting unnecessary insert operation. */ public void testConstructInsertOperationsEmptyData() { VCardEntry entry = new VCardEntry(); ContentResolver resolver = getContext().getContentResolver(); ArrayList operationList = new ArrayList(); entry.constructInsertOperations(resolver, operationList); assertEquals(0, operationList.size()); } // TODO: add bunch of test for constructInsertOperations.. }