diff options
3 files changed, 113 insertions, 15 deletions
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java index c5afb73..8eabd4b 100644 --- a/core/java/android/pim/vcard/VCardComposer.java +++ b/core/java/android/pim/vcard/VCardComposer.java @@ -742,10 +742,9 @@ public class VCardComposer { encodedSuffix = escapeCharacters(suffix); } - // N property. This order is specified by vCard spec and does not depend on countries. builder.append(Constants.PROPERTY_N); if (shouldAppendCharsetAttribute(Arrays.asList( - familyName, givenName, middleName, prefix, suffix))) { + encodedFamily, encodedGiven, encodedMiddle, encodedPrefix, encodedSuffix))) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); } @@ -766,9 +765,15 @@ public class VCardComposer { builder.append(encodedSuffix); builder.append(VCARD_COL_SEPARATOR); - final String formattedName = VCardUtils.constructNameFromElements( + final String formattedName; + if (!TextUtils.isEmpty(displayName)) { + formattedName = displayName; + } else { + formattedName = VCardUtils.constructNameFromElements( VCardConfig.getNameOrderType(mVCardType), encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix); + } + final boolean reallyUseQuotedPrintableToFullname = !mRefrainsQPToPrimaryProperties && !VCardUtils.containsOnlyNonCrLfPrintableAscii(formattedName); @@ -1501,7 +1506,7 @@ public class VCardComposer { final StringBuilder tmpBuilder = new StringBuilder(); final int length = unescaped.length(); for (int i = 0; i < length; i++) { - char ch = unescaped.charAt(i); + final char ch = unescaped.charAt(i); switch (ch) { case ';': { tmpBuilder.append('\\'); @@ -1512,7 +1517,7 @@ public class VCardComposer { if (i + 1 < length) { char nextChar = unescaped.charAt(i); if (nextChar == '\n') { - continue; + break; } else { // fall through } diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java index b009e2d..a0d6d16 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java +++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/PropertyNodesVerifier.java @@ -70,6 +70,21 @@ public class PropertyNodesVerifier { return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null); } + public PropertyNodesVerifier addNodeWithOrder(String propName, List<String> propValueList) { + StringBuffer buffer = new StringBuffer(); + boolean first = true; + for (String propValueElem : propValueList) { + if (first) { + first = false; + } else { + buffer.append(';'); + } + buffer.append(propValueElem); + } + return addNodeWithOrder(propName, buffer.toString(), propValueList, + null, null, null, null); + } + public PropertyNodesVerifier addNodeWithOrder(String propName, String propValue, TypeSet paramMap_TYPE) { return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null); @@ -107,6 +122,21 @@ public class PropertyNodesVerifier { return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null); } + public PropertyNodesVerifier addNodeWithoutOrder(String propName, List<String> propValueList) { + StringBuffer buffer = new StringBuffer(); + boolean first = true; + for (String propValueElem : propValueList) { + if (first) { + first = false; + } else { + buffer.append(';'); + } + buffer.append(propValueElem); + } + return addNodeWithoutOrder(propName, buffer.toString(), propValueList, + null, null, null, null); + } + public PropertyNodesVerifier addNodeWithoutOrder(String propName, String propValue, TypeSet paramMap_TYPE) { return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null); diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java index 53afb5b..05a9871 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardExporterTests.java @@ -16,8 +16,6 @@ package com.android.unit_tests.vcard; -import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet; - import android.content.ContentProvider; import android.content.ContentProviderOperation; import android.content.ContentProviderResult; @@ -60,16 +58,20 @@ import android.test.mock.MockContentResolver; import android.test.mock.MockContext; import android.test.mock.MockCursor; +import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet; + +import junit.framework.TestCase; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; - -import junit.framework.TestCase; +import java.util.Set; /** * Almost a dead copy of android.test.mock.MockContentProvider, but different in that this @@ -292,12 +294,16 @@ public class VCardExporterTests extends AndroidTestCase { final private TestCase mTestCase; final private List<PropertyNodesVerifier> mPropertyNodesVerifierList; final private boolean mIsV30; + // To allow duplication, use list instead of set. + // TODO: support multiple vCard entries. + final private List<String> mExpectedLineList; int mCount; - public VCardVerificationHandler(TestCase testCase, int version) { + public VCardVerificationHandler(final TestCase testCase, final int version) { mTestCase = testCase; mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>(); mIsV30 = (version == V30); + mExpectedLineList = new ArrayList<String>(); mCount = 1; } @@ -316,11 +322,51 @@ public class VCardExporterTests extends AndroidTestCase { return verifier; } - public boolean onInit(Context context) { + public VCardVerificationHandler addExpectedLine(String line) { + mExpectedLineList.add(line); + return this; + } + + public boolean onInit(final Context context) { + return true; + } + + public boolean onEntryCreated(final String vcard) { + if (!mExpectedLineList.isEmpty()) { + verifyLines(vcard); + } + verifyNodes(vcard); return true; } - public boolean onEntryCreated(String vcard) { + private void verifyLines(final String vcard) { + final String[] lineArray = vcard.split("\\r?\\n"); + final int length = lineArray.length; + for (int i = 0; i < length; i++) { + final String line = lineArray[i]; + // TODO: support multiple vcard entries. + if ("BEGIN:VCARD".equals(line) || "END:VCARD".equals(line) || + (mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equals(line)) { + continue; + } + final int index = mExpectedLineList.indexOf(line); + if (index >= 0) { + mExpectedLineList.remove(index); + } else { + mTestCase.fail("Unexpected line: " + line); + } + } + if (!mExpectedLineList.isEmpty()) { + StringBuffer buffer = new StringBuffer(); + for (String expectedLine : mExpectedLineList) { + buffer.append(expectedLine); + buffer.append("\n"); + } + mTestCase.fail("Expected line(s) not found:" + buffer.toString()); + } + } + + private void verifyNodes(final String vcard) { if (mPropertyNodesVerifierList.size() == 0) { mTestCase.fail("Too many vCard entries seems to be inserted(No." + mCount + " of the entries (No.1 is the first entry))"); @@ -344,7 +390,6 @@ public class VCardExporterTests extends AndroidTestCase { } finally { mCount++; } - return true; } public void onTerminate() { @@ -1178,8 +1223,6 @@ public class VCardExporterTests extends AndroidTestCase { testNoteCommon(V30); } - // TODO: test for non-ascii... - private void testPhotoCommon(int version) { final boolean isV30 = version == V30; ExportTestResolver resolver = new ExportTestResolver(); @@ -1208,4 +1251,24 @@ public class VCardExporterTests extends AndroidTestCase { public void testPhotoV30() { testPhotoCommon(V30); } + + public void testV30HandleEscape() { + final int version = V30; + ExportTestResolver resolver = new ExportTestResolver(); + ContentValues contentValues = resolver.buildData(StructuredName.CONTENT_ITEM_TYPE); + contentValues.put(StructuredName.FAMILY_NAME, "\\"); + contentValues.put(StructuredName.GIVEN_NAME, ";"); + contentValues.put(StructuredName.MIDDLE_NAME, ","); + contentValues.put(StructuredName.PREFIX, "\n"); + contentValues.put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]"); + VCardVerificationHandler handler = new VCardVerificationHandler(this, version); + // Verifies the vCard String correctly escapes each character which must be escaped. + handler.addExpectedLine("N:\\\\;\\;;\\,;\\n;") + .addExpectedLine("FN:[<{Unescaped:Asciis}>]"); + handler.addNewVerifier() + .addNodeWithoutOrder("FN", "[<{Unescaped:Asciis}>]") + .addNodeWithoutOrder("N", Arrays.asList("\\", ";", ",", "\n", "")); + + verifyOneComposition(resolver, handler, version); + } } |
