VCardExporterTests.java revision 677ef21613a9d35053ec098444832ce4125a847e
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 com.android.vcard.VCardConfig; 20import com.android.vcard.tests.testutils.ContactEntry; 21import com.android.vcard.tests.testutils.PropertyNodesVerifierElem; 22import com.android.vcard.tests.testutils.VCardTestsBase; 23import com.android.vcard.tests.testutils.PropertyNodesVerifierElem.TypeSet; 24 25import android.content.ContentValues; 26import android.provider.ContactsContract.CommonDataKinds.Email; 27import android.provider.ContactsContract.CommonDataKinds.Event; 28import android.provider.ContactsContract.CommonDataKinds.Im; 29import android.provider.ContactsContract.CommonDataKinds.Nickname; 30import android.provider.ContactsContract.CommonDataKinds.Note; 31import android.provider.ContactsContract.CommonDataKinds.Organization; 32import android.provider.ContactsContract.CommonDataKinds.Phone; 33import android.provider.ContactsContract.CommonDataKinds.Photo; 34import android.provider.ContactsContract.CommonDataKinds.Relation; 35import android.provider.ContactsContract.CommonDataKinds.SipAddress; 36import android.provider.ContactsContract.CommonDataKinds.StructuredName; 37import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 38import android.provider.ContactsContract.CommonDataKinds.Website; 39 40import java.util.Arrays; 41 42/** 43 * Tests for the code related to vCard exporter, inculding vCard composer. 44 * This test class depends on vCard importer code, so if tests for vCard importer fail, 45 * the result of this class will not be reliable. 46 */ 47public class VCardExporterTests extends VCardTestsBase { 48 private static final byte[] sPhotoByteArray = 49 VCardImporterTests.sPhotoByteArrayForComplicatedCase; 50 51 public void testSimpleV21() { 52 mVerifier.initForExportTest(V21); 53 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 54 .put(StructuredName.FAMILY_NAME, "Ando") 55 .put(StructuredName.GIVEN_NAME, "Roid"); 56 mVerifier.addPropertyNodesVerifierElem() 57 .addExpectedNode("FN", "Roid Ando") 58 .addExpectedNode("N", "Ando;Roid;;;", 59 Arrays.asList("Ando", "Roid", "", "", "")); 60 } 61 62 private void testStructuredNameBasic(int 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.DISPLAY_NAME, "DISPLAY NAME"); 71 72 mVerifier.addPropertyNodesVerifierElem() 73 .addExpectedNodeWithOrder("N", 74 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 75 + "AppropriatePrefix;AppropriateSuffix", 76 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 77 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")) 78 .addExpectedNodeWithOrder("FN", "DISPLAY NAME"); 79 } 80 81 public void testStructuredNameBasicV21() { 82 testStructuredNameBasic(V21); 83 } 84 85 public void testStructuredNameBasicV30() { 86 testStructuredNameBasic(V30); 87 } 88 89 public void testStructuredNameBasicV40() { 90 testStructuredNameBasic(V40); 91 } 92 93 /** 94 * Test that only "primary" StructuredName is emitted, so that our vCard file 95 * will not confuse the external importer, assuming there may be some importer 96 * which presume that there's only one property toward each of "N", "FN", etc. 97 * Note that more than one "N", "FN", etc. properties are acceptable in vCard spec. 98 */ 99 private void testStructuredNameUsePrimaryCommon(int vcardType) { 100 mVerifier.initForExportTest(vcardType); 101 final ContactEntry entry = mVerifier.addInputEntry(); 102 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 103 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1") 104 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1") 105 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1") 106 .put(StructuredName.PREFIX, "DoNotEmitPrefix1") 107 .put(StructuredName.SUFFIX, "DoNotEmitSuffix1") 108 .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName1"); 109 110 // With "IS_PRIMARY=1". This is what we should use. 111 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 112 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 113 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 114 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 115 .put(StructuredName.PREFIX, "AppropriatePrefix") 116 .put(StructuredName.SUFFIX, "AppropriateSuffix") 117 .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName") 118 .put(StructuredName.IS_PRIMARY, 1); 119 120 // With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first. 121 // vCard 2.1 does not specify anything about the number of N properties. We choose not 122 // emitting this property. 123 // vCard 3.0 does (There must be one N property) 124 // vCard 4.0 (rev13) does (cardinality (0, 1)). 125 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 126 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2") 127 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2") 128 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2") 129 .put(StructuredName.PREFIX, "DoNotEmitPrefix2") 130 .put(StructuredName.SUFFIX, "DoNotEmitSuffix2") 131 .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName2") 132 .put(StructuredName.IS_PRIMARY, 1); 133 134 mVerifier.addPropertyNodesVerifierElem() 135 .addExpectedNodeWithOrder("N", 136 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 137 + "AppropriatePrefix;AppropriateSuffix", 138 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 139 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")) 140 .addExpectedNodeWithOrder("FN", "AppropriateDisplayName"); 141 } 142 143 public void testStructuredNameUsePrimaryV21() { 144 testStructuredNameUsePrimaryCommon(V21); 145 } 146 147 public void testStructuredNameUsePrimaryV30() { 148 testStructuredNameUsePrimaryCommon(V30); 149 } 150 151 public void testStructuredNameUsePrimaryV40() { 152 testStructuredNameUsePrimaryCommon(V40); 153 } 154 155 /** 156 * Tests that only "super primary" StructuredName is emitted. 157 * See also the comment in {@link #testStructuredNameUsePrimaryCommon(int)}. 158 */ 159 private void testStructuredNameUseSuperPrimaryCommon(int vcardType) { 160 mVerifier.initForExportTest(vcardType); 161 final ContactEntry entry = mVerifier.addInputEntry(); 162 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 163 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1") 164 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1") 165 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1") 166 .put(StructuredName.PREFIX, "DoNotEmitPrefix1") 167 .put(StructuredName.SUFFIX, "DoNotEmitSuffix1") 168 .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay1"); 169 170 // With "IS_PRIMARY=1", but we should ignore this time. 171 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 172 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2") 173 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2") 174 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2") 175 .put(StructuredName.PREFIX, "DoNotEmitPrefix2") 176 .put(StructuredName.SUFFIX, "DoNotEmitSuffix2") 177 .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay2") 178 .put(StructuredName.IS_PRIMARY, 1); 179 180 // With "IS_SUPER_PRIMARY=1". This is what we should use. 181 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 182 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 183 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 184 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 185 .put(StructuredName.PREFIX, "AppropriatePrefix") 186 .put(StructuredName.SUFFIX, "AppropriateSuffix") 187 .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName") 188 .put(StructuredName.IS_SUPER_PRIMARY, 1); 189 190 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 191 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3") 192 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3") 193 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3") 194 .put(StructuredName.PREFIX, "DoNotEmitPrefix3") 195 .put(StructuredName.SUFFIX, "DoNotEmitSuffix3") 196 .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay3") 197 .put(StructuredName.IS_PRIMARY, 1); 198 199 final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem(); 200 elem.addExpectedNodeWithOrder("N", 201 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 202 + "AppropriatePrefix;AppropriateSuffix", 203 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 204 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")); 205 206 elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName"); 207 } 208 209 public void testStructuredNameUseSuperPrimaryV21() { 210 testStructuredNameUseSuperPrimaryCommon(V21); 211 } 212 213 public void testStructuredNameUseSuperPrimaryV30() { 214 testStructuredNameUseSuperPrimaryCommon(V30); 215 } 216 217 public void testStructuredNameUseSuperPrimaryV40() { 218 testStructuredNameUseSuperPrimaryCommon(V40); 219 } 220 221 /** 222 * Tests phonetic names field are handled correctly. 223 * 224 * vCard 2.1 does not have any field corresponding to them. 225 * vCard 3.0 has SORT-STRING property, which does not support multiple values inside it. 226 * vCard 4.0 (rev13) has SORT-AS parameter, which has three values (family, given, middle) 227 * inside it. 228 */ 229 private void testStructuredNamePhoneticNameCommon(int vcardType) { 230 mVerifier.initForExportTest(vcardType); 231 final ContactEntry entry = mVerifier.addInputEntry(); 232 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 233 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 234 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 235 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 236 .put(StructuredName.PREFIX, "AppropriatePrefix") 237 .put(StructuredName.SUFFIX, "AppropriateSuffix") 238 .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName") 239 .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily") 240 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven") 241 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle"); 242 243 final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem(); 244 if (VCardConfig.isVersion40(vcardType)) { 245 final ContentValues contentValues = new ContentValues(); 246 contentValues.put("SORT-AS", 247 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName"); 248 // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with 249 // either 2.1 nor 3.0. 250 elem.addExpectedNodeWithOrder("N", 251 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 252 + "AppropriatePrefix;AppropriateSuffix", 253 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 254 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"), 255 contentValues); 256 } else { 257 elem.addExpectedNodeWithOrder("N", 258 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 259 + "AppropriatePrefix;AppropriateSuffix", 260 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 261 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")); 262 if (VCardConfig.isVersion30(vcardType)) { 263 elem.addExpectedNode("SORT-STRING", 264 "AppropriatePhoneticGiven AppropriatePhoneticMiddle" 265 + " AppropriatePhoneticFamily"); 266 } 267 } 268 269 elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName") 270 .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven") 271 .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle") 272 .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily"); 273 } 274 275 public void testStructuredNamePhoneticNameV21() { 276 testStructuredNamePhoneticNameCommon(V21); 277 } 278 279 public void testStructuredNamePhoneticNameV30() { 280 testStructuredNamePhoneticNameCommon(V30); 281 } 282 283 public void testStructuredNamePhoneticNameV40() { 284 testStructuredNamePhoneticNameCommon(V40); 285 } 286 287 // TODO: need to add test cases confirming escaping, empty values, etc. 288 289 /** 290 * Confirms all the other sides of the handling is correctly interpreted at one time. 291 * 292 * A kind of regression test for StructuredName handling. 293 */ 294 private void testStructuredNameComplicatedCommon(int vcardType) { 295 mVerifier.initForExportTest(vcardType); 296 final ContactEntry entry = mVerifier.addInputEntry(); 297 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 298 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1") 299 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1") 300 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1") 301 .put(StructuredName.PREFIX, "DoNotEmitPrefix1") 302 .put(StructuredName.SUFFIX, "DoNotEmitSuffix1") 303 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1") 304 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1") 305 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1"); 306 307 // With "IS_PRIMARY=1", but we should ignore this time. 308 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 309 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2") 310 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2") 311 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2") 312 .put(StructuredName.PREFIX, "DoNotEmitPrefix2") 313 .put(StructuredName.SUFFIX, "DoNotEmitSuffix2") 314 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2") 315 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2") 316 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2") 317 .put(StructuredName.IS_PRIMARY, 1); 318 319 // With "IS_SUPER_PRIMARY=1". This is what we should use. 320 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 321 .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName") 322 .put(StructuredName.GIVEN_NAME, "AppropriateGivenName") 323 .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName") 324 .put(StructuredName.PREFIX, "AppropriatePrefix") 325 .put(StructuredName.SUFFIX, "AppropriateSuffix") 326 .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily") 327 .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven") 328 .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle") 329 .put(StructuredName.IS_SUPER_PRIMARY, 1); 330 331 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 332 .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3") 333 .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3") 334 .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3") 335 .put(StructuredName.PREFIX, "DoNotEmitPrefix3") 336 .put(StructuredName.SUFFIX, "DoNotEmitSuffix3") 337 .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily3") 338 .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven3") 339 .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3") 340 .put(StructuredName.IS_PRIMARY, 1); 341 342 final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem(); 343 if (VCardConfig.isVersion40(vcardType)) { 344 final ContentValues contentValues = new ContentValues(); 345 contentValues.put("SORT-AS", 346 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName"); 347 // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with 348 // either 2.1 nor 3.0. 349 elem.addExpectedNodeWithOrder("N", 350 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 351 + "AppropriatePrefix;AppropriateSuffix", 352 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 353 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"), 354 contentValues); 355 } else { 356 elem.addExpectedNodeWithOrder("N", 357 "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;" 358 + "AppropriatePrefix;AppropriateSuffix", 359 Arrays.asList("AppropriateFamilyName", "AppropriateGivenName", 360 "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix")); 361 if (VCardConfig.isVersion30(vcardType)) { 362 elem.addExpectedNode("SORT-STRING", 363 "AppropriatePhoneticGiven AppropriatePhoneticMiddle" 364 + " AppropriatePhoneticFamily"); 365 } 366 } 367 368 elem.addExpectedNodeWithOrder("FN", 369 "AppropriatePrefix AppropriateGivenName " 370 + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix") 371 .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven") 372 .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle") 373 .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily"); 374 } 375 376 public void testStructuredNameComplicatedV21() { 377 testStructuredNameComplicatedCommon(V21); 378 } 379 380 public void testStructuredNameComplicatedV30() { 381 testStructuredNameComplicatedCommon(V30); 382 } 383 384 public void testStructuredNameComplicatedV40() { 385 testStructuredNameComplicatedCommon(V40); 386 } 387 388 public void testNickNameV30() { 389 mVerifier.initForExportTest(V30); 390 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 391 .put(Nickname.NAME, "Nicky"); 392 393 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 394 .addExpectedNodeWithOrder("NICKNAME", "Nicky"); 395 } 396 397 public void testNickNameV40() { 398 mVerifier.initForExportTest(V40); 399 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 400 .put(Nickname.NAME, "Nicky"); 401 402 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 403 .addExpectedNodeWithOrder("NICKNAME", "Nicky"); 404 } 405 406 private void testPhoneBasicCommon(int vcardType) { 407 mVerifier.initForExportTest(vcardType); 408 mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) 409 .put(Phone.NUMBER, "1") 410 .put(Phone.TYPE, Phone.TYPE_HOME); 411 if (VCardConfig.isVersion40(vcardType)) { 412 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 413 .addExpectedNode("TEL", "tel:1", new TypeSet("HOME")); 414 } else { 415 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 416 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 417 } 418 } 419 420 public void testPhoneBasicV21() { 421 testPhoneBasicCommon(V21); 422 } 423 424 public void testPhoneBasicV30() { 425 testPhoneBasicCommon(V30); 426 } 427 428 public void testPhoneBasicV40() { 429 testPhoneBasicCommon(V40); 430 } 431 432 public void testPhoneRefrainFormatting() { 433 mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING); 434 mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) 435 .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)") 436 .put(Phone.TYPE, Phone.TYPE_HOME); 437 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 438 .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)", 439 new TypeSet("HOME")); 440 } 441 442 /** 443 * Tests that vCard composer emits corresponding type param which we expect. 444 */ 445 private void testPhoneVariousTypeSupport(int vcardType) { 446 mVerifier.initForExportTest(vcardType); 447 ContactEntry entry = mVerifier.addInputEntry(); 448 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 449 .put(Phone.NUMBER, "10") 450 .put(Phone.TYPE, Phone.TYPE_HOME); 451 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 452 .put(Phone.NUMBER, "20") 453 .put(Phone.TYPE, Phone.TYPE_WORK); 454 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 455 .put(Phone.NUMBER, "30") 456 .put(Phone.TYPE, Phone.TYPE_FAX_HOME); 457 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 458 .put(Phone.NUMBER, "40") 459 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 460 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 461 .put(Phone.NUMBER, "50") 462 .put(Phone.TYPE, Phone.TYPE_MOBILE); 463 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 464 .put(Phone.NUMBER, "60") 465 .put(Phone.TYPE, Phone.TYPE_PAGER); 466 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 467 .put(Phone.NUMBER, "70") 468 .put(Phone.TYPE, Phone.TYPE_OTHER); 469 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 470 .put(Phone.NUMBER, "80") 471 .put(Phone.TYPE, Phone.TYPE_CAR); 472 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 473 .put(Phone.NUMBER, "90") 474 .put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN); 475 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 476 .put(Phone.NUMBER, "100") 477 .put(Phone.TYPE, Phone.TYPE_ISDN); 478 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 479 .put(Phone.NUMBER, "110") 480 .put(Phone.TYPE, Phone.TYPE_MAIN); 481 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 482 .put(Phone.NUMBER, "120") 483 .put(Phone.TYPE, Phone.TYPE_OTHER_FAX); 484 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 485 .put(Phone.NUMBER, "130") 486 .put(Phone.TYPE, Phone.TYPE_TELEX); 487 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 488 .put(Phone.NUMBER, "140") 489 .put(Phone.TYPE, Phone.TYPE_WORK_MOBILE); 490 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 491 .put(Phone.NUMBER, "150") 492 .put(Phone.TYPE, Phone.TYPE_WORK_PAGER); 493 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 494 .put(Phone.NUMBER, "160") 495 .put(Phone.TYPE, Phone.TYPE_MMS); 496 497 if (VCardConfig.isVersion40(vcardType)) { 498 // Currently pager type has special logic... 499 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 500 .addExpectedNode("TEL", "tel:10", new TypeSet("HOME")) 501 .addExpectedNode("TEL", "tel:20", new TypeSet("WORK")) 502 .addExpectedNode("TEL", "tel:30", new TypeSet("HOME", "FAX")) 503 .addExpectedNode("TEL", "tel:40", new TypeSet("WORK", "FAX")) 504 .addExpectedNode("TEL", "tel:50", new TypeSet("CELL")) 505 .addExpectedNode("TEL", "60", new TypeSet("PAGER")) 506 .addExpectedNode("TEL", "tel:70", new TypeSet("VOICE")) 507 .addExpectedNode("TEL", "tel:80", new TypeSet("CAR")) 508 .addExpectedNode("TEL", "tel:90", new TypeSet("WORK", "PREF")) 509 .addExpectedNode("TEL", "tel:100", new TypeSet("ISDN")) 510 .addExpectedNode("TEL", "tel:110", new TypeSet("PREF")) 511 .addExpectedNode("TEL", "tel:120", new TypeSet("FAX")) 512 .addExpectedNode("TEL", "tel:130", new TypeSet("TLX")) 513 .addExpectedNode("TEL", "tel:140", new TypeSet("WORK", "CELL")) 514 .addExpectedNode("TEL", "tel:150", new TypeSet("WORK", "PAGER")) 515 .addExpectedNode("TEL", "tel:160", new TypeSet("MSG")); 516 } else { 517 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 518 .addExpectedNode("TEL", "10", new TypeSet("HOME")) 519 .addExpectedNode("TEL", "20", new TypeSet("WORK")) 520 .addExpectedNode("TEL", "30", new TypeSet("HOME", "FAX")) 521 .addExpectedNode("TEL", "40", new TypeSet("WORK", "FAX")) 522 .addExpectedNode("TEL", "50", new TypeSet("CELL")) 523 .addExpectedNode("TEL", "60", new TypeSet("PAGER")) 524 .addExpectedNode("TEL", "70", new TypeSet("VOICE")) 525 .addExpectedNode("TEL", "80", new TypeSet("CAR")) 526 .addExpectedNode("TEL", "90", new TypeSet("WORK", "PREF")) 527 .addExpectedNode("TEL", "100", new TypeSet("ISDN")) 528 .addExpectedNode("TEL", "110", new TypeSet("PREF")) 529 .addExpectedNode("TEL", "120", new TypeSet("FAX")) 530 .addExpectedNode("TEL", "130", new TypeSet("TLX")) 531 .addExpectedNode("TEL", "140", new TypeSet("WORK", "CELL")) 532 .addExpectedNode("TEL", "150", new TypeSet("WORK", "PAGER")) 533 .addExpectedNode("TEL", "160", new TypeSet("MSG")); 534 } 535 } 536 537 public void testPhoneVariousTypeSupportV21() { 538 testPhoneVariousTypeSupport(V21); 539 } 540 541 public void testPhoneVariousTypeSupportV30() { 542 testPhoneVariousTypeSupport(V30); 543 } 544 545 public void testPhoneVariousTypeSupportV40() { 546 testPhoneVariousTypeSupport(V40); 547 } 548 549 /** 550 * Tests that "PREF"s are emitted appropriately. 551 */ 552 private void testPhonePrefHandlingCommon(int vcardType) { 553 mVerifier.initForExportTest(vcardType); 554 ContactEntry entry = mVerifier.addInputEntry(); 555 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 556 .put(Phone.NUMBER, "1") 557 .put(Phone.TYPE, Phone.TYPE_HOME); 558 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 559 .put(Phone.NUMBER, "2") 560 .put(Phone.TYPE, Phone.TYPE_WORK) 561 .put(Phone.IS_PRIMARY, 1); 562 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 563 .put(Phone.NUMBER, "3") 564 .put(Phone.TYPE, Phone.TYPE_FAX_HOME) 565 .put(Phone.IS_PRIMARY, 1); 566 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 567 .put(Phone.NUMBER, "4") 568 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 569 570 if (VCardConfig.isVersion40(vcardType)) { 571 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 572 .addExpectedNode("TEL", "tel:4", new TypeSet("WORK", "FAX")) 573 .addExpectedNode("TEL", "tel:3", new TypeSet("HOME", "FAX", "PREF")) 574 .addExpectedNode("TEL", "tel:2", new TypeSet("WORK", "PREF")) 575 .addExpectedNode("TEL", "tel:1", new TypeSet("HOME")); 576 } else { 577 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 578 .addExpectedNode("TEL", "4", new TypeSet("WORK", "FAX")) 579 .addExpectedNode("TEL", "3", new TypeSet("HOME", "FAX", "PREF")) 580 .addExpectedNode("TEL", "2", new TypeSet("WORK", "PREF")) 581 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 582 } 583 } 584 585 public void testPhonePrefHandlingV21() { 586 testPhonePrefHandlingCommon(V21); 587 } 588 589 public void testPhonePrefHandlingV30() { 590 testPhonePrefHandlingCommon(V30); 591 } 592 593 public void testPhonePrefHandlingV40() { 594 testPhonePrefHandlingCommon(V40); 595 } 596 597 private void testMiscPhoneTypeHandling(int vcardType) { 598 mVerifier.initForExportTest(vcardType); 599 ContactEntry entry = mVerifier.addInputEntry(); 600 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 601 .put(Phone.NUMBER, "1") 602 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 603 .put(Phone.LABEL, "Modem"); 604 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 605 .put(Phone.NUMBER, "2") 606 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 607 .put(Phone.LABEL, "MSG"); 608 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 609 .put(Phone.NUMBER, "3") 610 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 611 .put(Phone.LABEL, "BBS"); 612 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 613 .put(Phone.NUMBER, "4") 614 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 615 .put(Phone.LABEL, "VIDEO"); 616 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 617 .put(Phone.NUMBER, "5") 618 .put(Phone.TYPE, Phone.TYPE_CUSTOM); 619 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 620 .put(Phone.NUMBER, "6") 621 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 622 .put(Phone.LABEL, "_AUTO_CELL"); // The old indicator for the type mobile. 623 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 624 .put(Phone.NUMBER, "7") 625 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 626 .put(Phone.LABEL, "\u643A\u5E2F"); // Mobile phone in Japanese Kanji 627 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 628 .put(Phone.NUMBER, "8") 629 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 630 .put(Phone.LABEL, "invalid"); 631 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName(); 632 if (VCardConfig.isVersion40(vcardType)) { 633 // vCard 4.0 (rev.13) does not allow bare number but URI. 634 elem.addExpectedNode("TEL", "tel:1", new TypeSet("Modem")) 635 .addExpectedNode("TEL", "tel:2", new TypeSet("MSG")) 636 .addExpectedNode("TEL", "tel:3", new TypeSet("BBS")) 637 .addExpectedNode("TEL", "tel:4", new TypeSet("VIDEO")) 638 .addExpectedNode("TEL", "tel:5", new TypeSet("VOICE")) 639 .addExpectedNode("TEL", "tel:6", new TypeSet("CELL")) 640 .addExpectedNode("TEL", "tel:7", new TypeSet("CELL")) 641 .addExpectedNode("TEL", "tel:8", new TypeSet("invalid")); 642 } else if (VCardConfig.isVersion30(vcardType)) { 643 // vCard 3.0 accepts "invalid". Also stop using toUpper() 644 elem.addExpectedNode("TEL", "1", new TypeSet("Modem")) 645 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 646 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 647 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 648 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 649 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 650 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 651 .addExpectedNode("TEL", "8", new TypeSet("invalid")); 652 } else { 653 elem.addExpectedNode("TEL", "1", new TypeSet("MODEM")) 654 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 655 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 656 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 657 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 658 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 659 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 660 .addExpectedNode("TEL", "8", new TypeSet("X-invalid")); 661 } 662 } 663 664 public void testPhoneTypeHandlingV21() { 665 testMiscPhoneTypeHandling(V21); 666 } 667 668 public void testPhoneTypeHandlingV30() { 669 testMiscPhoneTypeHandling(V30); 670 } 671 672 public void testPhoneTypeHandlingV40() { 673 testMiscPhoneTypeHandling(V40); 674 } 675 676 private void testEmailBasicCommon(int vcardType) { 677 mVerifier.initForExportTest(vcardType); 678 mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE) 679 .put(Email.DATA, "sample@example.com"); 680 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 681 .addExpectedNode("EMAIL", "sample@example.com"); 682 } 683 684 public void testEmailBasicV21() { 685 testEmailBasicCommon(V21); 686 } 687 688 public void testEmailBasicV30() { 689 testEmailBasicCommon(V30); 690 } 691 692 public void testEmailBasicV40() { 693 testEmailBasicCommon(V40); 694 } 695 696 private void testEmailVariousTypeSupportCommon(int vcardType) { 697 mVerifier.initForExportTest(vcardType); 698 ContactEntry entry = mVerifier.addInputEntry(); 699 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 700 .put(Email.DATA, "type_home@example.com") 701 .put(Email.TYPE, Email.TYPE_HOME); 702 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 703 .put(Email.DATA, "type_work@example.com") 704 .put(Email.TYPE, Email.TYPE_WORK); 705 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 706 .put(Email.DATA, "type_mobile@example.com") 707 .put(Email.TYPE, Email.TYPE_MOBILE); 708 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 709 .put(Email.DATA, "type_other@example.com") 710 .put(Email.TYPE, Email.TYPE_OTHER); 711 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 712 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME")) 713 .addExpectedNode("EMAIL", "type_work@example.com", new TypeSet("WORK")) 714 .addExpectedNode("EMAIL", "type_mobile@example.com", new TypeSet("CELL")) 715 .addExpectedNode("EMAIL", "type_other@example.com"); 716 } 717 718 public void testEmailVariousTypeSupportV21() { 719 testEmailVariousTypeSupportCommon(V21); 720 } 721 722 public void testEmailVariousTypeSupportV30() { 723 testEmailVariousTypeSupportCommon(V30); 724 } 725 726 public void testEmailVariousTypeSupportV40() { 727 testEmailVariousTypeSupportCommon(V40); 728 } 729 730 private void testEmailPrefHandlingCommon(int vcardType) { 731 mVerifier.initForExportTest(vcardType); 732 ContactEntry entry = mVerifier.addInputEntry(); 733 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 734 .put(Email.DATA, "type_home@example.com") 735 .put(Email.TYPE, Email.TYPE_HOME) 736 .put(Email.IS_PRIMARY, 1); 737 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 738 .put(Email.DATA, "type_notype@example.com") 739 .put(Email.IS_PRIMARY, 1); 740 741 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 742 .addExpectedNode("EMAIL", "type_notype@example.com", new TypeSet("PREF")) 743 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF")); 744 } 745 746 public void testEmailPrefHandlingV21() { 747 testEmailPrefHandlingCommon(V21); 748 } 749 750 public void testEmailPrefHandlingV30() { 751 testEmailPrefHandlingCommon(V30); 752 } 753 754 public void testEmailPrefHandlingV40() { 755 testEmailPrefHandlingCommon(V40); 756 } 757 758 private void testPostalAddressCommon(int vcardType) { 759 mVerifier.initForExportTest(vcardType); 760 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 761 .put(StructuredPostal.POBOX, "Pobox") 762 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood") 763 .put(StructuredPostal.STREET, "Street") 764 .put(StructuredPostal.CITY, "City") 765 .put(StructuredPostal.REGION, "Region") 766 .put(StructuredPostal.POSTCODE, "100") 767 .put(StructuredPostal.COUNTRY, "Country") 768 .put(StructuredPostal.FORMATTED_ADDRESS, "Formatted Address") 769 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK); 770 // adr-value = 0*6(text-value ";") text-value 771 // ; PO Box, Extended Address, Street, Locality, Region, Postal Code, 772 // ; Country Name 773 // 774 // The NEIGHBORHOOD field is appended after the CITY field. 775 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 776 .addExpectedNode("ADR", 777 Arrays.asList("Pobox", "", "Street", "City Neighborhood", 778 "Region", "100", "Country"), new TypeSet("WORK")); 779 } 780 781 public void testPostalAddressV21() { 782 testPostalAddressCommon(V21); 783 } 784 785 public void testPostalAddressV30() { 786 testPostalAddressCommon(V30); 787 } 788 789 public void testPostalAddressV40() { 790 testPostalAddressCommon(V40); 791 } 792 793 private void testPostalAddressNonNeighborhood(int vcardType) { 794 mVerifier.initForExportTest(vcardType); 795 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 796 .put(StructuredPostal.CITY, "City"); 797 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 798 .addExpectedNode("ADR", 799 Arrays.asList("", "", "", "City", "", "", ""), new TypeSet("HOME")); 800 } 801 802 public void testPostalAddressNonNeighborhoodV21() { 803 testPostalAddressNonNeighborhood(V21); 804 } 805 806 public void testPostalAddressNonNeighborhoodV30() { 807 testPostalAddressNonNeighborhood(V30); 808 } 809 810 public void testPostalAddressNonNeighborhoodV40() { 811 testPostalAddressNonNeighborhood(V40); 812 } 813 814 private void testPostalAddressNonCity(int vcardType) { 815 mVerifier.initForExportTest(vcardType); 816 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 817 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood"); 818 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 819 .addExpectedNode("ADR", 820 Arrays.asList("", "", "", "Neighborhood", "", "", ""), new TypeSet("HOME")); 821 } 822 823 public void testPostalAddressNonCityV21() { 824 testPostalAddressNonCity(V21); 825 } 826 827 public void testPostalAddressNonCityV30() { 828 testPostalAddressNonCity(V30); 829 } 830 831 public void testPostalAddressNonCityV40() { 832 testPostalAddressNonCity(V40); 833 } 834 835 private void testPostalOnlyWithFormattedAddressCommon(int vcardType) { 836 mVerifier.initForExportTest(vcardType); 837 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 838 .put(StructuredPostal.REGION, "") // Must be ignored. 839 .put(StructuredPostal.FORMATTED_ADDRESS, 840 "Formatted address CA 123-334 United Statue"); 841 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 842 .addExpectedNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;", 843 Arrays.asList("", "Formatted address CA 123-334 United Statue", 844 "", "", "", "", ""), new TypeSet("HOME")); 845 } 846 847 public void testPostalOnlyWithFormattedAddressV21() { 848 testPostalOnlyWithFormattedAddressCommon(V21); 849 } 850 851 public void testPostalOnlyWithFormattedAddressV30() { 852 testPostalOnlyWithFormattedAddressCommon(V30); 853 } 854 855 public void testPostalOnlyWithFormattedAddressV40() { 856 testPostalOnlyWithFormattedAddressCommon(V40); 857 } 858 859 /** 860 * Tests that the vCard composer honors formatted data when it is available 861 * even when it is partial. 862 */ 863 private void testPostalWithBothStructuredAndFormattedCommon(int vcardType) { 864 mVerifier.initForExportTest(vcardType); 865 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 866 .put(StructuredPostal.POBOX, "Pobox") 867 .put(StructuredPostal.COUNTRY, "Country") 868 .put(StructuredPostal.FORMATTED_ADDRESS, 869 "Formatted address CA 123-334 United Statue"); // Should be ignored 870 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 871 .addExpectedNode("ADR", "Pobox;;;;;;Country", 872 Arrays.asList("Pobox", "", "", "", "", "", "Country"), 873 new TypeSet("HOME")); 874 } 875 876 public void testPostalWithBothStructuredAndFormattedV21() { 877 testPostalWithBothStructuredAndFormattedCommon(V21); 878 } 879 880 public void testPostalWithBothStructuredAndFormattedV30() { 881 testPostalWithBothStructuredAndFormattedCommon(V30); 882 } 883 884 public void testPostalWithBothStructuredAndFormattedV40() { 885 testPostalWithBothStructuredAndFormattedCommon(V40); 886 } 887 888 private void testOrganizationCommon(int vcardType) { 889 mVerifier.initForExportTest(vcardType); 890 ContactEntry entry = mVerifier.addInputEntry(); 891 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 892 .put(Organization.COMPANY, "CompanyX") 893 .put(Organization.DEPARTMENT, "DepartmentY") 894 .put(Organization.TITLE, "TitleZ") 895 .put(Organization.JOB_DESCRIPTION, "Description Rambda") // Ignored. 896 .put(Organization.OFFICE_LOCATION, "Mountain View") // Ignored. 897 .put(Organization.PHONETIC_NAME, "PhoneticName!") // Ignored 898 .put(Organization.SYMBOL, "(^o^)/~~"); // Ignore him (her). 899 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 900 .putNull(Organization.COMPANY) 901 .put(Organization.DEPARTMENT, "DepartmentXX") 902 .putNull(Organization.TITLE); 903 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 904 .put(Organization.COMPANY, "CompanyXYZ") 905 .putNull(Organization.DEPARTMENT) 906 .put(Organization.TITLE, "TitleXYZYX"); 907 // Currently we do not use group but depend on the order. 908 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 909 .addExpectedNodeWithOrder("ORG", "CompanyX;DepartmentY", 910 Arrays.asList("CompanyX", "DepartmentY")) 911 .addExpectedNodeWithOrder("TITLE", "TitleZ") 912 .addExpectedNodeWithOrder("ORG", "DepartmentXX") 913 .addExpectedNodeWithOrder("ORG", "CompanyXYZ") 914 .addExpectedNodeWithOrder("TITLE", "TitleXYZYX"); 915 } 916 917 public void testOrganizationV21() { 918 testOrganizationCommon(V21); 919 } 920 921 public void testOrganizationV30() { 922 testOrganizationCommon(V30); 923 } 924 925 public void testOrganizationV40() { 926 testOrganizationCommon(V40); 927 } 928 929 private void testImVariousTypeSupportCommon(int vcardType) { 930 mVerifier.initForExportTest(vcardType); 931 ContactEntry entry = mVerifier.addInputEntry(); 932 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 933 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 934 .put(Im.DATA, "aim"); 935 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 936 .put(Im.PROTOCOL, Im.PROTOCOL_MSN) 937 .put(Im.DATA, "msn"); 938 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 939 .put(Im.PROTOCOL, Im.PROTOCOL_YAHOO) 940 .put(Im.DATA, "yahoo"); 941 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 942 .put(Im.PROTOCOL, Im.PROTOCOL_SKYPE) 943 .put(Im.DATA, "skype"); 944 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 945 .put(Im.PROTOCOL, Im.PROTOCOL_QQ) 946 .put(Im.DATA, "qq"); 947 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 948 .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK) 949 .put(Im.DATA, "google talk"); 950 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 951 .put(Im.PROTOCOL, Im.PROTOCOL_ICQ) 952 .put(Im.DATA, "icq"); 953 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 954 .put(Im.PROTOCOL, Im.PROTOCOL_JABBER) 955 .put(Im.DATA, "jabber"); 956 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 957 .put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING) 958 .put(Im.DATA, "netmeeting"); 959 960 // No determined way to express unknown type... 961 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 962 .addExpectedNode("X-JABBER", "jabber") 963 .addExpectedNode("X-ICQ", "icq") 964 .addExpectedNode("X-GOOGLE-TALK", "google talk") 965 .addExpectedNode("X-QQ", "qq") 966 .addExpectedNode("X-SKYPE-USERNAME", "skype") 967 .addExpectedNode("X-YAHOO", "yahoo") 968 .addExpectedNode("X-MSN", "msn") 969 .addExpectedNode("X-NETMEETING", "netmeeting") 970 .addExpectedNode("X-AIM", "aim"); 971 } 972 973 public void testImBasiV21() { 974 testImVariousTypeSupportCommon(V21); 975 } 976 977 public void testImBasicV30() { 978 testImVariousTypeSupportCommon(V30); 979 } 980 981 public void testImBasicV40() { 982 testImVariousTypeSupportCommon(V40); 983 } 984 985 private void testImPrefHandlingCommon(int vcardType) { 986 mVerifier.initForExportTest(vcardType); 987 ContactEntry entry = mVerifier.addInputEntry(); 988 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 989 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 990 .put(Im.DATA, "aim1"); 991 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 992 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 993 .put(Im.DATA, "aim2") 994 .put(Im.TYPE, Im.TYPE_HOME) 995 .put(Im.IS_PRIMARY, 1); 996 997 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 998 .addExpectedNode("X-AIM", "aim1") 999 .addExpectedNode("X-AIM", "aim2", new TypeSet("HOME", "PREF")); 1000 } 1001 1002 public void testImPrefHandlingV21() { 1003 testImPrefHandlingCommon(V21); 1004 } 1005 1006 public void testImPrefHandlingV30() { 1007 testImPrefHandlingCommon(V30); 1008 } 1009 1010 public void testImPrefHandlingV40() { 1011 testImPrefHandlingCommon(V40); 1012 } 1013 1014 private void testWebsiteCommon(int vcardType) { 1015 mVerifier.initForExportTest(vcardType); 1016 ContactEntry entry = mVerifier.addInputEntry(); 1017 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 1018 .put(Website.URL, "http://website.example.android.com/index.html") 1019 .put(Website.TYPE, Website.TYPE_BLOG); 1020 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 1021 .put(Website.URL, "ftp://ftp.example.android.com/index.html") 1022 .put(Website.TYPE, Website.TYPE_FTP); 1023 1024 // We drop TYPE information since vCard (especially 3.0) does not allow us to emit it. 1025 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1026 .addExpectedNode("URL", "ftp://ftp.example.android.com/index.html") 1027 .addExpectedNode("URL", "http://website.example.android.com/index.html"); 1028 } 1029 1030 public void testWebsiteV21() { 1031 testWebsiteCommon(V21); 1032 } 1033 1034 public void testWebsiteV30() { 1035 testWebsiteCommon(V30); 1036 } 1037 1038 public void testWebsiteV40() { 1039 testWebsiteCommon(V40); 1040 } 1041 1042 private String getAndroidPropValue(final String mimeType, String value, Integer type) { 1043 return getAndroidPropValue(mimeType, value, type, null); 1044 } 1045 1046 private String getAndroidPropValue(final String mimeType, String value, 1047 Integer type, String label) { 1048 return (mimeType + ";" + value + ";" 1049 + (type != null ? type : "") + ";" 1050 + (label != null ? label : "") + ";;;;;;;;;;;;"); 1051 } 1052 1053 private void testEventCommon(int vcardType) { 1054 mVerifier.initForExportTest(vcardType); 1055 ContactEntry entry = mVerifier.addInputEntry(); 1056 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1057 .put(Event.TYPE, Event.TYPE_ANNIVERSARY) 1058 .put(Event.START_DATE, "1982-06-16"); 1059 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1060 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 1061 .put(Event.START_DATE, "2008-10-22"); 1062 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1063 .put(Event.TYPE, Event.TYPE_OTHER) 1064 .put(Event.START_DATE, "2018-03-12"); 1065 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1066 .put(Event.TYPE, Event.TYPE_CUSTOM) 1067 .put(Event.LABEL, "The last day") 1068 .put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed."); 1069 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1070 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 1071 .put(Event.START_DATE, "2009-05-19"); // Should be ignored. 1072 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1073 .addExpectedNode("BDAY", "2008-10-22") 1074 .addExpectedNode("X-ANDROID-CUSTOM", 1075 getAndroidPropValue( 1076 Event.CONTENT_ITEM_TYPE, "1982-06-16", Event.TYPE_ANNIVERSARY)) 1077 .addExpectedNode("X-ANDROID-CUSTOM", 1078 getAndroidPropValue( 1079 Event.CONTENT_ITEM_TYPE, "2018-03-12", Event.TYPE_OTHER)) 1080 .addExpectedNode("X-ANDROID-CUSTOM", 1081 getAndroidPropValue( 1082 Event.CONTENT_ITEM_TYPE, 1083 "When the Tower of Hanoi with 64 rings is completed.", 1084 Event.TYPE_CUSTOM, "The last day")); 1085 } 1086 1087 public void testEventV21() { 1088 testEventCommon(V21); 1089 } 1090 1091 public void testEventV30() { 1092 testEventCommon(V30); 1093 } 1094 1095 public void testEventV40() { 1096 testEventCommon(V40); 1097 } 1098 1099 private void testNoteCommon(int vcardType) { 1100 mVerifier.initForExportTest(vcardType); 1101 ContactEntry entry = mVerifier.addInputEntry(); 1102 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 1103 .put(Note.NOTE, "note1"); 1104 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 1105 .put(Note.NOTE, "note2") 1106 .put(Note.IS_PRIMARY, 1); // Just ignored. 1107 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1108 .addExpectedNodeWithOrder("NOTE", "note1") 1109 .addExpectedNodeWithOrder("NOTE", "note2"); 1110 } 1111 1112 public void testNoteV21() { 1113 testNoteCommon(V21); 1114 } 1115 1116 public void testNoteV30() { 1117 testNoteCommon(V30); 1118 } 1119 1120 public void testNoteV40() { 1121 testNoteCommon(V40); 1122 } 1123 1124 private void testPhotoCommon(int vcardType) { 1125 final boolean useB = 1126 (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType)); 1127 mVerifier.initForExportTest(vcardType); 1128 ContactEntry entry = mVerifier.addInputEntry(); 1129 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1130 .put(StructuredName.FAMILY_NAME, "PhotoTest"); 1131 entry.addContentValues(Photo.CONTENT_ITEM_TYPE) 1132 .put(Photo.PHOTO, sPhotoByteArray); 1133 1134 ContentValues contentValuesForPhoto = new ContentValues(); 1135 contentValuesForPhoto.put("ENCODING", (useB ? "b" : "BASE64")); 1136 mVerifier.addPropertyNodesVerifierElem() 1137 .addExpectedNode("FN", "PhotoTest") 1138 .addExpectedNode("N", "PhotoTest;;;;", 1139 Arrays.asList("PhotoTest", "", "", "", "")) 1140 .addExpectedNodeWithOrder("PHOTO", null, null, sPhotoByteArray, 1141 contentValuesForPhoto, new TypeSet("JPEG"), null); 1142 } 1143 1144 public void testPhotoV21() { 1145 testPhotoCommon(V21); 1146 } 1147 1148 public void testPhotoV30() { 1149 testPhotoCommon(V30); 1150 } 1151 1152 public void testPhotoV40() { 1153 testPhotoCommon(V40); 1154 } 1155 1156 private void testRelationCommon(int vcardType) { 1157 mVerifier.initForExportTest(vcardType); 1158 mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE) 1159 .put(Relation.TYPE, Relation.TYPE_MOTHER) 1160 .put(Relation.NAME, "Ms. Mother"); 1161 mVerifier.addContentValuesVerifierElem().addExpected(Relation.CONTENT_ITEM_TYPE) 1162 .put(Relation.TYPE, Relation.TYPE_MOTHER) 1163 .put(Relation.NAME, "Ms. Mother"); 1164 } 1165 1166 public void testRelationV21() { 1167 testRelationCommon(V21); 1168 } 1169 1170 public void testRelationV30() { 1171 testRelationCommon(V30); 1172 } 1173 1174 public void testV30HandleEscape() { 1175 mVerifier.initForExportTest(V30); 1176 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1177 .put(StructuredName.FAMILY_NAME, "\\") 1178 .put(StructuredName.GIVEN_NAME, ";") 1179 .put(StructuredName.MIDDLE_NAME, ",") 1180 .put(StructuredName.PREFIX, "\n") 1181 .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]"); 1182 // Verifies the vCard String correctly escapes each character which must be escaped. 1183 mVerifier.addLineVerifierElem() 1184 .addExpected("N:\\\\;\\;;\\,;\\n;") 1185 .addExpected("FN:[<{Unescaped:Asciis}>]"); 1186 mVerifier.addPropertyNodesVerifierElem() 1187 .addExpectedNode("FN", "[<{Unescaped:Asciis}>]") 1188 .addExpectedNode("N", Arrays.asList("\\", ";", ",", "\n", "")); 1189 } 1190 1191 /** 1192 * There's no "NICKNAME" property in vCard 2.1, while there is in vCard 3.0. 1193 * We use Android-specific "X-ANDROID-CUSTOM" property. 1194 * This test verifies the functionality. 1195 */ 1196 public void testNickNameV21() { 1197 mVerifier.initForExportTest(V21); 1198 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 1199 .put(Nickname.NAME, "Nicky"); 1200 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1201 .addExpectedNode("X-ANDROID-CUSTOM", 1202 Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;"); 1203 mVerifier.addContentValuesVerifierElem().addExpected(Nickname.CONTENT_ITEM_TYPE) 1204 .put(Nickname.NAME, "Nicky"); 1205 } 1206 1207 public void testTolerateBrokenPhoneNumberEntryV21() { 1208 mVerifier.initForExportTest(V21); 1209 ContactEntry entry = mVerifier.addInputEntry(); 1210 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 1211 .put(Phone.TYPE, Phone.TYPE_HOME) 1212 .put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo);" 1213 + "777-888-9999 (Chicago);111-222-3333 (Miami)"); 1214 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1215 .addExpectedNode("TEL", "111-222-3333", new TypeSet("HOME")) 1216 .addExpectedNode("TEL", "444-555-5666", new TypeSet("HOME")) 1217 .addExpectedNode("TEL", "777-888-9999", new TypeSet("HOME")); 1218 } 1219 1220 private void testPickUpNonEmptyContentValuesCommon(int vcardType) { 1221 mVerifier.initForExportTest(vcardType); 1222 ContactEntry entry = mVerifier.addInputEntry(); 1223 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1224 .put(StructuredName.IS_PRIMARY, 1); // Empty name. Should be ignored. 1225 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1226 .put(StructuredName.FAMILY_NAME, "family1") // Not primary. Should be ignored. 1227 .put(StructuredName.DISPLAY_NAME, "display"); 1228 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1229 .put(StructuredName.IS_PRIMARY, 1) 1230 .put(StructuredName.FAMILY_NAME, "family2") // This entry is what we want. 1231 .put(StructuredName.DISPLAY_NAME, "display"); 1232 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1233 .put(StructuredName.IS_PRIMARY, 1) 1234 .put(StructuredName.FAMILY_NAME, "family3") 1235 .put(StructuredName.DISPLAY_NAME, "display"); 1236 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1237 .put(StructuredName.FAMILY_NAME, "family4") 1238 .put(StructuredName.DISPLAY_NAME, "display"); 1239 mVerifier.addPropertyNodesVerifierElem() 1240 .addExpectedNode("N", Arrays.asList("family2", "", "", "", "")) 1241 .addExpectedNode("FN", "display"); 1242 } 1243 1244 public void testPickUpNonEmptyContentValuesV21() { 1245 testPickUpNonEmptyContentValuesCommon(V21); 1246 } 1247 1248 public void testPickUpNonEmptyContentValuesV30() { 1249 testPickUpNonEmptyContentValuesCommon(V30); 1250 } 1251 1252 public void testPickUpNonEmptyContentValuesV40() { 1253 testPickUpNonEmptyContentValuesCommon(V40); 1254 } 1255 1256 public void testUseMultiByteTypeV30() { 1257 mVerifier.initForExportTest(V30); 1258 final ContactEntry entry = mVerifier.addInputEntry(); 1259 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 1260 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 1261 .put(Phone.LABEL, "\u96FB\u8A71") 1262 .put(Phone.NUMBER, "1"); 1263 mVerifier.addLineVerifierElem() 1264 .addExpected("N:") 1265 .addExpected("FN:") 1266 .addExpected("TEL;TYPE=\u96FB\u8A71:1"); 1267 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1268 .addExpectedNode("TEL", "1", new TypeSet("\u96FB\u8A71")); 1269 } 1270 1271 public void testSipAddressV21() { 1272 mVerifier.initForExportTest(V21); 1273 final ContactEntry entry = mVerifier.addInputEntry(); 1274 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1275 .put(SipAddress.SIP_ADDRESS, "gold"); 1276 mVerifier.addLineVerifierElem() 1277 .addExpected("X-SIP:gold"); 1278 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1279 .addExpectedNode("X-SIP", "gold"); 1280 } 1281 1282 public void testSipAddressV30() { 1283 mVerifier.initForExportTest(V30); 1284 final ContactEntry entry = mVerifier.addInputEntry(); 1285 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1286 .put(SipAddress.SIP_ADDRESS, "android@example.com"); 1287 mVerifier.addLineVerifierElem() 1288 .addExpected("N:") 1289 .addExpected("FN:") 1290 .addExpected("IMPP:sip:android@example.com"); 1291 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1292 .addExpectedNode("IMPP", "sip:android@example.com"); 1293 } 1294 1295 public void testSipAddressV40() { 1296 mVerifier.initForExportTest(V40); 1297 final ContactEntry entry = mVerifier.addInputEntry(); 1298 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1299 .put(SipAddress.SIP_ADDRESS, "android@example.com"); 1300 mVerifier.addLineVerifierElem() 1301 .addExpected("FN:") 1302 .addExpected("TEL:sip:android@example.com"); 1303 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1304 .addExpectedNode("TEL", "sip:android@example.com"); 1305 } 1306} 1307