FileDocCategorySizeDatePackage
VCardExporterTests.javaAPI DocAndroid 5.1 API61541Thu Mar 12 22:22:54 GMT 2015com.android.vcard.tests

VCardExporterTests

public class VCardExporterTests extends com.android.vcard.tests.testutils.VCardTestsBase
Tests for the code related to vCard exporter, inculding vCard composer. This test class depends on vCard importer code, so if tests for vCard importer fail, the result of this class will not be reliable.

Fields Summary
private static final byte[]
sPhotoByteArray
Constructors Summary
Methods Summary
private java.lang.StringgetAndroidPropValue(java.lang.String mimeType, java.lang.String value, java.lang.Integer type)

        return getAndroidPropValue(mimeType, value, type, null);
    
private java.lang.StringgetAndroidPropValue(java.lang.String mimeType, java.lang.String value, java.lang.Integer type, java.lang.String label)

        return (mimeType + ";" + value + ";"
                + (type != null ? type : "") + ";"
                + (label != null ? label : "") + ";;;;;;;;;;;;");
    
private voidtestEmailBasicCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "sample@example.com");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
            .addExpectedNode("EMAIL", "sample@example.com");
    
public voidtestEmailBasicV21()

        testEmailBasicCommon(V21);
    
public voidtestEmailBasicV30()

        testEmailBasicCommon(V30);
    
public voidtestEmailBasicV40()

        testEmailBasicCommon(V40);
    
private voidtestEmailPrefHandlingCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_home@example.com")
                .put(Email.TYPE, Email.TYPE_HOME)
                .put(Email.IS_PRIMARY, 1);
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_notype@example.com")
                .put(Email.IS_PRIMARY, 1);

        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("EMAIL", "type_notype@example.com", new TypeSet("PREF"))
                .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF"));
    
public voidtestEmailPrefHandlingV21()

        testEmailPrefHandlingCommon(V21);
    
public voidtestEmailPrefHandlingV30()

        testEmailPrefHandlingCommon(V30);
    
public voidtestEmailPrefHandlingV40()

        testEmailPrefHandlingCommon(V40);
    
private voidtestEmailVariousTypeSupportCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_home@example.com")
                .put(Email.TYPE, Email.TYPE_HOME);
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_work@example.com")
                .put(Email.TYPE, Email.TYPE_WORK);
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_mobile@example.com")
                .put(Email.TYPE, Email.TYPE_MOBILE);
        entry.addContentValues(Email.CONTENT_ITEM_TYPE)
                .put(Email.DATA, "type_other@example.com")
                .put(Email.TYPE, Email.TYPE_OTHER);
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME"))
                .addExpectedNode("EMAIL", "type_work@example.com", new TypeSet("WORK"))
                .addExpectedNode("EMAIL", "type_mobile@example.com", new TypeSet("CELL"))
                .addExpectedNode("EMAIL", "type_other@example.com");
    
public voidtestEmailVariousTypeSupportV21()

        testEmailVariousTypeSupportCommon(V21);
    
public voidtestEmailVariousTypeSupportV30()

        testEmailVariousTypeSupportCommon(V30);
    
public voidtestEmailVariousTypeSupportV40()

        testEmailVariousTypeSupportCommon(V40);
    
private voidtestEventCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                .put(Event.TYPE, Event.TYPE_ANNIVERSARY)
                .put(Event.START_DATE, "1982-06-16");
        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                .put(Event.TYPE, Event.TYPE_BIRTHDAY)
                .put(Event.START_DATE, "2008-10-22");
        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                .put(Event.TYPE, Event.TYPE_OTHER)
                .put(Event.START_DATE, "2018-03-12");
        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                .put(Event.TYPE, Event.TYPE_CUSTOM)
                .put(Event.LABEL, "The last day")
                .put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed.");
        entry.addContentValues(Event.CONTENT_ITEM_TYPE)
                .put(Event.TYPE, Event.TYPE_BIRTHDAY)
                .put(Event.START_DATE, "2009-05-19");  // Should be ignored.
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("BDAY", "2008-10-22")
                .addExpectedNode("X-ANDROID-CUSTOM",
                        getAndroidPropValue(
                                Event.CONTENT_ITEM_TYPE, "1982-06-16", Event.TYPE_ANNIVERSARY))
                .addExpectedNode("X-ANDROID-CUSTOM",
                        getAndroidPropValue(
                                Event.CONTENT_ITEM_TYPE, "2018-03-12", Event.TYPE_OTHER))
                .addExpectedNode("X-ANDROID-CUSTOM",
                        getAndroidPropValue(
                                Event.CONTENT_ITEM_TYPE,
                                "When the Tower of Hanoi with 64 rings is completed.",
                                Event.TYPE_CUSTOM, "The last day"));
    
public voidtestEventV21()

        testEventCommon(V21);
    
public voidtestEventV30()

        testEventCommon(V30);
    
