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