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