public voidtestEventV40()

        testEventCommon(V40);
    
public voidtestImBasiV21()

        testImVariousTypeSupportCommon(V21);
    
public voidtestImBasicV30()

        testImVariousTypeSupportCommon(V30);
    
public voidtestImBasicV40()

        testImVariousTypeSupportCommon(V40);
    
private voidtestImPrefHandlingCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                .put(Im.DATA, "aim1");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                .put(Im.DATA, "aim2")
                .put(Im.TYPE, Im.TYPE_HOME)
                .put(Im.IS_PRIMARY, 1);

        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("X-AIM", "aim1")
                .addExpectedNode("X-AIM", "aim2", new TypeSet("HOME", "PREF"));
    
public voidtestImPrefHandlingV21()

        testImPrefHandlingCommon(V21);
    
public voidtestImPrefHandlingV30()

        testImPrefHandlingCommon(V30);
    
public voidtestImPrefHandlingV40()

        testImPrefHandlingCommon(V40);
    
private voidtestImVariousTypeSupportCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_AIM)
                .put(Im.DATA, "aim");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_MSN)
                .put(Im.DATA, "msn");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_YAHOO)
                .put(Im.DATA, "yahoo");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_SKYPE)
                .put(Im.DATA, "skype");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_QQ)
                .put(Im.DATA, "qq");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK)
                .put(Im.DATA, "google talk");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_ICQ)
                .put(Im.DATA, "icq");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_JABBER)
                .put(Im.DATA, "jabber");
        entry.addContentValues(Im.CONTENT_ITEM_TYPE)
                .put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING)
                .put(Im.DATA, "netmeeting");

        // No determined way to express unknown type...
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("X-JABBER", "jabber")
                .addExpectedNode("X-ICQ", "icq")
                .addExpectedNode("X-GOOGLE-TALK", "google talk")
                .addExpectedNode("X-QQ", "qq")
                .addExpectedNode("X-SKYPE-USERNAME", "skype")
                .addExpectedNode("X-YAHOO", "yahoo")
                .addExpectedNode("X-MSN", "msn")
                .addExpectedNode("X-NETMEETING", "netmeeting")
                .addExpectedNode("X-AIM", "aim");
    
private voidtestMiscPhoneTypeHandling(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "1")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "Modem");
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "2")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "MSG");
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "3")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "BBS");
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "4")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "VIDEO");
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "5")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "6")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "_AUTO_CELL");  // The old indicator for the type mobile.
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "7")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "\u643A\u5E2F");  // Mobile phone in Japanese Kanji
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "8")
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "invalid");
        PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
        if (VCardConfig.isVersion40(vcardType)) {
            // vCard 4.0 (rev.13) does not allow bare number but URI.
            elem.addExpectedNode("TEL", "tel:1", new TypeSet("Modem"))
                    .addExpectedNode("TEL", "tel:2", new TypeSet("MSG"))
                    .addExpectedNode("TEL", "tel:3", new TypeSet("BBS"))
                    .addExpectedNode("TEL", "tel:4", new TypeSet("VIDEO"))
                    .addExpectedNode("TEL", "tel:5", new TypeSet("VOICE"))
                    .addExpectedNode("TEL", "tel:6", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "tel:7", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "tel:8", new TypeSet("invalid"));
        } else if (VCardConfig.isVersion30(vcardType)) {
            // vCard 3.0 accepts "invalid". Also stop using toUpper()
            elem.addExpectedNode("TEL", "1", new TypeSet("Modem"))
                    .addExpectedNode("TEL", "2", new TypeSet("MSG"))
                    .addExpectedNode("TEL", "3", new TypeSet("BBS"))
                    .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
                    .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
                    .addExpectedNode("TEL", "6", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "7", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "8", new TypeSet("invalid"));
        } else {
            elem.addExpectedNode("TEL", "1", new TypeSet("MODEM"))
                    .addExpectedNode("TEL", "2", new TypeSet("MSG"))
                    .addExpectedNode("TEL", "3", new TypeSet("BBS"))
                    .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
                    .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
                    .addExpectedNode("TEL", "6", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "7", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "8", new TypeSet("X-invalid"));
        }
    
