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