VCardExporterTests.java revision 237dd947f2e22d34f490bf35ef4b850d05cfffa9
1/* 2 * Copyright (C) 2009 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 17package com.android.vcard.tests; 18 19import android.content.ContentValues; 20import android.provider.ContactsContract.CommonDataKinds.Email; 21import android.provider.ContactsContract.CommonDataKinds.Event; 22import android.provider.ContactsContract.CommonDataKinds.Im; 23import android.provider.ContactsContract.CommonDataKinds.Nickname; 24import android.provider.ContactsContract.CommonDataKinds.Note; 25import android.provider.ContactsContract.CommonDataKinds.Organization; 26import android.provider.ContactsContract.CommonDataKinds.Phone; 27import android.provider.ContactsContract.CommonDataKinds.Photo; 28import android.provider.ContactsContract.CommonDataKinds.Relation; 29import android.provider.ContactsContract.CommonDataKinds.StructuredName; 30import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 31import android.provider.ContactsContract.CommonDataKinds.Website; 32 33import com.android.vcard.VCardConfig; 34import com.android.vcard.tests.test_utils.ContactEntry; 35import com.android.vcard.tests.test_utils.PropertyNodesVerifierElem; 36import com.android.vcard.tests.test_utils.PropertyNodesVerifierElem.TypeSet; 37import com.android.vcard.tests.test_utils.VCardTestsBase; 38 39import java.util.Arrays; 40 41/** 42 * Tests for the code related to vCard exporter, inculding vCard composer. 43 * This test class depends on vCard importer code, so if tests for vCard importer fail, 44 * the result of this class will not be reliable. 45 */ 46public class VCardExporterTests extends VCardTestsBase { 47 private static final byte[] sPhotoByteArray = 48 VCardImporterTests.sPhotoByteArrayForComplicatedCase; 49 50 public void testSimpleV21() { 51 mVerifier.initForExportTest(V21); 52 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 53 .put(StructuredName.FAMILY_NAME, "Ando") 54 .put(StructuredName.GIVEN_NAME, "Roid"); 55 mVerifier.addPropertyNodesVerifierElem() 56 .addExpectedNode("FN", "Roid Ando") 57 .addExpectedNode("N", "Ando;Roid;;;", 58 Arrays.asList("Ando", "Roid", "", "", "")); 59 } 60 61 private void testStructuredNameBasic(int vcardType) { 62 final boolean isV21 = VCardConfig.isVersion21(vcardType); 63 mVerifier.initForExportTest(vcardType); 64 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 65 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 66 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 67 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 68 .put(StructuredName.PREFIX, "AppropriatePrefix") 69 .put(StructuredName.SUFFIX, "AppropriateSuffix") 70 .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily") 71 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven") 72 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle"); 73 74 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem() 75 .addExpectedNodeWithOrder("N", 76 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 77 + "AppropriatePrefix;AppropriateSuffix", 78 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 79 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")) 80 .addExpectedNodeWithOrder("FN", 81 "AppropriatePrefix AppropriateGivenName " 82 + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix") 83 .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven") 84 .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle") 85 .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily"); 86 87 if (!isV21) { 88 elem.addExpectedNode("SORT-STRING", 89 "AppropriatePhoneticGiven AppropriatePhoneticMiddle " 90 + "AppropriatePhoneticFamily"); 91 } 92 } 93 94 public void testStructuredNameBasicV21() { 95 testStructuredNameBasic(V21); 96 } 97 98 public void testStructuredNameBasicV30() { 99 testStructuredNameBasic(V30); 100 } 101 102 /** 103 * Test that only "primary" StructuredName is emitted, so that our vCard file 104 * will not confuse the external importer, assuming there may be some importer 105 * which presume that there's only one property toward each of "N", "FN", etc. 106 * Note that more than one "N", "FN", etc. properties are acceptable in vCard spec. 107 */ 108 private void testStructuredNameUsePrimaryCommon(int vcardType) { 109 final boolean isV30 = (vcardType == V30); 110 mVerifier.initForExportTest(vcardType); 111 ContactEntry entry = mVerifier.addInputEntry(); 112 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 113 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1") 114 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1") 115 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1") 116 .put(StructuredName.PREFIX, "DoNotEmitPrefix1") 117 .put(StructuredName.SUFFIX, "DoNotEmitSuffix1") 118 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1") 119 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1") 120 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1"); 121 122 // With "IS_PRIMARY=1". This is what we should use. 123 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 124 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 125 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 126 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 127 .put(StructuredName.PREFIX, "AppropriatePrefix") 128 .put(StructuredName.SUFFIX, "AppropriateSuffix") 129 .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily") 130 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven") 131 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle") 132 .put(StructuredName.IS_PRIMARY, 1); 133 134 // With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first. 135 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 136 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2") 137 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2") 138 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2") 139 .put(StructuredName.PREFIX, "DoNotEmitPrefix2") 140 .put(StructuredName.SUFFIX, "DoNotEmitSuffix2") 141 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2") 142 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2") 143 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2") 144 .put(StructuredName.IS_PRIMARY, 1); 145 146 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem() 147 .addExpectedNodeWithOrder("N", 148 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 149 + "AppropriatePrefix;AppropriateSuffix", 150 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 151 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")) 152 .addExpectedNodeWithOrder("FN", 153 "AppropriatePrefix AppropriateGivenName " 154 + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix") 155 .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven") 156 .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle") 157 .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily"); 158 159 if (isV30) { 160 elem.addExpectedNode("SORT-STRING", 161 "AppropriatePhoneticGiven AppropriatePhoneticMiddle " 162 + "AppropriatePhoneticFamily"); 163 } 164 } 165 166 public void testStructuredNameUsePrimaryV21() { 167 testStructuredNameUsePrimaryCommon(V21); 168 } 169 170 public void testStructuredNameUsePrimaryV30() { 171 testStructuredNameUsePrimaryCommon(V30); 172 } 173 174 /** 175 * Tests that only "super primary" StructuredName is emitted. 176 * See also the comment in {@link #testStructuredNameUsePrimaryCommon(int)}. 177 */ 178 private void testStructuredNameUseSuperPrimaryCommon(int vcardType) { 179 final boolean isV30 = (vcardType == V30); 180 mVerifier.initForExportTest(vcardType); 181 ContactEntry entry = mVerifier.addInputEntry(); 182 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 183 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1") 184 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1") 185 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1") 186 .put(StructuredName.PREFIX, "DoNotEmitPrefix1") 187 .put(StructuredName.SUFFIX, "DoNotEmitSuffix1") 188 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1") 189 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1") 190 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1"); 191 192 // With "IS_PRIMARY=1", but we should ignore this time. 193 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 194 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2") 195 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2") 196 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2") 197 .put(StructuredName.PREFIX, "DoNotEmitPrefix2") 198 .put(StructuredName.SUFFIX, "DoNotEmitSuffix2") 199 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2") 200 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2") 201 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2") 202 .put(StructuredName.IS_PRIMARY, 1); 203 204 // With "IS_SUPER_PRIMARY=1". This is what we should use. 205 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 206 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 207 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 208 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 209 .put(StructuredName.PREFIX, "AppropriatePrefix") 210 .put(StructuredName.SUFFIX, "AppropriateSuffix") 211 .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily") 212 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven") 213 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle") 214 .put(StructuredName.IS_SUPER_PRIMARY, 1); 215 216 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 217 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3") 218 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3") 219 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3") 220 .put(StructuredName.PREFIX, "DoNotEmitPrefix3") 221 .put(StructuredName.SUFFIX, "DoNotEmitSuffix3") 222 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily3") 223 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven3") 224 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3") 225 .put(StructuredName.IS_PRIMARY, 1); 226 227 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem() 228 .addExpectedNodeWithOrder("N", 229 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 230 + "AppropriatePrefix;AppropriateSuffix", 231 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 232 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")) 233 .addExpectedNodeWithOrder("FN", 234 "AppropriatePrefix AppropriateGivenName " 235 + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix") 236 .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven") 237 .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle") 238 .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily"); 239 240 if (isV30) { 241 elem.addExpectedNode("SORT-STRING", 242 "AppropriatePhoneticGiven AppropriatePhoneticMiddle" 243 + " AppropriatePhoneticFamily"); 244 } 245 } 246 247 public void testStructuredNameUseSuperPrimaryV21() { 248 testStructuredNameUseSuperPrimaryCommon(V21); 249 } 250 251 public void testStructuredNameUseSuperPrimaryV30() { 252 testStructuredNameUseSuperPrimaryCommon(V30); 253 } 254 255 public void testNickNameV30() { 256 mVerifier.initForExportTest(V30); 257 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 258 .put(Nickname.NAME, "Nicky"); 259 260 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 261 .addExpectedNodeWithOrder("NICKNAME", "Nicky"); 262 } 263 264 private void testPhoneBasicCommon(int vcardType) { 265 mVerifier.initForExportTest(vcardType); 266 mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) 267 .put(Phone.NUMBER, "1") 268 .put(Phone.TYPE, Phone.TYPE_HOME); 269 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 270 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 271 } 272 273 public void testPhoneBasicV21() { 274 testPhoneBasicCommon(V21); 275 } 276 277 public void testPhoneBasicV30() { 278 testPhoneBasicCommon(V30); 279 } 280 281 public void testPhoneRefrainFormatting() { 282 mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING); 283 mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) 284 .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)") 285 .put(Phone.TYPE, Phone.TYPE_HOME); 286 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 287 .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)", 288 new TypeSet("HOME")); 289 } 290 291 /** 292 * Tests that vCard composer emits corresponding type param which we expect. 293 */ 294 private void testPhoneVariousTypeSupport(int vcardType) { 295 mVerifier.initForExportTest(vcardType); 296 ContactEntry entry = mVerifier.addInputEntry(); 297 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 298 .put(Phone.NUMBER, "10") 299 .put(Phone.TYPE, Phone.TYPE_HOME); 300 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 301 .put(Phone.NUMBER, "20") 302 .put(Phone.TYPE, Phone.TYPE_WORK); 303 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 304 .put(Phone.NUMBER, "30") 305 .put(Phone.TYPE, Phone.TYPE_FAX_HOME); 306 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 307 .put(Phone.NUMBER, "40") 308 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 309 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 310 .put(Phone.NUMBER, "50") 311 .put(Phone.TYPE, Phone.TYPE_MOBILE); 312 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 313 .put(Phone.NUMBER, "60") 314 .put(Phone.TYPE, Phone.TYPE_PAGER); 315 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 316 .put(Phone.NUMBER, "70") 317 .put(Phone.TYPE, Phone.TYPE_OTHER); 318 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 319 .put(Phone.NUMBER, "80") 320 .put(Phone.TYPE, Phone.TYPE_CAR); 321 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 322 .put(Phone.NUMBER, "90") 323 .put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN); 324 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 325 .put(Phone.NUMBER, "100") 326 .put(Phone.TYPE, Phone.TYPE_ISDN); 327 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 328 .put(Phone.NUMBER, "110") 329 .put(Phone.TYPE, Phone.TYPE_MAIN); 330 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 331 .put(Phone.NUMBER, "120") 332 .put(Phone.TYPE, Phone.TYPE_OTHER_FAX); 333 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 334 .put(Phone.NUMBER, "130") 335 .put(Phone.TYPE, Phone.TYPE_TELEX); 336 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 337 .put(Phone.NUMBER, "140") 338 .put(Phone.TYPE, Phone.TYPE_WORK_MOBILE); 339 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 340 .put(Phone.NUMBER, "150") 341 .put(Phone.TYPE, Phone.TYPE_WORK_PAGER); 342 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 343 .put(Phone.NUMBER, "160") 344 .put(Phone.TYPE, Phone.TYPE_MMS); 345 346 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 347 .addExpectedNode("TEL", "10", new TypeSet("HOME")) 348 .addExpectedNode("TEL", "20", new TypeSet("WORK")) 349 .addExpectedNode("TEL", "30", new TypeSet("HOME", "FAX")) 350 .addExpectedNode("TEL", "40", new TypeSet("WORK", "FAX")) 351 .addExpectedNode("TEL", "50", new TypeSet("CELL")) 352 .addExpectedNode("TEL", "60", new TypeSet("PAGER")) 353 .addExpectedNode("TEL", "70", new TypeSet("VOICE")) 354 .addExpectedNode("TEL", "80", new TypeSet("CAR")) 355 .addExpectedNode("TEL", "90", new TypeSet("WORK", "PREF")) 356 .addExpectedNode("TEL", "100", new TypeSet("ISDN")) 357 .addExpectedNode("TEL", "110", new TypeSet("PREF")) 358 .addExpectedNode("TEL", "120", new TypeSet("FAX")) 359 .addExpectedNode("TEL", "130", new TypeSet("TLX")) 360 .addExpectedNode("TEL", "140", new TypeSet("WORK", "CELL")) 361 .addExpectedNode("TEL", "150", new TypeSet("WORK", "PAGER")) 362 .addExpectedNode("TEL", "160", new TypeSet("MSG")); 363 } 364 365 public void testPhoneVariousTypeSupportV21() { 366 testPhoneVariousTypeSupport(V21); 367 } 368 369 public void testPhoneVariousTypeSupportV30() { 370 testPhoneVariousTypeSupport(V30); 371 } 372 373 /** 374 * Tests that "PREF"s are emitted appropriately. 375 */ 376 private void testPhonePrefHandlingCommon(int vcardType) { 377 mVerifier.initForExportTest(vcardType); 378 ContactEntry entry = mVerifier.addInputEntry(); 379 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 380 .put(Phone.NUMBER, "1") 381 .put(Phone.TYPE, Phone.TYPE_HOME); 382 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 383 .put(Phone.NUMBER, "2") 384 .put(Phone.TYPE, Phone.TYPE_WORK) 385 .put(Phone.IS_PRIMARY, 1); 386 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 387 .put(Phone.NUMBER, "3") 388 .put(Phone.TYPE, Phone.TYPE_FAX_HOME) 389 .put(Phone.IS_PRIMARY, 1); 390 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 391 .put(Phone.NUMBER, "4") 392 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 393 394 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 395 .addExpectedNode("TEL", "4", new TypeSet("WORK", "FAX")) 396 .addExpectedNode("TEL", "3", new TypeSet("HOME", "FAX", "PREF")) 397 .addExpectedNode("TEL", "2", new TypeSet("WORK", "PREF")) 398 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 399 } 400 401 public void testPhonePrefHandlingV21() { 402 testPhonePrefHandlingCommon(V21); 403 } 404 405 public void testPhonePrefHandlingV30() { 406 testPhonePrefHandlingCommon(V30); 407 } 408 409 private void testMiscPhoneTypeHandling(int vcardType) { 410 mVerifier.initForExportTest(vcardType); 411 ContactEntry entry = mVerifier.addInputEntry(); 412 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 413 .put(Phone.NUMBER, "1") 414 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 415 .put(Phone.LABEL, "Modem"); 416 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 417 .put(Phone.NUMBER, "2") 418 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 419 .put(Phone.LABEL, "MSG"); 420 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 421 .put(Phone.NUMBER, "3") 422 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 423 .put(Phone.LABEL, "BBS"); 424 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 425 .put(Phone.NUMBER, "4") 426 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 427 .put(Phone.LABEL, "VIDEO"); 428 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 429 .put(Phone.NUMBER, "5") 430 .put(Phone.TYPE, Phone.TYPE_CUSTOM); 431 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 432 .put(Phone.NUMBER, "6") 433 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 434 .put(Phone.LABEL, "_AUTO_CELL"); // The old indicator for the type mobile. 435 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 436 .put(Phone.NUMBER, "7") 437 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 438 .put(Phone.LABEL, "\u643A\u5E2F"); // Mobile phone in Japanese Kanji 439 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 440 .put(Phone.NUMBER, "8") 441 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 442 .put(Phone.LABEL, "invalid"); 443 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName(); 444 if (VCardConfig.isVersion30(vcardType)) { 445 // vCard 3.0 accepts "invalid". Also stop using toUpper() 446 elem.addExpectedNode("TEL", "1", new TypeSet("Modem")) 447 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 448 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 449 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 450 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 451 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 452 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 453 .addExpectedNode("TEL", "8", new TypeSet("invalid")); 454 } else { 455 elem.addExpectedNode("TEL", "1", new TypeSet("MODEM")) 456 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 457 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 458 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 459 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 460 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 461 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 462 .addExpectedNode("TEL", "8", new TypeSet("X-invalid")); 463 } 464 } 465 466 public void testPhoneTypeHandlingV21() { 467 testMiscPhoneTypeHandling(V21); 468 } 469 470 public void testPhoneTypeHandlingV30() { 471 testMiscPhoneTypeHandling(V30); 472 } 473 474 private void testEmailBasicCommon(int vcardType) { 475 mVerifier.initForExportTest(vcardType); 476 mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE) 477 .put(Email.DATA, "sample@example.com"); 478 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 479 .addExpectedNode("EMAIL", "sample@example.com"); 480 } 481 482 public void testEmailBasicV21() { 483 testEmailBasicCommon(V21); 484 } 485 486 public void testEmailBasicV30() { 487 testEmailBasicCommon(V30); 488 } 489 490 private void testEmailVariousTypeSupportCommon(int vcardType) { 491 mVerifier.initForExportTest(vcardType); 492 ContactEntry entry = mVerifier.addInputEntry(); 493 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 494 .put(Email.DATA, "type_home@example.com") 495 .put(Email.TYPE, Email.TYPE_HOME); 496 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 497 .put(Email.DATA, "type_work@example.com") 498 .put(Email.TYPE, Email.TYPE_WORK); 499 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 500 .put(Email.DATA, "type_mobile@example.com") 501 .put(Email.TYPE, Email.TYPE_MOBILE); 502 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 503 .put(Email.DATA, "type_other@example.com") 504 .put(Email.TYPE, Email.TYPE_OTHER); 505 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 506 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME")) 507 .addExpectedNode("EMAIL", "type_work@example.com", new TypeSet("WORK")) 508 .addExpectedNode("EMAIL", "type_mobile@example.com", new TypeSet("CELL")) 509 .addExpectedNode("EMAIL", "type_other@example.com"); 510 } 511 512 public void testEmailVariousTypeSupportV21() { 513 testEmailVariousTypeSupportCommon(V21); 514 } 515 516 public void testEmailVariousTypeSupportV30() { 517 testEmailVariousTypeSupportCommon(V30); 518 } 519 520 private void testEmailPrefHandlingCommon(int vcardType) { 521 mVerifier.initForExportTest(vcardType); 522 ContactEntry entry = mVerifier.addInputEntry(); 523 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 524 .put(Email.DATA, "type_home@example.com") 525 .put(Email.TYPE, Email.TYPE_HOME) 526 .put(Email.IS_PRIMARY, 1); 527 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 528 .put(Email.DATA, "type_notype@example.com") 529 .put(Email.IS_PRIMARY, 1); 530 531 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 532 .addExpectedNode("EMAIL", "type_notype@example.com", new TypeSet("PREF")) 533 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF")); 534 } 535 536 public void testEmailPrefHandlingV21() { 537 testEmailPrefHandlingCommon(V21); 538 } 539 540 public void testEmailPrefHandlingV30() { 541 testEmailPrefHandlingCommon(V30); 542 } 543 544 private void testPostalAddressCommon(int vcardType) { 545 mVerifier.initForExportTest(vcardType); 546 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 547 .put(StructuredPostal.POBOX, "Pobox") 548 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood") 549 .put(StructuredPostal.STREET, "Street") 550 .put(StructuredPostal.CITY, "City") 551 .put(StructuredPostal.REGION, "Region") 552 .put(StructuredPostal.POSTCODE, "100") 553 .put(StructuredPostal.COUNTRY, "Country") 554 .put(StructuredPostal.FORMATTED_ADDRESS, "Formatted Address") 555 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK); 556 // adr-value = 0*6(text-value ";") text-value 557 // ; PO Box, Extended Address, Street, Locality, Region, Postal Code, 558 // ; Country Name 559 // 560 // The NEIGHBORHOOD field is appended after the CITY field. 561 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 562 .addExpectedNode("ADR", 563 Arrays.asList("Pobox", "", "Street", "City Neighborhood", 564 "Region", "100", "Country"), new TypeSet("WORK")); 565 } 566 567 public void testPostalAddressV21() { 568 testPostalAddressCommon(V21); 569 } 570 571 public void testPostalAddressV30() { 572 testPostalAddressCommon(V30); 573 } 574 575 private void testPostalAddressNonNeighborhood(int vcardType) { 576 mVerifier.initForExportTest(vcardType); 577 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 578 .put(StructuredPostal.CITY, "City"); 579 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 580 .addExpectedNode("ADR", 581 Arrays.asList("", "", "", "City", "", "", ""), new TypeSet("HOME")); 582 } 583 584 public void testPostalAddressNonNeighborhoodV21() { 585 testPostalAddressNonNeighborhood(V21); 586 } 587 588 public void testPostalAddressNonNeighborhoodV30() { 589 testPostalAddressNonNeighborhood(V30); 590 } 591 592 private void testPostalAddressNonCity(int vcardType) { 593 mVerifier.initForExportTest(vcardType); 594 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 595 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood"); 596 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 597 .addExpectedNode("ADR", 598 Arrays.asList("", "", "", "Neighborhood", "", "", ""), new TypeSet("HOME")); 599 } 600 601 public void testPostalAddressNonCityV21() { 602 testPostalAddressNonCity(V21); 603 } 604 605 public void testPostalAddressNonCityV30() { 606 testPostalAddressNonCity(V30); 607 } 608 609 private void testPostalOnlyWithFormattedAddressCommon(int vcardType) { 610 mVerifier.initForExportTest(vcardType); 611 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 612 .put(StructuredPostal.REGION, "") // Must be ignored. 613 .put(StructuredPostal.FORMATTED_ADDRESS, 614 "Formatted address CA 123-334 United Statue"); 615 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 616 .addExpectedNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;", 617 Arrays.asList("", "Formatted address CA 123-334 United Statue", 618 "", "", "", "", ""), new TypeSet("HOME")); 619 } 620 621 public void testPostalOnlyWithFormattedAddressV21() { 622 testPostalOnlyWithFormattedAddressCommon(V21); 623 } 624 625 public void testPostalOnlyWithFormattedAddressV30() { 626 testPostalOnlyWithFormattedAddressCommon(V30); 627 } 628 629 /** 630 * Tests that the vCard composer honors formatted data when it is available 631 * even when it is partial. 632 */ 633 private void testPostalWithBothStructuredAndFormattedCommon(int vcardType) { 634 mVerifier.initForExportTest(vcardType); 635 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 636 .put(StructuredPostal.POBOX, "Pobox") 637 .put(StructuredPostal.COUNTRY, "Country") 638 .put(StructuredPostal.FORMATTED_ADDRESS, 639 "Formatted address CA 123-334 United Statue"); // Should be ignored 640 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 641 .addExpectedNode("ADR", "Pobox;;;;;;Country", 642 Arrays.asList("Pobox", "", "", "", "", "", "Country"), 643 new TypeSet("HOME")); 644 } 645 646 public void testPostalWithBothStructuredAndFormattedV21() { 647 testPostalWithBothStructuredAndFormattedCommon(V21); 648 } 649 650 public void testPostalWithBothStructuredAndFormattedV30() { 651 testPostalWithBothStructuredAndFormattedCommon(V30); 652 } 653 654 private void testOrganizationCommon(int vcardType) { 655 mVerifier.initForExportTest(vcardType); 656 ContactEntry entry = mVerifier.addInputEntry(); 657 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 658 .put(Organization.COMPANY, "CompanyX") 659 .put(Organization.DEPARTMENT, "DepartmentY") 660 .put(Organization.TITLE, "TitleZ") 661 .put(Organization.JOB_DESCRIPTION, "Description Rambda") // Ignored. 662 .put(Organization.OFFICE_LOCATION, "Mountain View") // Ignored. 663 .put(Organization.PHONETIC_NAME, "PhoneticName!") // Ignored 664 .put(Organization.SYMBOL, "(^o^)/~~"); // Ignore him (her). 665 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 666 .putNull(Organization.COMPANY) 667 .put(Organization.DEPARTMENT, "DepartmentXX") 668 .putNull(Organization.TITLE); 669 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 670 .put(Organization.COMPANY, "CompanyXYZ") 671 .putNull(Organization.DEPARTMENT) 672 .put(Organization.TITLE, "TitleXYZYX"); 673 // Currently we do not use group but depend on the order. 674 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 675 .addExpectedNodeWithOrder("ORG", "CompanyX;DepartmentY", 676 Arrays.asList("CompanyX", "DepartmentY")) 677 .addExpectedNodeWithOrder("TITLE", "TitleZ") 678 .addExpectedNodeWithOrder("ORG", "DepartmentXX") 679 .addExpectedNodeWithOrder("ORG", "CompanyXYZ") 680 .addExpectedNodeWithOrder("TITLE", "TitleXYZYX"); 681 } 682 683 public void testOrganizationV21() { 684 testOrganizationCommon(V21); 685 } 686 687 public void testOrganizationV30() { 688 testOrganizationCommon(V30); 689 } 690 691 private void testImVariousTypeSupportCommon(int vcardType) { 692 mVerifier.initForExportTest(vcardType); 693 ContactEntry entry = mVerifier.addInputEntry(); 694 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 695 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 696 .put(Im.DATA, "aim"); 697 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 698 .put(Im.PROTOCOL, Im.PROTOCOL_MSN) 699 .put(Im.DATA, "msn"); 700 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 701 .put(Im.PROTOCOL, Im.PROTOCOL_YAHOO) 702 .put(Im.DATA, "yahoo"); 703 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 704 .put(Im.PROTOCOL, Im.PROTOCOL_SKYPE) 705 .put(Im.DATA, "skype"); 706 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 707 .put(Im.PROTOCOL, Im.PROTOCOL_QQ) 708 .put(Im.DATA, "qq"); 709 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 710 .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK) 711 .put(Im.DATA, "google talk"); 712 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 713 .put(Im.PROTOCOL, Im.PROTOCOL_ICQ) 714 .put(Im.DATA, "icq"); 715 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 716 .put(Im.PROTOCOL, Im.PROTOCOL_JABBER) 717 .put(Im.DATA, "jabber"); 718 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 719 .put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING) 720 .put(Im.DATA, "netmeeting"); 721 722 // No determined way to express unknown type... 723 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 724 .addExpectedNode("X-JABBER", "jabber") 725 .addExpectedNode("X-ICQ", "icq") 726 .addExpectedNode("X-GOOGLE-TALK", "google talk") 727 .addExpectedNode("X-QQ", "qq") 728 .addExpectedNode("X-SKYPE-USERNAME", "skype") 729 .addExpectedNode("X-YAHOO", "yahoo") 730 .addExpectedNode("X-MSN", "msn") 731 .addExpectedNode("X-NETMEETING", "netmeeting") 732 .addExpectedNode("X-AIM", "aim"); 733 } 734 735 public void testImBasiV21() { 736 testImVariousTypeSupportCommon(V21); 737 } 738 739 public void testImBasicV30() { 740 testImVariousTypeSupportCommon(V30); 741 } 742 743 private void testImPrefHandlingCommon(int vcardType) { 744 mVerifier.initForExportTest(vcardType); 745 ContactEntry entry = mVerifier.addInputEntry(); 746 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 747 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 748 .put(Im.DATA, "aim1"); 749 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 750 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 751 .put(Im.DATA, "aim2") 752 .put(Im.TYPE, Im.TYPE_HOME) 753 .put(Im.IS_PRIMARY, 1); 754 755 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 756 .addExpectedNode("X-AIM", "aim1") 757 .addExpectedNode("X-AIM", "aim2", new TypeSet("HOME", "PREF")); 758 } 759 760 public void testImPrefHandlingV21() { 761 testImPrefHandlingCommon(V21); 762 } 763 764 public void testImPrefHandlingV30() { 765 testImPrefHandlingCommon(V30); 766 } 767 768 private void testWebsiteCommon(int vcardType) { 769 mVerifier.initForExportTest(vcardType); 770 ContactEntry entry = mVerifier.addInputEntry(); 771 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 772 .put(Website.URL, "http://website.example.android.com/index.html") 773 .put(Website.TYPE, Website.TYPE_BLOG); 774 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 775 .put(Website.URL, "ftp://ftp.example.android.com/index.html") 776 .put(Website.TYPE, Website.TYPE_FTP); 777 778 // We drop TYPE information since vCard (especially 3.0) does not allow us to emit it. 779 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 780 .addExpectedNode("URL", "ftp://ftp.example.android.com/index.html") 781 .addExpectedNode("URL", "http://website.example.android.com/index.html"); 782 } 783 784 public void testWebsiteV21() { 785 testWebsiteCommon(V21); 786 } 787 788 public void testWebsiteV30() { 789 testWebsiteCommon(V30); 790 } 791 792 private String getAndroidPropValue(final String mimeType, String value, Integer type) { 793 return getAndroidPropValue(mimeType, value, type, null); 794 } 795 796 private String getAndroidPropValue(final String mimeType, String value, 797 Integer type, String label) { 798 return (mimeType + ";" + value + ";" 799 + (type != null ? type : "") + ";" 800 + (label != null ? label : "") + ";;;;;;;;;;;;"); 801 } 802 803 private void testEventCommon(int vcardType) { 804 mVerifier.initForExportTest(vcardType); 805 ContactEntry entry = mVerifier.addInputEntry(); 806 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 807 .put(Event.TYPE, Event.TYPE_ANNIVERSARY) 808 .put(Event.START_DATE, "1982-06-16"); 809 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 810 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 811 .put(Event.START_DATE, "2008-10-22"); 812 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 813 .put(Event.TYPE, Event.TYPE_OTHER) 814 .put(Event.START_DATE, "2018-03-12"); 815 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 816 .put(Event.TYPE, Event.TYPE_CUSTOM) 817 .put(Event.LABEL, "The last day") 818 .put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed."); 819 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 820 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 821 .put(Event.START_DATE, "2009-05-19"); // Should be ignored. 822 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 823 .addExpectedNode("BDAY", "2008-10-22") 824 .addExpectedNode("X-ANDROID-CUSTOM", 825 getAndroidPropValue( 826 Event.CONTENT_ITEM_TYPE, "1982-06-16", Event.TYPE_ANNIVERSARY)) 827 .addExpectedNode("X-ANDROID-CUSTOM", 828 getAndroidPropValue( 829 Event.CONTENT_ITEM_TYPE, "2018-03-12", Event.TYPE_OTHER)) 830 .addExpectedNode("X-ANDROID-CUSTOM", 831 getAndroidPropValue( 832 Event.CONTENT_ITEM_TYPE, 833 "When the Tower of Hanoi with 64 rings is completed.", 834 Event.TYPE_CUSTOM, "The last day")); 835 } 836 837 public void testEventV21() { 838 testEventCommon(V21); 839 } 840 841 public void testEventV30() { 842 testEventCommon(V30); 843 } 844 845 private void testNoteCommon(int vcardType) { 846 mVerifier.initForExportTest(vcardType); 847 ContactEntry entry = mVerifier.addInputEntry(); 848 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 849 .put(Note.NOTE, "note1"); 850 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 851 .put(Note.NOTE, "note2") 852 .put(Note.IS_PRIMARY, 1); // Just ignored. 853 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 854 .addExpectedNodeWithOrder("NOTE", "note1") 855 .addExpectedNodeWithOrder("NOTE", "note2"); 856 } 857 858 public void testNoteV21() { 859 testNoteCommon(V21); 860 } 861 862 public void testNoteV30() { 863 testNoteCommon(V30); 864 } 865 866 private void testPhotoCommon(int vcardType) { 867 final boolean isV30 = vcardType == V30; 868 mVerifier.initForExportTest(vcardType); 869 ContactEntry entry = mVerifier.addInputEntry(); 870 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 871 .put(StructuredName.FAMILY_NAME, "PhotoTest"); 872 entry.addContentValues(Photo.CONTENT_ITEM_TYPE) 873 .put(Photo.PHOTO, sPhotoByteArray); 874 875 ContentValues contentValuesForPhoto = new ContentValues(); 876 contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64")); 877 mVerifier.addPropertyNodesVerifierElem() 878 .addExpectedNode("FN", "PhotoTest") 879 .addExpectedNode("N", "PhotoTest;;;;", 880 Arrays.asList("PhotoTest", "", "", "", "")) 881 .addExpectedNodeWithOrder("PHOTO", null, null, sPhotoByteArray, 882 contentValuesForPhoto, new TypeSet("JPEG"), null); 883 } 884 885 public void testPhotoV21() { 886 testPhotoCommon(V21); 887 } 888 889 public void testPhotoV30() { 890 testPhotoCommon(V30); 891 } 892 893 private void testRelationCommon(int vcardType) { 894 mVerifier.initForExportTest(vcardType); 895 mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE) 896 .put(Relation.TYPE, Relation.TYPE_MOTHER) 897 .put(Relation.NAME, "Ms. Mother"); 898 mVerifier.addContentValuesVerifierElem().addExpected(Relation.CONTENT_ITEM_TYPE) 899 .put(Relation.TYPE, Relation.TYPE_MOTHER) 900 .put(Relation.NAME, "Ms. Mother"); 901 } 902 903 public void testRelationV21() { 904 testRelationCommon(V21); 905 } 906 907 public void testRelationV30() { 908 testRelationCommon(V30); 909 } 910 911 public void testV30HandleEscape() { 912 mVerifier.initForExportTest(V30); 913 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 914 .put(StructuredName.FAMILY_NAME, "\\") 915 .put(StructuredName.GIVEN_NAME, ";") 916 .put(StructuredName.MIDDLE_NAME, ",") 917 .put(StructuredName.PREFIX, "\n") 918 .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]"); 919 // Verifies the vCard String correctly escapes each character which must be escaped. 920 mVerifier.addLineVerifierElem() 921 .addExpected("N:\\\\;\\;;\\,;\\n;") 922 .addExpected("FN:[<{Unescaped:Asciis}>]"); 923 mVerifier.addPropertyNodesVerifierElem() 924 .addExpectedNode("FN", "[<{Unescaped:Asciis}>]") 925 .addExpectedNode("N", Arrays.asList("\\", ";", ",", "\n", "")); 926 } 927 928 /** 929 * There's no "NICKNAME" property in vCard 2.1, while there is in vCard 3.0. 930 * We use Android-specific "X-ANDROID-CUSTOM" property. 931 * This test verifies the functionality. 932 */ 933 public void testNickNameV21() { 934 mVerifier.initForExportTest(V21); 935 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 936 .put(Nickname.NAME, "Nicky"); 937 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 938 .addExpectedNode("X-ANDROID-CUSTOM", 939 Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;"); 940 mVerifier.addContentValuesVerifierElem().addExpected(Nickname.CONTENT_ITEM_TYPE) 941 .put(Nickname.NAME, "Nicky"); 942 } 943 944 public void testTolerateBrokenPhoneNumberEntryV21() { 945 mVerifier.initForExportTest(V21); 946 ContactEntry entry = mVerifier.addInputEntry(); 947 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 948 .put(Phone.TYPE, Phone.TYPE_HOME) 949 .put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo);" 950 + "777-888-9999 (Chicago);111-222-3333 (Miami)"); 951 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 952 .addExpectedNode("TEL", "111-222-3333", new TypeSet("HOME")) 953 .addExpectedNode("TEL", "444-555-5666", new TypeSet("HOME")) 954 .addExpectedNode("TEL", "777-888-9999", new TypeSet("HOME")); 955 } 956 957 private void testPickUpNonEmptyContentValuesCommon(int vcardType) { 958 mVerifier.initForExportTest(vcardType); 959 ContactEntry entry = mVerifier.addInputEntry(); 960 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 961 .put(StructuredName.IS_PRIMARY, 1); // Empty name. Should be ignored. 962 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 963 .put(StructuredName.FAMILY_NAME, "family1"); // Not primary. Should be ignored. 964 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 965 .put(StructuredName.IS_PRIMARY, 1) 966 .put(StructuredName.FAMILY_NAME, "family2"); // This entry is what we want. 967 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 968 .put(StructuredName.IS_PRIMARY, 1) 969 .put(StructuredName.FAMILY_NAME, "family3"); 970 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 971 .put(StructuredName.FAMILY_NAME, "family4"); 972 mVerifier.addPropertyNodesVerifierElem() 973 .addExpectedNode("N", Arrays.asList("family2", "", "", "", "")) 974 .addExpectedNode("FN", "family2"); 975 } 976 977 public void testPickUpNonEmptyContentValuesV21() { 978 testPickUpNonEmptyContentValuesCommon(V21); 979 } 980 981 public void testPickUpNonEmptyContentValuesV30() { 982 testPickUpNonEmptyContentValuesCommon(V30); 983 } 984 985 public void testUseMultiByteTypeV30() { 986 mVerifier.initForExportTest(V30); 987 final ContactEntry entry = mVerifier.addInputEntry(); 988 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 989 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 990 .put(Phone.LABEL, "\u96FB\u8A71") 991 .put(Phone.NUMBER, "1"); 992 mVerifier.addLineVerifierElem() 993 .addExpected("N:") 994 .addExpected("FN:") 995 .addExpected("TEL;TYPE=\u96FB\u8A71:1"); 996 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 997 .addExpectedNode("TEL", "1", new TypeSet("\u96FB\u8A71")); 998 } 999} 1000