public voidtestNickNameV21()
There's no "NICKNAME" property in vCard 2.1, while there is in vCard 3.0. We use Android-specific "X-ANDROID-CUSTOM" property. This test verifies the functionality.

        mVerifier.initForExportTest(V21);
        mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
                .put(Nickname.NAME, "Nicky");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("X-ANDROID-CUSTOM",
                        Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;");
        mVerifier.addContentValuesVerifierElem().addExpected(Nickname.CONTENT_ITEM_TYPE)
                .put(Nickname.NAME, "Nicky");
    
public voidtestNickNameV30()

        mVerifier.initForExportTest(V30);
        mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
                .put(Nickname.NAME, "Nicky");

        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
            .addExpectedNodeWithOrder("NICKNAME", "Nicky");
    
public voidtestNickNameV40()

        mVerifier.initForExportTest(V40);
        mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
                .put(Nickname.NAME, "Nicky");

        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
            .addExpectedNodeWithOrder("NICKNAME", "Nicky");
    
private voidtestNoteCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                .put(Note.NOTE, "note1");
        entry.addContentValues(Note.CONTENT_ITEM_TYPE)
                .put(Note.NOTE, "note2")
                .put(Note.IS_PRIMARY, 1);  // Just ignored.
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNodeWithOrder("NOTE", "note1")
                .addExpectedNodeWithOrder("NOTE", "note2");
    
public voidtestNoteV21()

        testNoteCommon(V21);
    
public voidtestNoteV30()

        testNoteCommon(V30);
    
public voidtestNoteV40()

        testNoteCommon(V40);
    
private voidtestOrganizationCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                .put(Organization.COMPANY, "CompanyX")
                .put(Organization.DEPARTMENT, "DepartmentY")
                .put(Organization.TITLE, "TitleZ")
                .put(Organization.JOB_DESCRIPTION, "Description Rambda")  // Ignored.
                .put(Organization.OFFICE_LOCATION, "Mountain View")  // Ignored.
                .put(Organization.PHONETIC_NAME, "PhoneticName!")  // Ignored
                .put(Organization.SYMBOL, "(^o^)/~~");  // Ignore him (her).
        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                .putNull(Organization.COMPANY)
                .put(Organization.DEPARTMENT, "DepartmentXX")
                .putNull(Organization.TITLE);
        entry.addContentValues(Organization.CONTENT_ITEM_TYPE)
                .put(Organization.COMPANY, "CompanyXYZ")
                .putNull(Organization.DEPARTMENT)
                .put(Organization.TITLE, "TitleXYZYX");
        // Currently we do not use group but depend on the order.
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNodeWithOrder("ORG", "CompanyX;DepartmentY",
                        Arrays.asList("CompanyX", "DepartmentY"))
                .addExpectedNodeWithOrder("TITLE", "TitleZ")
                .addExpectedNodeWithOrder("ORG", "DepartmentXX")
                .addExpectedNodeWithOrder("ORG", "CompanyXYZ")
                .addExpectedNodeWithOrder("TITLE", "TitleXYZYX");
    
public voidtestOrganizationV21()

        testOrganizationCommon(V21);
    
public voidtestOrganizationV30()

        testOrganizationCommon(V30);
    
public voidtestOrganizationV40()

        testOrganizationCommon(V40);
    
public voidtestPauseAndWaitConversionV30()

        mVerifier.initForExportTest(V30);
        final ContactEntry entry = mVerifier.addInputEntry();
        // Insert numbers with PAUSE (',' internally, 'p' for outside) and
        // WAIT (';' internally, 'w' for outside)
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.TYPE, Phone.TYPE_HOME)
                .put(Phone.NUMBER, "111,222;333");
        mVerifier.addLineVerifierElem()
                .addExpected("N:")
                .addExpected("FN:")
                .addExpected("TEL;TYPE=HOME:111p222w333");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("TEL", "111p222w333", new TypeSet("HOME"));
    
private voidtestPhoneBasicCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "1")
                .put(Phone.TYPE, Phone.TYPE_HOME);
        if (VCardConfig.isVersion40(vcardType)) {
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "tel:1", new TypeSet("HOME"));
        } else {
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "1", new TypeSet("HOME"));
        }
    
public voidtestPhoneBasicV21()

        testPhoneBasicCommon(V21);
    
public voidtestPhoneBasicV30()

        testPhoneBasicCommon(V30);
    
public voidtestPhoneBasicV40()

        testPhoneBasicCommon(V40);
    
private voidtestPhonePrefHandlingCommon(int vcardType)
Tests that "PREF"s are emitted appropriately.

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "1")
                .put(Phone.TYPE, Phone.TYPE_HOME);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "2")
                .put(Phone.TYPE, Phone.TYPE_WORK)
                .put(Phone.IS_PRIMARY, 1);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "3")
                .put(Phone.TYPE, Phone.TYPE_FAX_HOME)
                .put(Phone.IS_PRIMARY, 1);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "4")
                .put(Phone.TYPE, Phone.TYPE_FAX_WORK);

        if (VCardConfig.isVersion40(vcardType)) {
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "tel:4", new TypeSet("WORK", "FAX"))
                    .addExpectedNode("TEL", "tel:3", new TypeSet("HOME", "FAX", "PREF"))
                    .addExpectedNode("TEL", "tel:2", new TypeSet("WORK", "PREF"))
                    .addExpectedNode("TEL", "tel:1", new TypeSet("HOME"));
        } else {
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "4", new TypeSet("WORK", "FAX"))
                    .addExpectedNode("TEL", "3", new TypeSet("HOME", "FAX", "PREF"))
                    .addExpectedNode("TEL", "2", new TypeSet("WORK", "PREF"))
                    .addExpectedNode("TEL", "1", new TypeSet("HOME"));
        }
    
