149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey/* 249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * Copyright (C) 2009 The Android Open Source Project 349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * 449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * you may not use this file except in compliance with the License. 649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * You may obtain a copy of the License at 749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * 849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * 1049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 1149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 1249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * See the License for the specific language governing permissions and 1449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * limitations under the License. 1549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey */ 1649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 1749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeypackage com.android.contacts; 1849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 1988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_ASSERT; 2088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_DELETE; 2188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_INSERT; 2288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_UPDATE; 2388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 2449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport android.content.ContentProviderOperation; 2549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport android.content.ContentValues; 26851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport android.content.Context; 2788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport android.net.Uri; 2888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport android.provider.BaseColumns; 2949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport android.provider.ContactsContract.AggregationExceptions; 307173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email; 3188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Phone; 32e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport android.provider.ContactsContract.Data; 33e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport android.provider.ContactsContract.RawContacts; 3449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport android.test.AndroidTestCase; 3549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest; 3649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 37851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.RawContactModifierTests.MockContactsSource; 38851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContact; 39851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta; 40851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta.ValuesDelta; 41851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDeltaList; 42851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactModifier; 43851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.account.AccountType; 44e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.collect.Lists; 45e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 467173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkeyimport java.lang.reflect.Field; 4749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport java.util.ArrayList; 4849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 4949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey/** 50851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * Tests for {@link RawContactDeltaList} which focus on "diff" operations that should 5149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * create {@link AggregationExceptions} in certain cases. 5249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey */ 5349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey@LargeTest 54851222a96b5d68602fb361ea3527101e893f67e3Maurice Chupublic class RawContactDeltaListTests extends AndroidTestCase { 55851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public static final String TAG = RawContactDeltaListTests.class.getSimpleName(); 5649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 5749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey private static final long CONTACT_FIRST = 1; 5849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey private static final long CONTACT_SECOND = 2; 5949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 6088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long CONTACT_BOB = 10; 6188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long CONTACT_MARY = 11; 6288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 6388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long PHONE_RED = 20; 6488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long PHONE_GREEN = 21; 6588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long PHONE_BLUE = 22; 6688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 677173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey public static final long EMAIL_YELLOW = 25; 687173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 6988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long VER_FIRST = 100; 7088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public static final long VER_SECOND = 200; 7188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 727173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey public static final String TEST_PHONE = "555-1212"; 737173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey public static final String TEST_ACCOUNT = "org.example.test"; 747173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 75851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public RawContactDeltaListTests() { 7649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey super(); 7749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 7849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 7949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey @Override 8049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void setUp() { 8149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey mContext = getContext(); 8249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 8349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 847173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey /** 854597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov * Build a {@link AccountType} that has various odd constraints for 867173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey * testing purposes. 877173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey */ 88b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov protected AccountType getAccountType() { 89b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov return new MockContactsSource(); 907173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 917173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 92e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentValues getValues(ContentProviderOperation operation) 937173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey throws NoSuchFieldException, IllegalAccessException { 947173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final Field field = ContentProviderOperation.class.getDeclaredField("mValues"); 957173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey field.setAccessible(true); 967173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return (ContentValues) field.get(operation); 977173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 987173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 99851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static RawContactDelta getUpdate(Context context, long rawContactId) { 100851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContact before = RawContactDeltaTests.getRawContact(context, rawContactId, 101851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactDeltaTests.TEST_PHONE_ID); 102851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu return RawContactDelta.fromBefore(before); 10349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 10449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 105851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static RawContactDelta getInsert() { 10649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ContentValues after = new ContentValues(); 107851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu after.put(RawContacts.ACCOUNT_NAME, RawContactDeltaTests.TEST_ACCOUNT_NAME); 10849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey after.put(RawContacts.SEND_TO_VOICEMAIL, 1); 10949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 11049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ValuesDelta values = ValuesDelta.fromAfter(after); 111851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu return new RawContactDelta(values); 11249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 11349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 114851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static RawContactDeltaList buildSet(RawContactDelta... deltas) { 115851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = RawContactDeltaList.fromSingle(deltas[0]); 11649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey for (int i = 1; i < deltas.length; i++) { 11749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey set.add(deltas[i]); 11849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 11949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey return set; 12049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 12149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 122851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static RawContactDelta buildBeforeEntity(Context context, long rawContactId, long version, 12388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey ContentValues... entries) { 12488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Build an existing contact read from database 12588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentValues contact = new ContentValues(); 12688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey contact.put(RawContacts.VERSION, version); 12788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey contact.put(RawContacts._ID, rawContactId); 128851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContact before = new RawContact(context, contact); 12988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey for (ContentValues entry : entries) { 130851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu before.addDataItemValues(entry); 13188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 132851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu return RawContactDelta.fromBefore(before); 13388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 13488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 135851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static RawContactDelta buildAfterEntity(ContentValues... entries) { 13688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Build an existing contact read from database 13788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentValues contact = new ContentValues(); 1387173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT); 139851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta after = new RawContactDelta(ValuesDelta.fromAfter(contact)); 14088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey for (ContentValues entry : entries) { 14188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey after.addEntry(ValuesDelta.fromAfter(entry)); 14288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 14388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return after; 14488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 14588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 146e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentValues buildPhone(long phoneId) { 14788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return buildPhone(phoneId, Long.toString(phoneId)); 14888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 14988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 150e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentValues buildPhone(long phoneId, String value) { 15188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentValues values = new ContentValues(); 15288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey values.put(Data._ID, phoneId); 15388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); 15488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey values.put(Phone.NUMBER, value); 15588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey values.put(Phone.TYPE, Phone.TYPE_HOME); 15688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return values; 15788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 15888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 159e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentValues buildEmail(long emailId) { 1607173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues values = new ContentValues(); 1617173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(Data._ID, emailId); 1627173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE); 1637173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(Email.DATA, Long.toString(emailId)); 1647173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(Email.TYPE, Email.TYPE_HOME); 1657173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return values; 1667173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 1677173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 168851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static void insertPhone(RawContactDeltaList set, long rawContactId, ContentValues values) { 169851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta match = set.getByRawContactId(rawContactId); 17088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey match.addEntry(ValuesDelta.fromAfter(values)); 17188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 17288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 173851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static ValuesDelta getPhone(RawContactDeltaList set, long rawContactId, long dataId) { 174851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta match = set.getByRawContactId(rawContactId); 17588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return match.getEntry(dataId); 17688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 17788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 178851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static void assertDiffPattern(RawContactDelta delta, ContentProviderOperation... pattern) { 179e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); 180e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey delta.buildAssert(diff); 181e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey delta.buildDiff(diff); 182e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey assertDiffPattern(diff, pattern); 183e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey } 184e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey 185851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static void assertDiffPattern(RawContactDeltaList set, ContentProviderOperation... pattern) { 186e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey assertDiffPattern(set.buildDiff(), pattern); 187e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey } 18888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 189e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static void assertDiffPattern(ArrayList<ContentProviderOperation> diff, 190e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey ContentProviderOperation... pattern) { 19188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals("Unexpected operations", pattern.length, diff.size()); 19288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey for (int i = 0; i < pattern.length; i++) { 19388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentProviderOperation expected = pattern[i]; 19488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentProviderOperation found = diff.get(i); 19588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 1967173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey assertEquals("Unexpected uri", expected.getUri(), found.getUri()); 1977173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 19888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final String expectedType = getStringForType(expected.getType()); 19988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final String foundType = getStringForType(found.getType()); 20088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals("Unexpected type", expectedType, foundType); 2017173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 2027173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey if (expected.getType() == TYPE_DELETE) continue; 2037173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 2047173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey try { 2057173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues expectedValues = getValues(expected); 2067173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues foundValues = getValues(found); 2077173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 2087173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey expectedValues.remove(BaseColumns._ID); 2097173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey foundValues.remove(BaseColumns._ID); 2107173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 2117173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey assertEquals("Unexpected values", expectedValues, foundValues); 2127173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } catch (NoSuchFieldException e) { 2137173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey fail(e.toString()); 2147173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } catch (IllegalAccessException e) { 2157173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey fail(e.toString()); 2167173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 21788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 21888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 21988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 220e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static String getStringForType(int type) { 22188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey switch (type) { 22288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_ASSERT: return "TYPE_ASSERT"; 22388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_INSERT: return "TYPE_INSERT"; 22488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_UPDATE: return "TYPE_UPDATE"; 22588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_DELETE: return "TYPE_DELETE"; 22688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey default: return Integer.toString(type); 22788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 22888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 22988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 230e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildAssertVersion(long version) { 2317173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues values = new ContentValues(); 2327173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(RawContacts.VERSION, version); 2337173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildOper(RawContacts.CONTENT_URI, TYPE_ASSERT, values); 2347173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2357173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 236e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildAggregationModeUpdate(int mode) { 23788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ContentValues values = new ContentValues(); 2387173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(RawContacts.AGGREGATION_MODE, mode); 2397173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildOper(RawContacts.CONTENT_URI, TYPE_UPDATE, values); 2407173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2417173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 242e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildUpdateAggregationSuspended() { 2437173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_SUSPENDED); 2447173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2457173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 246e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildUpdateAggregationDefault() { 2477173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT); 2487173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2497173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 250e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildUpdateAggregationKeepTogether(long rawContactId) { 2517173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues values = new ContentValues(); 2527173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId); 2537173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey values.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER); 2547173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildOper(AggregationExceptions.CONTENT_URI, TYPE_UPDATE, values); 2557173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2567173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 257e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentValues buildDataInsert(ValuesDelta values, long rawContactId) { 2587173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues insertValues = values.getCompleteValues(); 2597173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey insertValues.put(Data.RAW_CONTACT_ID, rawContactId); 2607173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return insertValues; 2617173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2627173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 263e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildDelete(Uri uri) { 2647173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildOper(uri, TYPE_DELETE, (ContentValues)null); 2657173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2667173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 267e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildOper(Uri uri, int type, ValuesDelta values) { 2687173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey return buildOper(uri, type, values.getCompleteValues()); 2697173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 2707173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 271e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static ContentProviderOperation buildOper(Uri uri, int type, ContentValues values) { 27288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey switch (type) { 27388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_ASSERT: 27488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return ContentProviderOperation.newAssertQuery(uri).withValues(values).build(); 27588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_INSERT: 27688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return ContentProviderOperation.newInsert(uri).withValues(values).build(); 27788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_UPDATE: 27888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return ContentProviderOperation.newUpdate(uri).withValues(values).build(); 27988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey case TYPE_DELETE: 28088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return ContentProviderOperation.newDelete(uri).build(); 28188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 28288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return null; 28388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 28488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 285851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu static Long getVersion(RawContactDeltaList set, Long rawContactId) { 28688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey return set.getByRawContactId(rawContactId).getValues().getAsLong(RawContacts.VERSION); 28788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 28888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 28949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey /** 29049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * Count number of {@link AggregationExceptions} updates contained in the 29149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey * given list of {@link ContentProviderOperation}. 29249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey */ 293e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey static int countExceptionUpdates(ArrayList<ContentProviderOperation> diff) { 29449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey int updateCount = 0; 29549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey for (ContentProviderOperation oper : diff) { 29649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey if (AggregationExceptions.CONTENT_URI.equals(oper.getUri()) 29749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey && oper.getType() == ContentProviderOperation.TYPE_UPDATE) { 29849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey updateCount++; 29949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 30049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 30149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey return updateCount; 30249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 30349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 30449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void testInsert() { 305851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insert = getInsert(); 306851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = buildSet(insert); 30749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 30849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey // Inserting single shouldn't create rules 30949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ArrayList<ContentProviderOperation> diff = set.buildDiff(); 31049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final int exceptionCount = countExceptionUpdates(diff); 31149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey assertEquals("Unexpected exception updates", 0, exceptionCount); 31249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 31349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 31449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void testUpdateUpdate() { 315851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta updateFirst = getUpdate(mContext, CONTACT_FIRST); 316851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta updateSecond = getUpdate(mContext, CONTACT_SECOND); 317851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = buildSet(updateFirst, updateSecond); 31849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 31949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey // Updating two existing shouldn't create rules 32049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ArrayList<ContentProviderOperation> diff = set.buildDiff(); 32149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final int exceptionCount = countExceptionUpdates(diff); 32249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey assertEquals("Unexpected exception updates", 0, exceptionCount); 32349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 32449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 32549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void testUpdateInsert() { 326851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST); 327851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insert = getInsert(); 328851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = buildSet(update, insert); 32949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 33049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey // New insert should only create one rule 33149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ArrayList<ContentProviderOperation> diff = set.buildDiff(); 33249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final int exceptionCount = countExceptionUpdates(diff); 33349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey assertEquals("Unexpected exception updates", 1, exceptionCount); 33449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 33549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 33649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void testInsertUpdateInsert() { 337851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insertFirst = getInsert(); 338851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST); 339851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insertSecond = getInsert(); 340851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = buildSet(insertFirst, update, insertSecond); 34149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 34249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey // Two inserts should create two rules to bind against single existing 34349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ArrayList<ContentProviderOperation> diff = set.buildDiff(); 34449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final int exceptionCount = countExceptionUpdates(diff); 34549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey assertEquals("Unexpected exception updates", 2, exceptionCount); 34649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 34749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 34849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey public void testInsertInsertInsert() { 349851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insertFirst = getInsert(); 350851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insertSecond = getInsert(); 351851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta insertThird = getInsert(); 352851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList set = buildSet(insertFirst, insertSecond, insertThird); 35349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey 35449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey // Three new inserts should create only two binding rules 35549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final ArrayList<ContentProviderOperation> diff = set.buildDiff(); 35649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey final int exceptionCount = countExceptionUpdates(diff); 35749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey assertEquals("Unexpected exception updates", 2, exceptionCount); 35849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey } 35988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 36088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeDataRemoteInsert() { 361851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 362851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 363851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 364851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN))); 36588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 36688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in second version, verify they match 367851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 36888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals("Unexpected change when merging", second, merged); 36988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 37088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 37188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeDataLocalUpdateRemoteInsert() { 372851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 373851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 374851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 375851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN))); 37688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 37788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Change the local number to trigger update 3787173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED); 3797173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey phone.put(Phone.NUMBER, TEST_PHONE); 3807173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 38188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 3827173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 3837173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 3847173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()), 3857173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 38688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 38788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify diff matches 388851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 38988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 3907173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 3917173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 3927173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()), 3937173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 39488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 39588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 39688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeDataLocalUpdateRemoteDelete() { 397851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 398851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 399851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 400851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_GREEN))); 40188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 40288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Change the local number to trigger update 4037173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED); 4047173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey phone.put(Phone.NUMBER, TEST_PHONE); 4057173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 40688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 4077173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 4087173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4097173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()), 4107173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 41188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 41288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify that our update changed to 41388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // insert, since RED was deleted on remote side 414851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 41588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 4167173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 4177173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4187173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(phone, CONTACT_BOB)), 4197173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 42088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 42188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 42288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeDataLocalDeleteRemoteUpdate() { 423851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 424851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 425851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 426851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED, TEST_PHONE))); 42788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 42888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Delete phone locally 4297173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED); 4307173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey phone.markDeleted(); 4317173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 43288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 4337173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 4347173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4357173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildDelete(Data.CONTENT_URI), 4367173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 43788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 43888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify that our delete remains 439851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 44088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 4417173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 4427173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4437173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildDelete(Data.CONTENT_URI), 4447173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 44588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 44688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 44788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeDataLocalInsertRemoteInsert() { 448851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 449851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 450851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 451851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN))); 45288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 45388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Insert new phone locally 45488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey final ValuesDelta bluePhone = ValuesDelta.fromAfter(buildPhone(PHONE_BLUE)); 45588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey first.getByRawContactId(CONTACT_BOB).addEntry(bluePhone); 45688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 4577173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 4587173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4597173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)), 4607173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 46188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 46288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify that our insert remains 463851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 46488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 4657173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 4667173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 4677173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)), 4687173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 46988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 47088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 47188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeRawContactLocalInsertRemoteInsert() { 472851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 473851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 474851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 475851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED)), buildBeforeEntity(mContext, CONTACT_MARY, 476851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED))); 47788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 47888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Add new contact locally, should remain insert 4797173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues joePhoneInsert = buildPhone(PHONE_BLUE); 480851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta joeContact = buildAfterEntity(joePhoneInsert); 4817173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues joeContactInsert = joeContact.getValues().getCompleteValues(); 482c7c1905d60786936527e4baa0c131d435d8bbdb5Dmitri Plotnikov joeContactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED); 48388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey first.add(joeContact); 48488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 4857173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 4867173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert), 4877173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert), 4883aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT), 4897173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationKeepTogether(CONTACT_BOB)); 49088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 49188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify that our insert remains 492851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 49388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 4947173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 4957173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 4967173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert), 4977173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert), 4983aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT), 4997173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationKeepTogether(CONTACT_BOB)); 50088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 50188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 50288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeRawContactLocalDeleteRemoteDelete() { 503851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet( 504851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)), 505851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED))); 506851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet( 507851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED))); 50888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 50988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Remove contact locally 51088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey first.getByRawContactId(CONTACT_MARY).markDeleted(); 51188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 5127173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 5137173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 5147173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildDelete(RawContacts.CONTENT_URI)); 51588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 51688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge in the second version, verify that our delete isn't needed 517851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 51888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged); 51988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 52088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 52188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeRawContactLocalUpdateRemoteDelete() { 522851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet( 523851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)), 524851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED))); 525851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet( 526851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED))); 52788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 52888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Perform local update 5297173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ValuesDelta phone = getPhone(first, CONTACT_MARY, PHONE_RED); 5307173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey phone.put(Phone.NUMBER, TEST_PHONE); 53188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(first, 5327173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 5337173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 5347173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 5357173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()), 5367173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 5377173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5387173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues phoneInsert = phone.getCompleteValues(); 5397173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ContentValues contactInsert = first.getByRawContactId(CONTACT_MARY).getValues() 5407173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey .getCompleteValues(); 541c7c1905d60786936527e4baa0c131d435d8bbdb5Dmitri Plotnikov contactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED); 54288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 54388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey // Merge and verify that update turned into insert 544851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 54588d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertDiffPattern(merged, 5467173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_SECOND), 5477173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, contactInsert), 5487173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, phoneInsert), 5493aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT), 5507173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationKeepTogether(CONTACT_BOB)); 55188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 55288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 55388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey public void testMergeUsesNewVersion() { 554851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 555851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildPhone(PHONE_RED))); 556851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 557851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildPhone(PHONE_RED))); 55888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 55988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals((Long)VER_FIRST, getVersion(first, CONTACT_BOB)); 56088d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals((Long)VER_SECOND, getVersion(second, CONTACT_BOB)); 56188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey 562851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 56388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey assertEquals((Long)VER_SECOND, getVersion(merged, CONTACT_BOB)); 56488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey } 5657173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5667173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey public void testMergeAfterEnsureAndTrim() { 567851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 568851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_FIRST, buildEmail(EMAIL_YELLOW))); 569851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB, 570851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu VER_SECOND, buildEmail(EMAIL_YELLOW))); 5717173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5727173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey // Ensure we have at least one phone 573b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov final AccountType source = getAccountType(); 574851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDelta bobContact = first.getByRawContactId(CONTACT_BOB); 575851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.ensureKindExists(bobContact, source, Phone.CONTENT_ITEM_TYPE); 5767173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey final ValuesDelta bobPhone = bobContact.getSuperPrimaryEntry(Phone.CONTENT_ITEM_TYPE, true); 5777173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5787173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey // Make sure the update would insert a row 5797173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey assertDiffPattern(first, 5807173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildAssertVersion(VER_FIRST), 5817173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationSuspended(), 5827173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bobPhone, CONTACT_BOB)), 5837173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey buildUpdateAggregationDefault()); 5847173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5857173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey // Trim values and ensure that we don't insert things 586851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu RawContactModifier.trimEmpty(bobContact, source); 5877173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey assertDiffPattern(first); 5887173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey 5897173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey // Now re-parent the change, which should remain no-op 590851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first); 5917173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey assertDiffPattern(merged); 5927173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey } 59349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey} 594