EntityModifierTests.java revision 405671a7b42d97ebf7ae7c0eeb4721f881139673
107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey/* 207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Copyright (C) 2009 The Android Open Source Project 307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * 407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * you may not use this file except in compliance with the License. 607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * You may obtain a copy of the License at 707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * 807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * 1007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 1107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 1207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * See the License for the specific language governing permissions and 1407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * limitations under the License. 1507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 1607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 1707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeypackage com.android.contacts; 1807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_DELETE; 206f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_INSERT; 216f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_UPDATE; 226f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 234597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType; 244597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.EditType; 251173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.AccountTypeManager; 26405671a7b42d97ebf7ae7c0eeb4721f881139673Daisuke Miyakawaimport com.android.contacts.model.DataKind; 271173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityDelta; 286f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport com.android.contacts.model.EntityDelta.ValuesDelta; 291173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityDeltaList; 301173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityModifier; 311173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.tests.mocks.MockAccountTypeManager; 32aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport com.google.android.collect.Lists; 3307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 346f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport android.content.ContentProviderOperation; 3507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.content.ContentValues; 36ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkeyimport android.content.Context; 3707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.content.Entity; 3816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.os.Bundle; 397173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email; 4016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Im; 4116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Organization; 4207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Phone; 4316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 4416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 451173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.Data; 461173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.Intents.Insert; 471173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 4807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.test.AndroidTestCase; 4907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest; 5007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 5107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport java.util.ArrayList; 5207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport java.util.List; 5307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 5407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey/** 554597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov * Tests for {@link EntityModifier} to verify that {@link AccountType} 5607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * constraints are being enforced correctly. 5707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 5807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey@LargeTest 5907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeypublic class EntityModifierTests extends AndroidTestCase { 6007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey public static final String TAG = "EntityModifierTests"; 6107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 62e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey public static final long VER_FIRST = 100; 63e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 646f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey private static final long TEST_ID = 4; 656f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey private static final String TEST_PHONE = "218-555-1212"; 6616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey private static final String TEST_NAME = "Adam Young"; 6716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey private static final String TEST_NAME2 = "Breanne Duren"; 6816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey private static final String TEST_IM = "example@example.com"; 6916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey private static final String TEST_POSTAL = "1600 Amphitheatre Parkway"; 706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey private static final String TEST_ACCOUNT_NAME = "unittest@example.com"; 727f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey private static final String TEST_ACCOUNT_TYPE = "com.example.unittest"; 737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 7407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey @Override 7507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey public void setUp() { 7607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey mContext = getContext(); 7707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 7807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 794597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov public static class MockContactsSource extends AccountType { 80b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov 81b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov MockContactsSource() { 82ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey this.accountType = TEST_ACCOUNT_TYPE; 8307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 846c9b4b97752e415528279464b28560d389256783Daniel Lehmann final DataKind nameKind = new DataKind(StructuredName.CONTENT_ITEM_TYPE, 856c9b4b97752e415528279464b28560d389256783Daniel Lehmann R.string.nameLabelsGroup, -1, -1, true); 866c9b4b97752e415528279464b28560d389256783Daniel Lehmann nameKind.typeOverallMax = 1; 876c9b4b97752e415528279464b28560d389256783Daniel Lehmann addKind(nameKind); 886c9b4b97752e415528279464b28560d389256783Daniel Lehmann 8907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Phone allows maximum 2 home, 1 work, and unlimited other, with 9007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // constraint of 5 numbers maximum. 916c9b4b97752e415528279464b28560d389256783Daniel Lehmann final DataKind phoneKind = new DataKind(Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true); 9207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 936c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeOverallMax = 5; 946c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeColumn = Phone.TYPE; 956c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeList = Lists.newArrayList(); 966c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeList.add(new EditType(Phone.TYPE_HOME, -1).setSpecificMax(2)); 976c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeList.add(new EditType(Phone.TYPE_WORK, -1).setSpecificMax(1)); 986c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1).setSecondary(true)); 996c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.typeList.add(new EditType(Phone.TYPE_OTHER, -1)); 10007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 1016c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.fieldList = Lists.newArrayList(); 1026c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.fieldList.add(new EditField(Phone.NUMBER, -1, -1)); 1036c9b4b97752e415528279464b28560d389256783Daniel Lehmann phoneKind.fieldList.add(new EditField(Phone.LABEL, -1, -1)); 1046f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 1056c9b4b97752e415528279464b28560d389256783Daniel Lehmann addKind(phoneKind); 1067173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 1077173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey // Email is unlimited 1086c9b4b97752e415528279464b28560d389256783Daniel Lehmann final DataKind emailKind = new DataKind(Email.CONTENT_ITEM_TYPE, -1, -1, 10, true); 1096c9b4b97752e415528279464b28560d389256783Daniel Lehmann emailKind.typeOverallMax = -1; 1106c9b4b97752e415528279464b28560d389256783Daniel Lehmann emailKind.fieldList = Lists.newArrayList(); 1116c9b4b97752e415528279464b28560d389256783Daniel Lehmann emailKind.fieldList.add(new EditField(Email.DATA, -1, -1)); 1126c9b4b97752e415528279464b28560d389256783Daniel Lehmann addKind(emailKind); 11316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 11416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // IM is only one 1156c9b4b97752e415528279464b28560d389256783Daniel Lehmann final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10, true); 1166c9b4b97752e415528279464b28560d389256783Daniel Lehmann imKind.typeOverallMax = 1; 1176c9b4b97752e415528279464b28560d389256783Daniel Lehmann imKind.fieldList = Lists.newArrayList(); 1186c9b4b97752e415528279464b28560d389256783Daniel Lehmann imKind.fieldList.add(new EditField(Im.DATA, -1, -1)); 1196c9b4b97752e415528279464b28560d389256783Daniel Lehmann addKind(imKind); 1207173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 12116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // Organization is only one 1226c9b4b97752e415528279464b28560d389256783Daniel Lehmann final DataKind orgKind = new DataKind(Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true); 1236c9b4b97752e415528279464b28560d389256783Daniel Lehmann orgKind.typeOverallMax = 1; 1246c9b4b97752e415528279464b28560d389256783Daniel Lehmann orgKind.fieldList = Lists.newArrayList(); 1256c9b4b97752e415528279464b28560d389256783Daniel Lehmann orgKind.fieldList.add(new EditField(Organization.COMPANY, -1, -1)); 1266c9b4b97752e415528279464b28560d389256783Daniel Lehmann orgKind.fieldList.add(new EditField(Organization.TITLE, -1, -1)); 1276c9b4b97752e415528279464b28560d389256783Daniel Lehmann addKind(orgKind); 12807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 1295297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton 1305297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton @Override 1315297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton public int getHeaderColor(Context context) { 1325297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton return 0; 1335297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton } 1345297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton 1355297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton @Override 1365297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton public int getSideBarColor(Context context) { 1375297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton return 0xffffff; 1385297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton } 139ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey } 14007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 141ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey /** 1424597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov * Build a {@link AccountType} that has various odd constraints for 143ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey * testing purposes. 144ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey */ 145b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov protected AccountType getAccountType() { 146b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov return new MockContactsSource(); 14707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 14807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 14907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 150a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov * Build {@link AccountTypeManager} instance. 1517f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey */ 152a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov protected AccountTypeManager getAccountTypes(AccountType... types) { 1531173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikov return new MockAccountTypeManager(types, null); 1547f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 1557f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 1567f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey /** 15707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Build an {@link Entity} with the requested set of phone numbers. 15807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 1597f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey protected EntityDelta getEntity(Long existingId, ContentValues... entries) { 16007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final ContentValues contact = new ContentValues(); 1617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey if (existingId != null) { 1627f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey contact.put(RawContacts._ID, existingId); 1637f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 1647f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey contact.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME); 1657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE); 1667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 16707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final Entity before = new Entity(contact); 1686f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey for (ContentValues values : entries) { 1696f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.addSubValue(Data.CONTENT_URI, values); 1706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 1718d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey return EntityDelta.fromBefore(before); 17207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 17307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 17407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 17507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Assert this {@link List} contains the given {@link Object}. 17607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 17707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey protected void assertContains(List<?> list, Object object) { 17807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertTrue("Missing expected value", list.contains(object)); 17907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 18007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 18107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 18207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Assert this {@link List} does not contain the given {@link Object}. 18307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 18407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey protected void assertNotContains(List<?> list, Object object) { 18507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertFalse("Contained unexpected value", list.contains(object)); 18607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 18707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 18807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 18907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Insert various rows to test 1908d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey * {@link EntityModifier#getValidTypes(EntityDelta, DataKind, EditType)} 19107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 19207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey public void testValidTypes() { 19307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Build a source and pull specific types 194b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 19507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 19607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 19707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK); 19807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER); 19907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 20007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey List<EditType> validTypes; 20107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 20207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add first home, first work 2037f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 20407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 20507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeWork); 20607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 20707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Expecting home, other 20807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey validTypes = EntityModifier.getValidTypes(state, kindPhone, null); 20907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertContains(validTypes, typeHome); 21007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeWork); 21107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertContains(validTypes, typeOther); 21207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 21307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add second home 21407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 21507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 21607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Expecting other 21707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey validTypes = EntityModifier.getValidTypes(state, kindPhone, null); 21807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeHome); 21907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeWork); 22007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertContains(validTypes, typeOther); 22107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 22207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add third and fourth home (invalid, but possible) 22307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 22407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 22507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 22607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Expecting none 22707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey validTypes = EntityModifier.getValidTypes(state, kindPhone, null); 22807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeHome); 22907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeWork); 23007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertNotContains(validTypes, typeOther); 23107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 23207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 23307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 2348d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey * Test {@link EntityModifier#canInsert(EntityDelta, DataKind)} by 23507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * inserting various rows. 23607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 23707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey public void testCanInsert() { 23807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Build a source and pull specific types 239b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 24007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 24107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 24207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK); 24307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER); 24407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 24507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add first home, first work 2467f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 24707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 24807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeWork); 24907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone)); 25007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 25107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add two other, which puts us just under "5" overall limit 25207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeOther); 25307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeOther); 25407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone)); 25507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 25607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add second home, which should push to snug limit 25707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 25807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertFalse("Able to insert", EntityModifier.canInsert(state, kindPhone)); 25907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 26007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 26107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey /** 262d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey * Test 263d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey * {@link EntityModifier#getBestValidType(EntityDelta, DataKind, boolean, int)} 26407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * by asserting expected best options in various states. 26507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */ 26607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey public void testBestValidType() { 26707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Build a source and pull specific types 268b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 26907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 27007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 27107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK); 27207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeFaxWork = EntityModifier.getType(kindPhone, Phone.TYPE_FAX_WORK); 27307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER); 27407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 27507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EditType suggested; 27607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 27707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Default suggestion should be home 2787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 279d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE); 28007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertEquals("Unexpected suggestion", typeHome, suggested); 28107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 28207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add first home, should now suggest work 28307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeHome); 284d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE); 28507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertEquals("Unexpected suggestion", typeWork, suggested); 28607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 28707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add work fax, should still suggest work 28807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeFaxWork); 289d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE); 29007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertEquals("Unexpected suggestion", typeWork, suggested); 29107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 29207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add other, should still suggest work 29307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeOther); 294d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE); 29507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertEquals("Unexpected suggestion", typeWork, suggested); 29607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey 29707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey // Add work, now should suggest other 29807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey EntityModifier.insertChild(state, kindPhone, typeWork); 299d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE); 30007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey assertEquals("Unexpected suggestion", typeOther, suggested); 30107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey } 3026f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3036f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey public void testIsEmptyEmpty() { 304b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 3056f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 3066f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3076f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Test entirely empty row 3086f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentValues after = new ContentValues(); 3096f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ValuesDelta values = ValuesDelta.fromAfter(after); 3106f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3116f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone)); 3126f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3136f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3146f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey public void testIsEmptyDirectFields() { 315b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 3166f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 3176f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 3186f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Test row that has type values, but core fields are empty 3207f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 3216f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome); 3226f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3236f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone)); 3246f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3256f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Insert some data to trigger non-empty state 3266f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey values.put(Phone.NUMBER, TEST_PHONE); 3276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3286f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertFalse("Expected non-empty", EntityModifier.isEmpty(values, kindPhone)); 3296f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3316f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey public void testTrimEmptySingle() { 332b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 3336f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 3346f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 3356f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3366f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Test row that has type values, but core fields are empty 3377f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 3386c9b4b97752e415528279464b28560d389256783Daniel Lehmann EntityModifier.insertChild(state, kindPhone, typeHome); 3396f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3406f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Build diff, expecting insert for data row and update enforcement 3416f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 3426f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 3436f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 3, diff.size()); 3446f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 3456f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(0); 3466f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 3476f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 3486f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3496f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 3506f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(1); 3516f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); 3526f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 3536f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3546f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 3556f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(2); 3566f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 3576f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 3586f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3596f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 3607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Trim empty rows and try again, expecting delete of overall contact 3617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey EntityModifier.trimEmpty(state, source); 3626f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey diff.clear(); 3636f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 3647f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 1, diff.size()); 3657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 3667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 3677f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); 3687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 3697f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 3706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 3716f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 372e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey public void testTrimEmptySpaces() { 373b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 374e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 375e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 376e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 377e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Test row that has type values, but values are spaces 378ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST); 379e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome); 380e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey values.put(Phone.NUMBER, " "); 381e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 382e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Build diff, expecting insert for data row and update enforcement 383ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.assertDiffPattern(state, 384ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildAssertVersion(VER_FIRST), 385ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationSuspended(), 386ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT, 387ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildDataInsert(values, TEST_ID)), 388ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationDefault()); 389e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 390e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Trim empty rows and try again, expecting delete of overall contact 391e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey EntityModifier.trimEmpty(state, source); 392ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.assertDiffPattern(state, 393ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildAssertVersion(VER_FIRST), 394ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildDelete(RawContacts.CONTENT_URI)); 395e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey } 396e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 397e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey public void testTrimLeaveValid() { 398b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 399e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 400e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 401e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 402e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Test row that has type values with valid number 403ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST); 404e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome); 405e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey values.put(Phone.NUMBER, TEST_PHONE); 406e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 407e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Build diff, expecting insert for data row and update enforcement 408ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.assertDiffPattern(state, 409ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildAssertVersion(VER_FIRST), 410ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationSuspended(), 411ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT, 412ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildDataInsert(values, TEST_ID)), 413ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationDefault()); 414e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 415e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey // Trim empty rows and try again, expecting no differences 416e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey EntityModifier.trimEmpty(state, source); 417ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.assertDiffPattern(state, 418ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildAssertVersion(VER_FIRST), 419ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationSuspended(), 420ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT, 421ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildDataInsert(values, TEST_ID)), 422ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann EntityDeltaListTests.buildUpdateAggregationDefault()); 423e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey } 424e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 4256f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey public void testTrimEmptyUntouched() { 426b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 4276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 4286c9b4b97752e415528279464b28560d389256783Daniel Lehmann EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 4296f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Build "before" that has empty row 4317f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 4326f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentValues before = new ContentValues(); 4336f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(Data._ID, TEST_ID); 4346f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 4356f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.addEntry(ValuesDelta.fromBefore(before)); 4366f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4376f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Build diff, expecting no changes 4386f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 4396f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 4406f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 4416f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4426f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Try trimming existing empty, which we shouldn't touch 4437f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey EntityModifier.trimEmpty(state, source); 4446f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey diff.clear(); 4456f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 4466f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 4476f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 4486f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4496f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey public void testTrimEmptyAfterUpdate() { 450b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 4516f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 4526f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 4536f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4546f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Build "before" that has row with some phone number 4556f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentValues before = new ContentValues(); 4566f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(Data._ID, TEST_ID); 4576f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 4586f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(kindPhone.typeColumn, typeHome.rawValue); 4596f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey before.put(Phone.NUMBER, TEST_PHONE); 4607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID, before); 4616f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4626f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Build diff, expecting no changes 4636f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 4646f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 4656f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 4666f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4676f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Now update row by changing number to empty string, expecting single update 4686f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ValuesDelta child = state.getEntry(TEST_ID); 4696f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey child.put(Phone.NUMBER, ""); 4706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey diff.clear(); 4716f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 4726f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 3, diff.size()); 4736f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 4746f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(0); 4756f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 4766f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 4776f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 4786f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 4796f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(1); 4806f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect type", TYPE_UPDATE, oper.getType()); 4816f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 4826f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 4836f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 4846f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(2); 4856f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 4866f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 4876f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 4886f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey 4896f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey // Now run trim, which should turn that update into delete 4907f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey EntityModifier.trimEmpty(state, source); 4917f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 4927f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 4937f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 1, diff.size()); 4947f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 4957f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 4967f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); 4977f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 4987f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 4997f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5007f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5017f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey public void testTrimInsertEmpty() { 502a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 503a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = getAccountTypes(accountType); 504a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 5056c9b4b97752e415528279464b28560d389256783Daniel Lehmann EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 5067f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5077f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Try creating a contact without any child entries 5087f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(null); 509ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDeltaList set = EntityDeltaList.fromSingle(state); 5107f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5117f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build diff, expecting single insert 5127f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 5137f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5143aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov assertEquals("Unexpected operations", 2, diff.size()); 5157f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 5167f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 5177f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); 5187f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 5197f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5207f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5217f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Trim empty rows and try again, expecting no insert 522a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.trimEmpty(set, accountTypes); 5237f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 5247f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5257f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 5267f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5277f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5287f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey public void testTrimInsertInsert() { 529a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 530a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = getAccountTypes(accountType); 531a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 5327f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 5337f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5347f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Try creating a contact with single empty entry 5357f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(null); 5366c9b4b97752e415528279464b28560d389256783Daniel Lehmann EntityModifier.insertChild(state, kindPhone, typeHome); 537ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDeltaList set = EntityDeltaList.fromSingle(state); 5387f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5397f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build diff, expecting two insert operations 5407f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 5417f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5423aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov assertEquals("Unexpected operations", 3, diff.size()); 5437f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 5447f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 5457f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); 5467f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 5477f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5487f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 5497f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(1); 5507f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); 5517f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 5527f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5537f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5547f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Trim empty rows and try again, expecting silence 555a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.trimEmpty(set, accountTypes); 5567f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 5577f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5587f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 5597f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey public void testTrimUpdateRemain() { 562a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 563a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = getAccountTypes(accountType); 564a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 5657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 5667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5677f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build "before" with two phone numbers 5687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentValues first = new ContentValues(); 5697f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Data._ID, TEST_ID); 5707f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 5717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(kindPhone.typeColumn, typeHome.rawValue); 5727f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Phone.NUMBER, TEST_PHONE); 5737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5747f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentValues second = new ContentValues(); 5757f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey second.put(Data._ID, TEST_ID); 5767f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey second.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 5777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey second.put(kindPhone.typeColumn, typeHome.rawValue); 5787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey second.put(Phone.NUMBER, TEST_PHONE); 5797f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5807f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID, first, second); 581ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDeltaList set = EntityDeltaList.fromSingle(state); 5827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build diff, expecting no changes 5847f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 5857f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5867f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 5877f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 5887f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Now update row by changing number to empty string, expecting single update 5897f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ValuesDelta child = state.getEntry(TEST_ID); 5907f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey child.put(Phone.NUMBER, ""); 5917f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 5927f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 5937f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 3, diff.size()); 5947f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 5957f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 5967f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 5977f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 5987f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 5997f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6007f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(1); 6017f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_UPDATE, oper.getType()); 6027f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 6037f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6047f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6057f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(2); 6067f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 6077f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6087f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6097f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6107f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Now run trim, which should turn that update into delete 611a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.trimEmpty(set, accountTypes); 6126f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey diff.clear(); 6136f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey state.buildDiff(diff); 6146f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Unexpected operations", 3, diff.size()); 6156f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 6166f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(0); 6176f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 6186f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 6206f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 6216f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(1); 6226f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); 6236f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 6246f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 6256f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey { 6266f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey final ContentProviderOperation oper = diff.get(2); 6276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 6286f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6296f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 6306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey } 6317f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6327f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey public void testTrimUpdateUpdate() { 633a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 634a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountTypeManager accountTypes = getAccountTypes(accountType); 635a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); 6367f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); 6377f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6387f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build "before" with two phone numbers 6397f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentValues first = new ContentValues(); 6407f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Data._ID, TEST_ID); 6417f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 6427f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(kindPhone.typeColumn, typeHome.rawValue); 6437f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey first.put(Phone.NUMBER, TEST_PHONE); 6447f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6457f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final EntityDelta state = getEntity(TEST_ID, first); 646ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann final EntityDeltaList set = EntityDeltaList.fromSingle(state); 6477f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6487f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Build diff, expecting no changes 6497f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 6507f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 6517f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 0, diff.size()); 6527f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6537f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Now update row by changing number to empty string, expecting single update 6547f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ValuesDelta child = state.getEntry(TEST_ID); 6557f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey child.put(Phone.NUMBER, ""); 6567f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 6577f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 6587f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 3, diff.size()); 6597f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 6617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 6627f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6637f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6647f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(1); 6667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_UPDATE, oper.getType()); 6677f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); 6687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6697f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6707f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(2); 6717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); 6727f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6747f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey 6757f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey // Now run trim, which should turn into deleting the whole contact 676a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.trimEmpty(set, accountTypes); 6777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey diff.clear(); 6787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey state.buildDiff(diff); 6797f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Unexpected operations", 1, diff.size()); 6807f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey { 6817f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey final ContentProviderOperation oper = diff.get(0); 6827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); 6837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); 6847f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 6857f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey } 68616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 68716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey public void testParseExtrasExistingName() { 688a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 68916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 69016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // Build "before" name 69116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final ContentValues first = new ContentValues(); 69216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(Data._ID, TEST_ID); 69316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); 69416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(StructuredName.GIVEN_NAME, TEST_NAME); 69516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 69616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // Parse extras, making sure we keep single name 69716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final EntityDelta state = getEntity(TEST_ID, first); 69816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final Bundle extras = new Bundle(); 69916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey extras.putString(Insert.NAME, TEST_NAME2); 700a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.parseExtras(mContext, accountType, state, extras); 70116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 70216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final int nameCount = state.getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true); 70316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey assertEquals("Unexpected names", 1, nameCount); 70416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey } 70516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 70616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey public void testParseExtrasIgnoreLimit() { 707a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 70816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 70916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // Build "before" IM 71016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final ContentValues first = new ContentValues(); 71116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(Data._ID, TEST_ID); 71216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE); 71316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey first.put(Im.DATA, TEST_IM); 71416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 71516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final EntityDelta state = getEntity(TEST_ID, first); 71616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final int beforeCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size(); 71716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 718a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov // We should ignore data that doesn't fit account type rules, since account type 71916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // only allows single Im 72016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final Bundle extras = new Bundle(); 72116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey extras.putInt(Insert.IM_PROTOCOL, Im.PROTOCOL_GOOGLE_TALK); 72216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey extras.putString(Insert.IM_HANDLE, TEST_IM); 723a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.parseExtras(mContext, accountType, state, extras); 72416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 72516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final int afterCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size(); 726a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov assertEquals("Broke account type rules", beforeCount, afterCount); 72716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey } 72816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 72916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey public void testParseExtrasIgnoreUnhandled() { 730a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 73116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 73216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 733a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov // We should silently ignore types unsupported by account type 73416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final Bundle extras = new Bundle(); 73516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey extras.putString(Insert.POSTAL, TEST_POSTAL); 736a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.parseExtras(mContext, accountType, state, extras); 73716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 738a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov assertNull("Broke accoun type rules", 739a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov state.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE)); 74016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey } 74116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 74216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey public void testParseExtrasJobTitle() { 743a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov final AccountType accountType = getAccountType(); 74416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final EntityDelta state = getEntity(TEST_ID); 74516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 74616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey // Make sure that we create partial Organizations 74716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final Bundle extras = new Bundle(); 74816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey extras.putString(Insert.JOB_TITLE, TEST_NAME); 749a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov EntityModifier.parseExtras(mContext, accountType, state, extras); 75016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey 75116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey final int count = state.getMimeEntries(Organization.CONTENT_ITEM_TYPE).size(); 75216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey assertEquals("Expected to create organization", 1, count); 75316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey } 75407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey} 755