public voidtestPhonePrefHandlingV21()

        testPhonePrefHandlingCommon(V21);
    
public voidtestPhonePrefHandlingV30()

        testPhonePrefHandlingCommon(V30);
    
public voidtestPhonePrefHandlingV40()

        testPhonePrefHandlingCommon(V40);
    
public voidtestPhoneRefrainFormatting()

        mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING);
        mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)")
                .put(Phone.TYPE, Phone.TYPE_HOME);
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)",
                        new TypeSet("HOME"));
    
public voidtestPhoneTypeHandlingV21()

        testMiscPhoneTypeHandling(V21);
    
public voidtestPhoneTypeHandlingV30()

        testMiscPhoneTypeHandling(V30);
    
public voidtestPhoneTypeHandlingV40()

        testMiscPhoneTypeHandling(V40);
    
private voidtestPhoneVariousTypeSupport(int vcardType)
Tests that vCard composer emits corresponding type param which we expect.

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "10")
                .put(Phone.TYPE, Phone.TYPE_HOME);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "20")
                .put(Phone.TYPE, Phone.TYPE_WORK);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "30")
                .put(Phone.TYPE, Phone.TYPE_FAX_HOME);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "40")
                .put(Phone.TYPE, Phone.TYPE_FAX_WORK);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "50")
                .put(Phone.TYPE, Phone.TYPE_MOBILE);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "60")
                .put(Phone.TYPE, Phone.TYPE_PAGER);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "70")
                .put(Phone.TYPE, Phone.TYPE_OTHER);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "80")
                .put(Phone.TYPE, Phone.TYPE_CAR);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "90")
                .put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "100")
                .put(Phone.TYPE, Phone.TYPE_ISDN);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "110")
                .put(Phone.TYPE, Phone.TYPE_MAIN);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "120")
                .put(Phone.TYPE, Phone.TYPE_OTHER_FAX);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "130")
                .put(Phone.TYPE, Phone.TYPE_TELEX);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "140")
                .put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "150")
                .put(Phone.TYPE, Phone.TYPE_WORK_PAGER);
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.NUMBER, "160")
                .put(Phone.TYPE, Phone.TYPE_MMS);

        if (VCardConfig.isVersion40(vcardType)) {
            // Currently pager type has special logic...
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "tel:10", new TypeSet("HOME"))
                    .addExpectedNode("TEL", "tel:20", new TypeSet("WORK"))
                    .addExpectedNode("TEL", "tel:30", new TypeSet("HOME", "FAX"))
                    .addExpectedNode("TEL", "tel:40", new TypeSet("WORK", "FAX"))
                    .addExpectedNode("TEL", "tel:50", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "60", new TypeSet("PAGER"))
                    .addExpectedNode("TEL", "tel:70", new TypeSet("VOICE"))
                    .addExpectedNode("TEL", "tel:80", new TypeSet("CAR"))
                    .addExpectedNode("TEL", "tel:90", new TypeSet("WORK", "PREF"))
                    .addExpectedNode("TEL", "tel:100", new TypeSet("ISDN"))
                    .addExpectedNode("TEL", "tel:110", new TypeSet("PREF"))
                    .addExpectedNode("TEL", "tel:120", new TypeSet("FAX"))
                    .addExpectedNode("TEL", "tel:130", new TypeSet("TLX"))
                    .addExpectedNode("TEL", "tel:140", new TypeSet("WORK", "CELL"))
                    .addExpectedNode("TEL", "tel:150", new TypeSet("WORK", "PAGER"))
                    .addExpectedNode("TEL", "tel:160", new TypeSet("MSG"));
        } else {
            mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                    .addExpectedNode("TEL", "10", new TypeSet("HOME"))
                    .addExpectedNode("TEL", "20", new TypeSet("WORK"))
                    .addExpectedNode("TEL", "30", new TypeSet("HOME", "FAX"))
                    .addExpectedNode("TEL", "40", new TypeSet("WORK", "FAX"))
                    .addExpectedNode("TEL", "50", new TypeSet("CELL"))
                    .addExpectedNode("TEL", "60", new TypeSet("PAGER"))
                    .addExpectedNode("TEL", "70", new TypeSet("VOICE"))
                    .addExpectedNode("TEL", "80", new TypeSet("CAR"))
                    .addExpectedNode("TEL", "90", new TypeSet("WORK", "PREF"))
                    .addExpectedNode("TEL", "100", new TypeSet("ISDN"))
                    .addExpectedNode("TEL", "110", new TypeSet("PREF"))
                    .addExpectedNode("TEL", "120", new TypeSet("FAX"))
                    .addExpectedNode("TEL", "130", new TypeSet("TLX"))
                    .addExpectedNode("TEL", "140", new TypeSet("WORK", "CELL"))
                    .addExpectedNode("TEL", "150", new TypeSet("WORK", "PAGER"))
                    .addExpectedNode("TEL", "160", new TypeSet("MSG"));
        }
    
