VCardExporterTests.java revision 5db8b7baeffb35191032789cb0b0d643b78f0120
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.test_utils.ContactEntry; 21import com.android.vcard.tests.test_utils.PropertyNodesVerifierElem; 22import com.android.vcard.tests.test_utils.PropertyNodesVerifierElem.TypeSet; 23import com.android.vcard.tests.test_utils.VCardTestsBase; 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 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 412 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 413 } 414 415 public void testPhoneBasicV21() { 416 testPhoneBasicCommon(V21); 417 } 418 419 public void testPhoneBasicV30() { 420 testPhoneBasicCommon(V30); 421 } 422 423 public void testPhoneBasicV40() { 424 testPhoneBasicCommon(V40); 425 } 426 427 public void testPhoneRefrainFormatting() { 428 mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING); 429 mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) 430 .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)") 431 .put(Phone.TYPE, Phone.TYPE_HOME); 432 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 433 .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)", 434 new TypeSet("HOME")); 435 } 436 437 /** 438 * Tests that vCard composer emits corresponding type param which we expect. 439 */ 440 private void testPhoneVariousTypeSupport(int vcardType) { 441 mVerifier.initForExportTest(vcardType); 442 ContactEntry entry = mVerifier.addInputEntry(); 443 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 444 .put(Phone.NUMBER, "10") 445 .put(Phone.TYPE, Phone.TYPE_HOME); 446 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 447 .put(Phone.NUMBER, "20") 448 .put(Phone.TYPE, Phone.TYPE_WORK); 449 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 450 .put(Phone.NUMBER, "30") 451 .put(Phone.TYPE, Phone.TYPE_FAX_HOME); 452 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 453 .put(Phone.NUMBER, "40") 454 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 455 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 456 .put(Phone.NUMBER, "50") 457 .put(Phone.TYPE, Phone.TYPE_MOBILE); 458 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 459 .put(Phone.NUMBER, "60") 460 .put(Phone.TYPE, Phone.TYPE_PAGER); 461 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 462 .put(Phone.NUMBER, "70") 463 .put(Phone.TYPE, Phone.TYPE_OTHER); 464 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 465 .put(Phone.NUMBER, "80") 466 .put(Phone.TYPE, Phone.TYPE_CAR); 467 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 468 .put(Phone.NUMBER, "90") 469 .put(Phone.TYPE, Phone.TYPE_COMPANY_MAIN); 470 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 471 .put(Phone.NUMBER, "100") 472 .put(Phone.TYPE, Phone.TYPE_ISDN); 473 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 474 .put(Phone.NUMBER, "110") 475 .put(Phone.TYPE, Phone.TYPE_MAIN); 476 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 477 .put(Phone.NUMBER, "120") 478 .put(Phone.TYPE, Phone.TYPE_OTHER_FAX); 479 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 480 .put(Phone.NUMBER, "130") 481 .put(Phone.TYPE, Phone.TYPE_TELEX); 482 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 483 .put(Phone.NUMBER, "140") 484 .put(Phone.TYPE, Phone.TYPE_WORK_MOBILE); 485 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 486 .put(Phone.NUMBER, "150") 487 .put(Phone.TYPE, Phone.TYPE_WORK_PAGER); 488 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 489 .put(Phone.NUMBER, "160") 490 .put(Phone.TYPE, Phone.TYPE_MMS); 491 492 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 493 .addExpectedNode("TEL", "10", new TypeSet("HOME")) 494 .addExpectedNode("TEL", "20", new TypeSet("WORK")) 495 .addExpectedNode("TEL", "30", new TypeSet("HOME", "FAX")) 496 .addExpectedNode("TEL", "40", new TypeSet("WORK", "FAX")) 497 .addExpectedNode("TEL", "50", new TypeSet("CELL")) 498 .addExpectedNode("TEL", "60", new TypeSet("PAGER")) 499 .addExpectedNode("TEL", "70", new TypeSet("VOICE")) 500 .addExpectedNode("TEL", "80", new TypeSet("CAR")) 501 .addExpectedNode("TEL", "90", new TypeSet("WORK", "PREF")) 502 .addExpectedNode("TEL", "100", new TypeSet("ISDN")) 503 .addExpectedNode("TEL", "110", new TypeSet("PREF")) 504 .addExpectedNode("TEL", "120", new TypeSet("FAX")) 505 .addExpectedNode("TEL", "130", new TypeSet("TLX")) 506 .addExpectedNode("TEL", "140", new TypeSet("WORK", "CELL")) 507 .addExpectedNode("TEL", "150", new TypeSet("WORK", "PAGER")) 508 .addExpectedNode("TEL", "160", new TypeSet("MSG")); 509 } 510 511 public void testPhoneVariousTypeSupportV21() { 512 testPhoneVariousTypeSupport(V21); 513 } 514 515 public void testPhoneVariousTypeSupportV30() { 516 testPhoneVariousTypeSupport(V30); 517 } 518 519 public void testPhoneVariousTypeSupportV40() { 520 testPhoneVariousTypeSupport(V40); 521 } 522 523 /** 524 * Tests that "PREF"s are emitted appropriately. 525 */ 526 private void testPhonePrefHandlingCommon(int vcardType) { 527 mVerifier.initForExportTest(vcardType); 528 ContactEntry entry = mVerifier.addInputEntry(); 529 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 530 .put(Phone.NUMBER, "1") 531 .put(Phone.TYPE, Phone.TYPE_HOME); 532 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 533 .put(Phone.NUMBER, "2") 534 .put(Phone.TYPE, Phone.TYPE_WORK) 535 .put(Phone.IS_PRIMARY, 1); 536 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 537 .put(Phone.NUMBER, "3") 538 .put(Phone.TYPE, Phone.TYPE_FAX_HOME) 539 .put(Phone.IS_PRIMARY, 1); 540 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 541 .put(Phone.NUMBER, "4") 542 .put(Phone.TYPE, Phone.TYPE_FAX_WORK); 543 544 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 545 .addExpectedNode("TEL", "4", new TypeSet("WORK", "FAX")) 546 .addExpectedNode("TEL", "3", new TypeSet("HOME", "FAX", "PREF")) 547 .addExpectedNode("TEL", "2", new TypeSet("WORK", "PREF")) 548 .addExpectedNode("TEL", "1", new TypeSet("HOME")); 549 } 550 551 public void testPhonePrefHandlingV21() { 552 testPhonePrefHandlingCommon(V21); 553 } 554 555 public void testPhonePrefHandlingV30() { 556 testPhonePrefHandlingCommon(V30); 557 } 558 559 public void testPhonePrefHandlingV40() { 560 testPhonePrefHandlingCommon(V40); 561 } 562 563 private void testMiscPhoneTypeHandling(int vcardType) { 564 mVerifier.initForExportTest(vcardType); 565 ContactEntry entry = mVerifier.addInputEntry(); 566 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 567 .put(Phone.NUMBER, "1") 568 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 569 .put(Phone.LABEL, "Modem"); 570 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 571 .put(Phone.NUMBER, "2") 572 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 573 .put(Phone.LABEL, "MSG"); 574 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 575 .put(Phone.NUMBER, "3") 576 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 577 .put(Phone.LABEL, "BBS"); 578 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 579 .put(Phone.NUMBER, "4") 580 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 581 .put(Phone.LABEL, "VIDEO"); 582 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 583 .put(Phone.NUMBER, "5") 584 .put(Phone.TYPE, Phone.TYPE_CUSTOM); 585 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 586 .put(Phone.NUMBER, "6") 587 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 588 .put(Phone.LABEL, "_AUTO_CELL"); // The old indicator for the type mobile. 589 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 590 .put(Phone.NUMBER, "7") 591 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 592 .put(Phone.LABEL, "\u643A\u5E2F"); // Mobile phone in Japanese Kanji 593 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 594 .put(Phone.NUMBER, "8") 595 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 596 .put(Phone.LABEL, "invalid"); 597 PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName(); 598 if (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType)) { 599 // vCard 3.0 accepts "invalid". Also stop using toUpper() 600 elem.addExpectedNode("TEL", "1", new TypeSet("Modem")) 601 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 602 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 603 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 604 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 605 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 606 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 607 .addExpectedNode("TEL", "8", new TypeSet("invalid")); 608 } else { 609 elem.addExpectedNode("TEL", "1", new TypeSet("MODEM")) 610 .addExpectedNode("TEL", "2", new TypeSet("MSG")) 611 .addExpectedNode("TEL", "3", new TypeSet("BBS")) 612 .addExpectedNode("TEL", "4", new TypeSet("VIDEO")) 613 .addExpectedNode("TEL", "5", new TypeSet("VOICE")) 614 .addExpectedNode("TEL", "6", new TypeSet("CELL")) 615 .addExpectedNode("TEL", "7", new TypeSet("CELL")) 616 .addExpectedNode("TEL", "8", new TypeSet("X-invalid")); 617 } 618 } 619 620 public void testPhoneTypeHandlingV21() { 621 testMiscPhoneTypeHandling(V21); 622 } 623 624 public void testPhoneTypeHandlingV30() { 625 testMiscPhoneTypeHandling(V30); 626 } 627 628 public void testPhoneTypeHandlingV40() { 629 testMiscPhoneTypeHandling(V40); 630 } 631 632 private void testEmailBasicCommon(int vcardType) { 633 mVerifier.initForExportTest(vcardType); 634 mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE) 635 .put(Email.DATA, "sample@example.com"); 636 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 637 .addExpectedNode("EMAIL", "sample@example.com"); 638 } 639 640 public void testEmailBasicV21() { 641 testEmailBasicCommon(V21); 642 } 643 644 public void testEmailBasicV30() { 645 testEmailBasicCommon(V30); 646 } 647 648 public void testEmailBasicV40() { 649 testEmailBasicCommon(V40); 650 } 651 652 private void testEmailVariousTypeSupportCommon(int vcardType) { 653 mVerifier.initForExportTest(vcardType); 654 ContactEntry entry = mVerifier.addInputEntry(); 655 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 656 .put(Email.DATA, "type_home@example.com") 657 .put(Email.TYPE, Email.TYPE_HOME); 658 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 659 .put(Email.DATA, "type_work@example.com") 660 .put(Email.TYPE, Email.TYPE_WORK); 661 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 662 .put(Email.DATA, "type_mobile@example.com") 663 .put(Email.TYPE, Email.TYPE_MOBILE); 664 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 665 .put(Email.DATA, "type_other@example.com") 666 .put(Email.TYPE, Email.TYPE_OTHER); 667 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 668 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME")) 669 .addExpectedNode("EMAIL", "type_work@example.com", new TypeSet("WORK")) 670 .addExpectedNode("EMAIL", "type_mobile@example.com", new TypeSet("CELL")) 671 .addExpectedNode("EMAIL", "type_other@example.com"); 672 } 673 674 public void testEmailVariousTypeSupportV21() { 675 testEmailVariousTypeSupportCommon(V21); 676 } 677 678 public void testEmailVariousTypeSupportV30() { 679 testEmailVariousTypeSupportCommon(V30); 680 } 681 682 public void testEmailVariousTypeSupportV40() { 683 testEmailVariousTypeSupportCommon(V40); 684 } 685 686 private void testEmailPrefHandlingCommon(int vcardType) { 687 mVerifier.initForExportTest(vcardType); 688 ContactEntry entry = mVerifier.addInputEntry(); 689 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 690 .put(Email.DATA, "type_home@example.com") 691 .put(Email.TYPE, Email.TYPE_HOME) 692 .put(Email.IS_PRIMARY, 1); 693 entry.addContentValues(Email.CONTENT_ITEM_TYPE) 694 .put(Email.DATA, "type_notype@example.com") 695 .put(Email.IS_PRIMARY, 1); 696 697 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 698 .addExpectedNode("EMAIL", "type_notype@example.com", new TypeSet("PREF")) 699 .addExpectedNode("EMAIL", "type_home@example.com", new TypeSet("HOME", "PREF")); 700 } 701 702 public void testEmailPrefHandlingV21() { 703 testEmailPrefHandlingCommon(V21); 704 } 705 706 public void testEmailPrefHandlingV30() { 707 testEmailPrefHandlingCommon(V30); 708 } 709 710 public void testEmailPrefHandlingV40() { 711 testEmailPrefHandlingCommon(V40); 712 } 713 714 private void testPostalAddressCommon(int vcardType) { 715 mVerifier.initForExportTest(vcardType); 716 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 717 .put(StructuredPostal.POBOX, "Pobox") 718 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood") 719 .put(StructuredPostal.STREET, "Street") 720 .put(StructuredPostal.CITY, "City") 721 .put(StructuredPostal.REGION, "Region") 722 .put(StructuredPostal.POSTCODE, "100") 723 .put(StructuredPostal.COUNTRY, "Country") 724 .put(StructuredPostal.FORMATTED_ADDRESS, "Formatted Address") 725 .put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK); 726 // adr-value = 0*6(text-value ";") text-value 727 // ; PO Box, Extended Address, Street, Locality, Region, Postal Code, 728 // ; Country Name 729 // 730 // The NEIGHBORHOOD field is appended after the CITY field. 731 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 732 .addExpectedNode("ADR", 733 Arrays.asList("Pobox", "", "Street", "City Neighborhood", 734 "Region", "100", "Country"), new TypeSet("WORK")); 735 } 736 737 public void testPostalAddressV21() { 738 testPostalAddressCommon(V21); 739 } 740 741 public void testPostalAddressV30() { 742 testPostalAddressCommon(V30); 743 } 744 745 public void testPostalAddressV40() { 746 testPostalAddressCommon(V40); 747 } 748 749 private void testPostalAddressNonNeighborhood(int vcardType) { 750 mVerifier.initForExportTest(vcardType); 751 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 752 .put(StructuredPostal.CITY, "City"); 753 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 754 .addExpectedNode("ADR", 755 Arrays.asList("", "", "", "City", "", "", ""), new TypeSet("HOME")); 756 } 757 758 public void testPostalAddressNonNeighborhoodV21() { 759 testPostalAddressNonNeighborhood(V21); 760 } 761 762 public void testPostalAddressNonNeighborhoodV30() { 763 testPostalAddressNonNeighborhood(V30); 764 } 765 766 public void testPostalAddressNonNeighborhoodV40() { 767 testPostalAddressNonNeighborhood(V40); 768 } 769 770 private void testPostalAddressNonCity(int vcardType) { 771 mVerifier.initForExportTest(vcardType); 772 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 773 .put(StructuredPostal.NEIGHBORHOOD, "Neighborhood"); 774 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 775 .addExpectedNode("ADR", 776 Arrays.asList("", "", "", "Neighborhood", "", "", ""), new TypeSet("HOME")); 777 } 778 779 public void testPostalAddressNonCityV21() { 780 testPostalAddressNonCity(V21); 781 } 782 783 public void testPostalAddressNonCityV30() { 784 testPostalAddressNonCity(V30); 785 } 786 787 public void testPostalAddressNonCityV40() { 788 testPostalAddressNonCity(V40); 789 } 790 791 private void testPostalOnlyWithFormattedAddressCommon(int vcardType) { 792 mVerifier.initForExportTest(vcardType); 793 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 794 .put(StructuredPostal.REGION, "") // Must be ignored. 795 .put(StructuredPostal.FORMATTED_ADDRESS, 796 "Formatted address CA 123-334 United Statue"); 797 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 798 .addExpectedNodeWithOrder("ADR", ";Formatted address CA 123-334 United Statue;;;;;", 799 Arrays.asList("", "Formatted address CA 123-334 United Statue", 800 "", "", "", "", ""), new TypeSet("HOME")); 801 } 802 803 public void testPostalOnlyWithFormattedAddressV21() { 804 testPostalOnlyWithFormattedAddressCommon(V21); 805 } 806 807 public void testPostalOnlyWithFormattedAddressV30() { 808 testPostalOnlyWithFormattedAddressCommon(V30); 809 } 810 811 public void testPostalOnlyWithFormattedAddressV40() { 812 testPostalOnlyWithFormattedAddressCommon(V40); 813 } 814 815 /** 816 * Tests that the vCard composer honors formatted data when it is available 817 * even when it is partial. 818 */ 819 private void testPostalWithBothStructuredAndFormattedCommon(int vcardType) { 820 mVerifier.initForExportTest(vcardType); 821 mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE) 822 .put(StructuredPostal.POBOX, "Pobox") 823 .put(StructuredPostal.COUNTRY, "Country") 824 .put(StructuredPostal.FORMATTED_ADDRESS, 825 "Formatted address CA 123-334 United Statue"); // Should be ignored 826 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 827 .addExpectedNode("ADR", "Pobox;;;;;;Country", 828 Arrays.asList("Pobox", "", "", "", "", "", "Country"), 829 new TypeSet("HOME")); 830 } 831 832 public void testPostalWithBothStructuredAndFormattedV21() { 833 testPostalWithBothStructuredAndFormattedCommon(V21); 834 } 835 836 public void testPostalWithBothStructuredAndFormattedV30() { 837 testPostalWithBothStructuredAndFormattedCommon(V30); 838 } 839 840 public void testPostalWithBothStructuredAndFormattedV40() { 841 testPostalWithBothStructuredAndFormattedCommon(V40); 842 } 843 844 private void testOrganizationCommon(int vcardType) { 845 mVerifier.initForExportTest(vcardType); 846 ContactEntry entry = mVerifier.addInputEntry(); 847 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 848 .put(Organization.COMPANY, "CompanyX") 849 .put(Organization.DEPARTMENT, "DepartmentY") 850 .put(Organization.TITLE, "TitleZ") 851 .put(Organization.JOB_DESCRIPTION, "Description Rambda") // Ignored. 852 .put(Organization.OFFICE_LOCATION, "Mountain View") // Ignored. 853 .put(Organization.PHONETIC_NAME, "PhoneticName!") // Ignored 854 .put(Organization.SYMBOL, "(^o^)/~~"); // Ignore him (her). 855 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 856 .putNull(Organization.COMPANY) 857 .put(Organization.DEPARTMENT, "DepartmentXX") 858 .putNull(Organization.TITLE); 859 entry.addContentValues(Organization.CONTENT_ITEM_TYPE) 860 .put(Organization.COMPANY, "CompanyXYZ") 861 .putNull(Organization.DEPARTMENT) 862 .put(Organization.TITLE, "TitleXYZYX"); 863 // Currently we do not use group but depend on the order. 864 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 865 .addExpectedNodeWithOrder("ORG", "CompanyX;DepartmentY", 866 Arrays.asList("CompanyX", "DepartmentY")) 867 .addExpectedNodeWithOrder("TITLE", "TitleZ") 868 .addExpectedNodeWithOrder("ORG", "DepartmentXX") 869 .addExpectedNodeWithOrder("ORG", "CompanyXYZ") 870 .addExpectedNodeWithOrder("TITLE", "TitleXYZYX"); 871 } 872 873 public void testOrganizationV21() { 874 testOrganizationCommon(V21); 875 } 876 877 public void testOrganizationV30() { 878 testOrganizationCommon(V30); 879 } 880 881 public void testOrganizationV40() { 882 testOrganizationCommon(V40); 883 } 884 885 private void testImVariousTypeSupportCommon(int vcardType) { 886 mVerifier.initForExportTest(vcardType); 887 ContactEntry entry = mVerifier.addInputEntry(); 888 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 889 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 890 .put(Im.DATA, "aim"); 891 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 892 .put(Im.PROTOCOL, Im.PROTOCOL_MSN) 893 .put(Im.DATA, "msn"); 894 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 895 .put(Im.PROTOCOL, Im.PROTOCOL_YAHOO) 896 .put(Im.DATA, "yahoo"); 897 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 898 .put(Im.PROTOCOL, Im.PROTOCOL_SKYPE) 899 .put(Im.DATA, "skype"); 900 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 901 .put(Im.PROTOCOL, Im.PROTOCOL_QQ) 902 .put(Im.DATA, "qq"); 903 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 904 .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK) 905 .put(Im.DATA, "google talk"); 906 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 907 .put(Im.PROTOCOL, Im.PROTOCOL_ICQ) 908 .put(Im.DATA, "icq"); 909 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 910 .put(Im.PROTOCOL, Im.PROTOCOL_JABBER) 911 .put(Im.DATA, "jabber"); 912 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 913 .put(Im.PROTOCOL, Im.PROTOCOL_NETMEETING) 914 .put(Im.DATA, "netmeeting"); 915 916 // No determined way to express unknown type... 917 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 918 .addExpectedNode("X-JABBER", "jabber") 919 .addExpectedNode("X-ICQ", "icq") 920 .addExpectedNode("X-GOOGLE-TALK", "google talk") 921 .addExpectedNode("X-QQ", "qq") 922 .addExpectedNode("X-SKYPE-USERNAME", "skype") 923 .addExpectedNode("X-YAHOO", "yahoo") 924 .addExpectedNode("X-MSN", "msn") 925 .addExpectedNode("X-NETMEETING", "netmeeting") 926 .addExpectedNode("X-AIM", "aim"); 927 } 928 929 public void testImBasiV21() { 930 testImVariousTypeSupportCommon(V21); 931 } 932 933 public void testImBasicV30() { 934 testImVariousTypeSupportCommon(V30); 935 } 936 937 public void testImBasicV40() { 938 testImVariousTypeSupportCommon(V40); 939 } 940 941 private void testImPrefHandlingCommon(int vcardType) { 942 mVerifier.initForExportTest(vcardType); 943 ContactEntry entry = mVerifier.addInputEntry(); 944 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 945 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 946 .put(Im.DATA, "aim1"); 947 entry.addContentValues(Im.CONTENT_ITEM_TYPE) 948 .put(Im.PROTOCOL, Im.PROTOCOL_AIM) 949 .put(Im.DATA, "aim2") 950 .put(Im.TYPE, Im.TYPE_HOME) 951 .put(Im.IS_PRIMARY, 1); 952 953 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 954 .addExpectedNode("X-AIM", "aim1") 955 .addExpectedNode("X-AIM", "aim2", new TypeSet("HOME", "PREF")); 956 } 957 958 public void testImPrefHandlingV21() { 959 testImPrefHandlingCommon(V21); 960 } 961 962 public void testImPrefHandlingV30() { 963 testImPrefHandlingCommon(V30); 964 } 965 966 public void testImPrefHandlingV40() { 967 testImPrefHandlingCommon(V40); 968 } 969 970 private void testWebsiteCommon(int vcardType) { 971 mVerifier.initForExportTest(vcardType); 972 ContactEntry entry = mVerifier.addInputEntry(); 973 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 974 .put(Website.URL, "http://website.example.android.com/index.html") 975 .put(Website.TYPE, Website.TYPE_BLOG); 976 entry.addContentValues(Website.CONTENT_ITEM_TYPE) 977 .put(Website.URL, "ftp://ftp.example.android.com/index.html") 978 .put(Website.TYPE, Website.TYPE_FTP); 979 980 // We drop TYPE information since vCard (especially 3.0) does not allow us to emit it. 981 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 982 .addExpectedNode("URL", "ftp://ftp.example.android.com/index.html") 983 .addExpectedNode("URL", "http://website.example.android.com/index.html"); 984 } 985 986 public void testWebsiteV21() { 987 testWebsiteCommon(V21); 988 } 989 990 public void testWebsiteV30() { 991 testWebsiteCommon(V30); 992 } 993 994 public void testWebsiteV40() { 995 testWebsiteCommon(V40); 996 } 997 998 private String getAndroidPropValue(final String mimeType, String value, Integer type) { 999 return getAndroidPropValue(mimeType, value, type, null); 1000 } 1001 1002 private String getAndroidPropValue(final String mimeType, String value, 1003 Integer type, String label) { 1004 return (mimeType + ";" + value + ";" 1005 + (type != null ? type : "") + ";" 1006 + (label != null ? label : "") + ";;;;;;;;;;;;"); 1007 } 1008 1009 private void testEventCommon(int vcardType) { 1010 mVerifier.initForExportTest(vcardType); 1011 ContactEntry entry = mVerifier.addInputEntry(); 1012 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1013 .put(Event.TYPE, Event.TYPE_ANNIVERSARY) 1014 .put(Event.START_DATE, "1982-06-16"); 1015 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1016 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 1017 .put(Event.START_DATE, "2008-10-22"); 1018 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1019 .put(Event.TYPE, Event.TYPE_OTHER) 1020 .put(Event.START_DATE, "2018-03-12"); 1021 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1022 .put(Event.TYPE, Event.TYPE_CUSTOM) 1023 .put(Event.LABEL, "The last day") 1024 .put(Event.START_DATE, "When the Tower of Hanoi with 64 rings is completed."); 1025 entry.addContentValues(Event.CONTENT_ITEM_TYPE) 1026 .put(Event.TYPE, Event.TYPE_BIRTHDAY) 1027 .put(Event.START_DATE, "2009-05-19"); // Should be ignored. 1028 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1029 .addExpectedNode("BDAY", "2008-10-22") 1030 .addExpectedNode("X-ANDROID-CUSTOM", 1031 getAndroidPropValue( 1032 Event.CONTENT_ITEM_TYPE, "1982-06-16", Event.TYPE_ANNIVERSARY)) 1033 .addExpectedNode("X-ANDROID-CUSTOM", 1034 getAndroidPropValue( 1035 Event.CONTENT_ITEM_TYPE, "2018-03-12", Event.TYPE_OTHER)) 1036 .addExpectedNode("X-ANDROID-CUSTOM", 1037 getAndroidPropValue( 1038 Event.CONTENT_ITEM_TYPE, 1039 "When the Tower of Hanoi with 64 rings is completed.", 1040 Event.TYPE_CUSTOM, "The last day")); 1041 } 1042 1043 public void testEventV21() { 1044 testEventCommon(V21); 1045 } 1046 1047 public void testEventV30() { 1048 testEventCommon(V30); 1049 } 1050 1051 public void testEventV40() { 1052 testEventCommon(V40); 1053 } 1054 1055 private void testNoteCommon(int vcardType) { 1056 mVerifier.initForExportTest(vcardType); 1057 ContactEntry entry = mVerifier.addInputEntry(); 1058 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 1059 .put(Note.NOTE, "note1"); 1060 entry.addContentValues(Note.CONTENT_ITEM_TYPE) 1061 .put(Note.NOTE, "note2") 1062 .put(Note.IS_PRIMARY, 1); // Just ignored. 1063 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1064 .addExpectedNodeWithOrder("NOTE", "note1") 1065 .addExpectedNodeWithOrder("NOTE", "note2"); 1066 } 1067 1068 public void testNoteV21() { 1069 testNoteCommon(V21); 1070 } 1071 1072 public void testNoteV30() { 1073 testNoteCommon(V30); 1074 } 1075 1076 public void testNoteV40() { 1077 testNoteCommon(V40); 1078 } 1079 1080 private void testPhotoCommon(int vcardType) { 1081 final boolean useB = 1082 (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType)); 1083 mVerifier.initForExportTest(vcardType); 1084 ContactEntry entry = mVerifier.addInputEntry(); 1085 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1086 .put(StructuredName.FAMILY_NAME, "PhotoTest"); 1087 entry.addContentValues(Photo.CONTENT_ITEM_TYPE) 1088 .put(Photo.PHOTO, sPhotoByteArray); 1089 1090 ContentValues contentValuesForPhoto = new ContentValues(); 1091 contentValuesForPhoto.put("ENCODING", (useB ? "b" : "BASE64")); 1092 mVerifier.addPropertyNodesVerifierElem() 1093 .addExpectedNode("FN", "PhotoTest") 1094 .addExpectedNode("N", "PhotoTest;;;;", 1095 Arrays.asList("PhotoTest", "", "", "", "")) 1096 .addExpectedNodeWithOrder("PHOTO", null, null, sPhotoByteArray, 1097 contentValuesForPhoto, new TypeSet("JPEG"), null); 1098 } 1099 1100 public void testPhotoV21() { 1101 testPhotoCommon(V21); 1102 } 1103 1104 public void testPhotoV30() { 1105 testPhotoCommon(V30); 1106 } 1107 1108 public void testPhotoV40() { 1109 testPhotoCommon(V40); 1110 } 1111 1112 private void testRelationCommon(int vcardType) { 1113 mVerifier.initForExportTest(vcardType); 1114 mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE) 1115 .put(Relation.TYPE, Relation.TYPE_MOTHER) 1116 .put(Relation.NAME, "Ms. Mother"); 1117 mVerifier.addContentValuesVerifierElem().addExpected(Relation.CONTENT_ITEM_TYPE) 1118 .put(Relation.TYPE, Relation.TYPE_MOTHER) 1119 .put(Relation.NAME, "Ms. Mother"); 1120 } 1121 1122 public void testRelationV21() { 1123 testRelationCommon(V21); 1124 } 1125 1126 public void testRelationV30() { 1127 testRelationCommon(V30); 1128 } 1129 1130 public void testV30HandleEscape() { 1131 mVerifier.initForExportTest(V30); 1132 mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1133 .put(StructuredName.FAMILY_NAME, "\\") 1134 .put(StructuredName.GIVEN_NAME, ";") 1135 .put(StructuredName.MIDDLE_NAME, ",") 1136 .put(StructuredName.PREFIX, "\n") 1137 .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]"); 1138 // Verifies the vCard String correctly escapes each character which must be escaped. 1139 mVerifier.addLineVerifierElem() 1140 .addExpected("N:\\\\;\\;;\\,;\\n;") 1141 .addExpected("FN:[<{Unescaped:Asciis}>]"); 1142 mVerifier.addPropertyNodesVerifierElem() 1143 .addExpectedNode("FN", "[<{Unescaped:Asciis}>]") 1144 .addExpectedNode("N", Arrays.asList("\\", ";", ",", "\n", "")); 1145 } 1146 1147 /** 1148 * There's no "NICKNAME" property in vCard 2.1, while there is in vCard 3.0. 1149 * We use Android-specific "X-ANDROID-CUSTOM" property. 1150 * This test verifies the functionality. 1151 */ 1152 public void testNickNameV21() { 1153 mVerifier.initForExportTest(V21); 1154 mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE) 1155 .put(Nickname.NAME, "Nicky"); 1156 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1157 .addExpectedNode("X-ANDROID-CUSTOM", 1158 Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;"); 1159 mVerifier.addContentValuesVerifierElem().addExpected(Nickname.CONTENT_ITEM_TYPE) 1160 .put(Nickname.NAME, "Nicky"); 1161 } 1162 1163 public void testTolerateBrokenPhoneNumberEntryV21() { 1164 mVerifier.initForExportTest(V21); 1165 ContactEntry entry = mVerifier.addInputEntry(); 1166 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 1167 .put(Phone.TYPE, Phone.TYPE_HOME) 1168 .put(Phone.NUMBER, "111-222-3333 (Miami)\n444-5555-666 (Tokyo);" 1169 + "777-888-9999 (Chicago);111-222-3333 (Miami)"); 1170 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1171 .addExpectedNode("TEL", "111-222-3333", new TypeSet("HOME")) 1172 .addExpectedNode("TEL", "444-555-5666", new TypeSet("HOME")) 1173 .addExpectedNode("TEL", "777-888-9999", new TypeSet("HOME")); 1174 } 1175 1176 private void testPickUpNonEmptyContentValuesCommon(int vcardType) { 1177 mVerifier.initForExportTest(vcardType); 1178 ContactEntry entry = mVerifier.addInputEntry(); 1179 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1180 .put(StructuredName.IS_PRIMARY, 1); // Empty name. Should be ignored. 1181 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1182 .put(StructuredName.FAMILY_NAME, "family1") // Not primary. Should be ignored. 1183 .put(StructuredName.DISPLAY_NAME, "display"); 1184 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1185 .put(StructuredName.IS_PRIMARY, 1) 1186 .put(StructuredName.FAMILY_NAME, "family2") // This entry is what we want. 1187 .put(StructuredName.DISPLAY_NAME, "display"); 1188 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1189 .put(StructuredName.IS_PRIMARY, 1) 1190 .put(StructuredName.FAMILY_NAME, "family3") 1191 .put(StructuredName.DISPLAY_NAME, "display"); 1192 entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE) 1193 .put(StructuredName.FAMILY_NAME, "family4") 1194 .put(StructuredName.DISPLAY_NAME, "display"); 1195 mVerifier.addPropertyNodesVerifierElem() 1196 .addExpectedNode("N", Arrays.asList("family2", "", "", "", "")) 1197 .addExpectedNode("FN", "display"); 1198 } 1199 1200 public void testPickUpNonEmptyContentValuesV21() { 1201 testPickUpNonEmptyContentValuesCommon(V21); 1202 } 1203 1204 public void testPickUpNonEmptyContentValuesV30() { 1205 testPickUpNonEmptyContentValuesCommon(V30); 1206 } 1207 1208 public void testPickUpNonEmptyContentValuesV40() { 1209 testPickUpNonEmptyContentValuesCommon(V40); 1210 } 1211 1212 public void testUseMultiByteTypeV30() { 1213 mVerifier.initForExportTest(V30); 1214 final ContactEntry entry = mVerifier.addInputEntry(); 1215 entry.addContentValues(Phone.CONTENT_ITEM_TYPE) 1216 .put(Phone.TYPE, Phone.TYPE_CUSTOM) 1217 .put(Phone.LABEL, "\u96FB\u8A71") 1218 .put(Phone.NUMBER, "1"); 1219 mVerifier.addLineVerifierElem() 1220 .addExpected("N:") 1221 .addExpected("FN:") 1222 .addExpected("TEL;TYPE=\u96FB\u8A71:1"); 1223 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1224 .addExpectedNode("TEL", "1", new TypeSet("\u96FB\u8A71")); 1225 } 1226 1227 public void testSipAddressV21() { 1228 mVerifier.initForExportTest(V21); 1229 final ContactEntry entry = mVerifier.addInputEntry(); 1230 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1231 .put(SipAddress.SIP_ADDRESS, "gold"); 1232 mVerifier.addLineVerifierElem() 1233 .addExpected("X-SIP:gold"); 1234 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1235 .addExpectedNode("X-SIP", "gold"); 1236 } 1237 1238 public void testSipAddressV30() { 1239 mVerifier.initForExportTest(V30); 1240 final ContactEntry entry = mVerifier.addInputEntry(); 1241 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1242 .put(SipAddress.SIP_ADDRESS, "android@example.com"); 1243 mVerifier.addLineVerifierElem() 1244 .addExpected("N:") 1245 .addExpected("FN:") 1246 .addExpected("IMPP:sip:android@example.com"); 1247 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1248 .addExpectedNode("IMPP", "sip:android@example.com"); 1249 } 1250 1251 public void testSipAddressV40() { 1252 mVerifier.initForExportTest(V40); 1253 final ContactEntry entry = mVerifier.addInputEntry(); 1254 entry.addContentValues(SipAddress.CONTENT_ITEM_TYPE) 1255 .put(SipAddress.SIP_ADDRESS, "android@example.com"); 1256 mVerifier.addLineVerifierElem() 1257 .addExpected("FN:") 1258 .addExpected("IMPP:sip:android@example.com"); 1259 mVerifier.addPropertyNodesVerifierElemWithEmptyName() 1260 .addExpectedNode("IMPP", "sip:android@example.com"); 1261 } 1262} 1263