public voidtestPhoneVariousTypeSupportV21()

        testPhoneVariousTypeSupport(V21);
    
public voidtestPhoneVariousTypeSupportV30()

        testPhoneVariousTypeSupport(V30);
    
public voidtestPhoneVariousTypeSupportV40()

        testPhoneVariousTypeSupport(V40);
    
private voidtestPhotoCommon(int vcardType)

        final boolean useB =
            (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType));
        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "PhotoTest");
        entry.addContentValues(Photo.CONTENT_ITEM_TYPE)
                .put(Photo.PHOTO, sPhotoByteArray);

        ContentValues contentValuesForPhoto = new ContentValues();
        contentValuesForPhoto.put("ENCODING", (useB ? "b" : "BASE64"));
        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNode("FN", "PhotoTest")
                .addExpectedNode("N", "PhotoTest;;;;",
                        Arrays.asList("PhotoTest", "", "", "", ""))
                .addExpectedNodeWithOrder("PHOTO", null, null, sPhotoByteArray,
                        contentValuesForPhoto, new TypeSet("JPEG"), null);
    
public voidtestPhotoV21()

        testPhotoCommon(V21);
    
public voidtestPhotoV30()

        testPhotoCommon(V30);
    
public voidtestPhotoV40()

        testPhotoCommon(V40);
    
private voidtestPickUpNonEmptyContentValuesCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.IS_PRIMARY, 1);  // Empty name. Should be ignored.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "family1")  // Not primary. Should be ignored.
                .put(StructuredName.DISPLAY_NAME, "display");
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.IS_PRIMARY, 1)
                .put(StructuredName.FAMILY_NAME, "family2")  // This entry is what we want.
                .put(StructuredName.DISPLAY_NAME, "display");
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.IS_PRIMARY, 1)
                .put(StructuredName.FAMILY_NAME, "family3")
                .put(StructuredName.DISPLAY_NAME, "display");
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "family4")
                .put(StructuredName.DISPLAY_NAME, "display");
        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNode("N", Arrays.asList("family2", "", "", "", ""))
                .addExpectedNode("FN", "display");
    
public voidtestPickUpNonEmptyContentValuesV21()

        testPickUpNonEmptyContentValuesCommon(V21);
    
public voidtestPickUpNonEmptyContentValuesV30()

        testPickUpNonEmptyContentValuesCommon(V30);
    
public voidtestPickUpNonEmptyContentValuesV40()

        testPickUpNonEmptyContentValuesCommon(V40);
    
private voidtestPostalAddressCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                .put(StructuredPostal.POBOX, "Pobox")
                .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood")
                .put(StructuredPostal.STREET, "Street")
                .put(StructuredPostal.CITY, "City")
                .put(StructuredPostal.REGION, "Region")
                .put(StructuredPostal.POSTCODE, "100")
                .put(StructuredPostal.COUNTRY, "Country")
                .put(StructuredPostal.FORMATTED_ADDRESS, "Formatted Address")
                .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK);
        // adr-value    = 0*6(text-value ";") text-value
        //              ; PO Box, Extended Address, Street, Locality, Region, Postal Code,
        //              ; Country Name
        //
        // The NEIGHBORHOOD field is appended after the CITY field.
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("ADR",
                        Arrays.asList("Pobox", "", "Street", "City Neighborhood",
                                "Region", "100", "Country"), new TypeSet("WORK"));
    
private voidtestPostalAddressNonCity(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("ADR",
                        Arrays.asList("", "", "", "Neighborhood", "", "", ""), new TypeSet("HOME"));
    
public voidtestPostalAddressNonCityV21()

        testPostalAddressNonCity(V21);
    
public voidtestPostalAddressNonCityV30()

        testPostalAddressNonCity(V30);
    
public voidtestPostalAddressNonCityV40()

        testPostalAddressNonCity(V40);
    
private voidtestPostalAddressNonNeighborhood(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                .put(StructuredPostal.CITY, "City");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("ADR",
                        Arrays.asList("", "", "", "City", "", "", ""), new TypeSet("HOME"));
    
public voidtestPostalAddressNonNeighborhoodV21()

        testPostalAddressNonNeighborhood(V21);
    
public voidtestPostalAddressNonNeighborhoodV30()

        testPostalAddressNonNeighborhood(V30);
    
public voidtestPostalAddressNonNeighborhoodV40()

        testPostalAddressNonNeighborhood(V40);
    
public voidtestPostalAddressV21()

        testPostalAddressCommon(V21);
    
public voidtestPostalAddressV30()

        testPostalAddressCommon(V30);
    
public voidtestPostalAddressV40()

        testPostalAddressCommon(V40);
    
private voidtestPostalOnlyWithFormattedAddressCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                .put(StructuredPostal.REGION, "")  // Must be ignored.
                .put(StructuredPostal.FORMATTED_ADDRESS,
                "Formatted address CA 123-334 United Statue");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;",
                        Arrays.asList("", "Formatted address CA 123-334 United Statue",
                                "", "", "", "", ""), new TypeSet("HOME"));
    
public voidtestPostalOnlyWithFormattedAddressV21()

        testPostalOnlyWithFormattedAddressCommon(V21);
    
public voidtestPostalOnlyWithFormattedAddressV30()

        testPostalOnlyWithFormattedAddressCommon(V30);
    
public voidtestPostalOnlyWithFormattedAddressV40()

        testPostalOnlyWithFormattedAddressCommon(V40);
    
private voidtestPostalWithBothStructuredAndFormattedCommon(int vcardType)
Tests that the vCard composer honors formatted data when it is available even when it is partial.

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
                .put(StructuredPostal.POBOX, "Pobox")
                .put(StructuredPostal.COUNTRY, "Country")
                .put(StructuredPostal.FORMATTED_ADDRESS,
                        "Formatted address CA 123-334 United Statue");  // Should be ignored
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("ADR", "Pobox;;;;;;Country",
                        Arrays.asList("Pobox", "", "", "", "", "", "Country"),
                        new TypeSet("HOME"));
    
public voidtestPostalWithBothStructuredAndFormattedV21()

        testPostalWithBothStructuredAndFormattedCommon(V21);
    
public voidtestPostalWithBothStructuredAndFormattedV30()

        testPostalWithBothStructuredAndFormattedCommon(V30);
    
public voidtestPostalWithBothStructuredAndFormattedV40()

        testPostalWithBothStructuredAndFormattedCommon(V40);
    
private voidtestRelationCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE)
                .put(Relation.TYPE, Relation.TYPE_MOTHER)
                .put(Relation.NAME, "Ms. Mother");
        mVerifier.addContentValuesVerifierElem().addExpected(Relation.CONTENT_ITEM_TYPE)
                .put(Relation.TYPE, Relation.TYPE_MOTHER)
                .put(Relation.NAME, "Ms. Mother");
    
public voidtestRelationV21()

        testRelationCommon(V21);
    
public voidtestRelationV30()

        testRelationCommon(V30);
    
public voidtestSimpleV21()


       
        mVerifier.initForExportTest(V21);
        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "Ando")
                .put(StructuredName.GIVEN_NAME, "Roid");
        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNode("FN", "Roid Ando")
                .addExpectedNode("N", "Ando;Roid;;;",
                        Arrays.asList("Ando", "Roid", "", "", ""));
    
public voidtestSipAddressV21()

        mVerifier.initForExportTest(V21);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE)
                .put(SipAddress.SIP_ADDRESS, "gold");
        mVerifier.addLineVerifierElem()
                .addExpected("X-SIP:gold");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("X-SIP", "gold");
    
public voidtestSipAddressV30()

        mVerifier.initForExportTest(V30);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE)
                .put(SipAddress.SIP_ADDRESS, "android@example.com");
        mVerifier.addLineVerifierElem()
                .addExpected("N:")
                .addExpected("FN:")
                .addExpected("IMPP:sip:android@example.com");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("IMPP", "sip:android@example.com");
    
public voidtestSipAddressV40()

        mVerifier.initForExportTest(V40);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE)
                .put(SipAddress.SIP_ADDRESS, "android@example.com");
        mVerifier.addLineVerifierElem()
                .addExpected("FN:")
                .addExpected("TEL:sip:android@example.com");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("TEL", "sip:android@example.com");
    
private voidtestStructuredNameBasic(int vcardType)

        mVerifier.initForExportTest(vcardType);
        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
                .put(StructuredName.PREFIX, "AppropriatePrefix")
                .put(StructuredName.SUFFIX, "AppropriateSuffix")
                .put(StructuredName.DISPLAY_NAME, "DISPLAY NAME");

        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNodeWithOrder("N",
                        "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                        + "AppropriatePrefix;AppropriateSuffix",
                        Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                                "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
                .addExpectedNodeWithOrder("FN", "DISPLAY NAME");
    
public voidtestStructuredNameBasicV21()

        testStructuredNameBasic(V21);
    
public voidtestStructuredNameBasicV30()

        testStructuredNameBasic(V30);
    
public voidtestStructuredNameBasicV40()

        testStructuredNameBasic(V40);
    
private voidtestStructuredNameComplicatedCommon(int vcardType)
Confirms all the other sides of the handling is correctly interpreted at one time. A kind of regression test for StructuredName handling.

        mVerifier.initForExportTest(vcardType);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix1")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix1")
                .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1")
                .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1")
                .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");

        // With "IS_PRIMARY=1", but we should ignore this time.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix2")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix2")
                .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2")
                .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2")
                .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2")
                .put(StructuredName.IS_PRIMARY, 1);

        // With "IS_SUPER_PRIMARY=1". This is what we should use.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
                .put(StructuredName.PREFIX, "AppropriatePrefix")
                .put(StructuredName.SUFFIX, "AppropriateSuffix")
                .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily")
                .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
                .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle")
                .put(StructuredName.IS_SUPER_PRIMARY, 1);

        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix3")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix3")
                .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily3")
                .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven3")
                .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3")
                .put(StructuredName.IS_PRIMARY, 1);

        final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
        if (VCardConfig.isVersion40(vcardType)) {
            final ContentValues contentValues = new ContentValues();
            contentValues.put("SORT-AS",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName");
            // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with
            // either 2.1 nor 3.0.
            elem.addExpectedNodeWithOrder("N",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                    + "AppropriatePrefix;AppropriateSuffix",
                    Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                            "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"),
                    contentValues);
        } else {
            elem.addExpectedNodeWithOrder("N",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                    + "AppropriatePrefix;AppropriateSuffix",
                    Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                            "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));
            if (VCardConfig.isVersion30(vcardType)) {
                elem.addExpectedNode("SORT-STRING",
                        "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
                        + " AppropriatePhoneticFamily");
            }
        }

        elem.addExpectedNodeWithOrder("FN",
                "AppropriatePrefix AppropriateGivenName "
                + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
            .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
            .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
            .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
    
public voidtestStructuredNameComplicatedV21()

        testStructuredNameComplicatedCommon(V21);
    
public voidtestStructuredNameComplicatedV30()

        testStructuredNameComplicatedCommon(V30);
    
public voidtestStructuredNameComplicatedV40()

        testStructuredNameComplicatedCommon(V40);
    
private voidtestStructuredNamePhoneticNameCommon(int vcardType)
Tests phonetic names field are handled correctly. vCard 2.1 does not have any field corresponding to them. vCard 3.0 has SORT-STRING property, which does not support multiple values inside it. vCard 4.0 (rev13) has SORT-AS parameter, which has three values (family, given, middle) inside it.

        mVerifier.initForExportTest(vcardType);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
                .put(StructuredName.PREFIX, "AppropriatePrefix")
                .put(StructuredName.SUFFIX, "AppropriateSuffix")
                .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
                .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily")
                .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
                .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");

        final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
        if (VCardConfig.isVersion40(vcardType)) {
            final ContentValues contentValues = new ContentValues();
            contentValues.put("SORT-AS",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName");
            // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with
            // either 2.1 nor 3.0.
            elem.addExpectedNodeWithOrder("N",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                    + "AppropriatePrefix;AppropriateSuffix",
                    Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                            "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"),
                    contentValues);
        } else {
            elem.addExpectedNodeWithOrder("N",
                    "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                    + "AppropriatePrefix;AppropriateSuffix",
                    Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                            "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));
            if (VCardConfig.isVersion30(vcardType)) {
                elem.addExpectedNode("SORT-STRING",
                        "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
                        + " AppropriatePhoneticFamily");
            }
        }

        elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName")
            .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
            .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
            .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
    
public voidtestStructuredNamePhoneticNameV21()

        testStructuredNamePhoneticNameCommon(V21);
    
public voidtestStructuredNamePhoneticNameV30()

        testStructuredNamePhoneticNameCommon(V30);
    
public voidtestStructuredNamePhoneticNameV40()

        testStructuredNamePhoneticNameCommon(V40);
    
private voidtestStructuredNameUsePrimaryCommon(int vcardType)
Test that only "primary" StructuredName is emitted, so that our vCard file will not confuse the external importer, assuming there may be some importer which presume that there's only one property toward each of "N", "FN", etc. Note that more than one "N", "FN", etc. properties are acceptable in vCard spec.

        mVerifier.initForExportTest(vcardType);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix1")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix1")
                .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName1");

        // With "IS_PRIMARY=1". This is what we should use.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
                .put(StructuredName.PREFIX, "AppropriatePrefix")
                .put(StructuredName.SUFFIX, "AppropriateSuffix")
                .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
                .put(StructuredName.IS_PRIMARY, 1);

        // With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first.
        // vCard 2.1 does not specify anything about the number of N properties. We choose not
        // emitting this property.
        // vCard 3.0 does (There must be one N property)
        // vCard 4.0 (rev13) does (cardinality (0, 1)).
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix2")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix2")
                .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName2")
                .put(StructuredName.IS_PRIMARY, 1);

       mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNodeWithOrder("N",
                        "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                        + "AppropriatePrefix;AppropriateSuffix",
                        Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                                "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
                .addExpectedNodeWithOrder("FN", "AppropriateDisplayName");
    
public voidtestStructuredNameUsePrimaryV21()

        testStructuredNameUsePrimaryCommon(V21);
    
public voidtestStructuredNameUsePrimaryV30()

        testStructuredNameUsePrimaryCommon(V30);
    
public voidtestStructuredNameUsePrimaryV40()

        testStructuredNameUsePrimaryCommon(V40);
    
private voidtestStructuredNameUseSuperPrimaryCommon(int vcardType)
Tests that only "super primary" StructuredName is emitted. See also the comment in {@link #testStructuredNameUsePrimaryCommon(int)}.

        mVerifier.initForExportTest(vcardType);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix1")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix1")
                .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay1");

        // With "IS_PRIMARY=1", but we should ignore this time.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix2")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix2")
                .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay2")
                .put(StructuredName.IS_PRIMARY, 1);

        // With "IS_SUPER_PRIMARY=1". This is what we should use.
        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
                .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
                .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
                .put(StructuredName.PREFIX, "AppropriatePrefix")
                .put(StructuredName.SUFFIX, "AppropriateSuffix")
                .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
                .put(StructuredName.IS_SUPER_PRIMARY, 1);

        entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3")
                .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3")
                .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3")
                .put(StructuredName.PREFIX, "DoNotEmitPrefix3")
                .put(StructuredName.SUFFIX, "DoNotEmitSuffix3")
                .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay3")
                .put(StructuredName.IS_PRIMARY, 1);

        final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
        elem.addExpectedNodeWithOrder("N",
                "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
                + "AppropriatePrefix;AppropriateSuffix",
                Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
                        "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));

        elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName");
    
public voidtestStructuredNameUseSuperPrimaryV21()

        testStructuredNameUseSuperPrimaryCommon(V21);
    
public voidtestStructuredNameUseSuperPrimaryV30()

        testStructuredNameUseSuperPrimaryCommon(V30);
    
public voidtestStructuredNameUseSuperPrimaryV40()

        testStructuredNameUseSuperPrimaryCommon(V40);
    
public voidtestTolerateBrokenPhoneNumberEntryV21()

        mVerifier.initForExportTest(V21);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.TYPE, Phone.TYPE_HOME)
                .put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo)\n"
                        + "777-888-9999 (Chicago)\n111-222-3333 (Miami)");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("TEL", "111-222-3333", new TypeSet("HOME"))
                .addExpectedNode("TEL", "444-555-5666", new TypeSet("HOME"))
                .addExpectedNode("TEL", "777-888-9999", new TypeSet("HOME"));
    
public voidtestUseMultiByteTypeV30()

        mVerifier.initForExportTest(V30);
        final ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
                .put(Phone.TYPE, Phone.TYPE_CUSTOM)
                .put(Phone.LABEL, "\u96FB\u8A71")
                .put(Phone.NUMBER, "1");
        mVerifier.addLineVerifierElem()
                .addExpected("N:")
                .addExpected("FN:")
                .addExpected("TEL;TYPE=\u96FB\u8A71:1");
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("TEL", "1", new TypeSet("\u96FB\u8A71"));
    
public voidtestV30HandleEscape()

        mVerifier.initForExportTest(V30);
        mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
                .put(StructuredName.FAMILY_NAME, "\\")
                .put(StructuredName.GIVEN_NAME, ";")
                .put(StructuredName.MIDDLE_NAME, ",")
                .put(StructuredName.PREFIX, "\n")
                .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]");
        // Verifies the vCard String correctly escapes each character which must be escaped.
        mVerifier.addLineVerifierElem()
                .addExpected("N:\\\\;\\;;\\,;\\n;")
                .addExpected("FN:[<{Unescaped:Asciis}>]");
        mVerifier.addPropertyNodesVerifierElem()
                .addExpectedNode("FN", "[<{Unescaped:Asciis}>]")
                .addExpectedNode("N", Arrays.asList("\\", ";", ",", "\n", ""));
    
private voidtestWebsiteCommon(int vcardType)

        mVerifier.initForExportTest(vcardType);
        ContactEntry entry = mVerifier.addInputEntry();
        entry.addContentValues(Website.CONTENT_ITEM_TYPE)
                .put(Website.URL, "http://website.example.android.com/index.html")
                .put(Website.TYPE, Website.TYPE_BLOG);
        entry.addContentValues(Website.CONTENT_ITEM_TYPE)
                .put(Website.URL, "ftp://ftp.example.android.com/index.html")
                .put(Website.TYPE, Website.TYPE_FTP);

        // We drop TYPE information since vCard (especially 3.0) does not allow us to emit it.
        mVerifier.addPropertyNodesVerifierElemWithEmptyName()
                .addExpectedNode("URL", "ftp://ftp.example.android.com/index.html")
                .addExpectedNode("URL", "http://website.example.android.com/index.html");
    
public voidtestWebsiteV21()

        testWebsiteCommon(V21);
    
public voidtestWebsiteV30()

        testWebsiteCommon(V30);
    
public voidtestWebsiteV40()

        testWebsiteCommon(V40);