1309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey/*
2309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * Copyright (C) 2009 The Android Open Source Project
3309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey *
4309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * you may not use this file except in compliance with the License.
6309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * You may obtain a copy of the License at
7309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey *
8309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey *
10309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
11309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * See the License for the specific language governing permissions and
14309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * limitations under the License.
15309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey */
16309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
17309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeypackage com.android.contacts;
18309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
198d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkeyimport com.android.contacts.model.EntityDelta;
208d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkeyimport com.android.contacts.model.EntityDelta.ValuesDelta;
2149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkeyimport com.google.android.collect.Lists;
22309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
23309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_INSERT;
24309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_UPDATE;
25309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_DELETE;
2614f61ab769f6e178a540a7579e446a010fb836daJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_ASSERT;
27309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
28309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.content.ContentProviderOperation;
29309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.content.ContentValues;
30309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.content.Entity;
31309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.content.ContentProviderOperation.Builder;
32309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.os.Parcel;
33309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.provider.ContactsContract.Data;
34309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.provider.ContactsContract.RawContacts;
35309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Phone;
36309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.test.AndroidTestCase;
37309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest;
38309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
39309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkeyimport java.util.ArrayList;
40309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
41309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey/**
428d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey * Tests for {@link EntityDelta} and {@link ValuesDelta}. These tests
43309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * focus on passing changes across {@link Parcel}, and verifying that they
44309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey * correctly build expected "diff" operations.
45309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey */
46309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey@LargeTest
478d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkeypublic class EntityDeltaTests extends AndroidTestCase {
4849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final String TAG = "EntityDeltaTests";
49309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
5049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final long TEST_CONTACT_ID = 12;
5149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final long TEST_PHONE_ID = 24;
52309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
5349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final String TEST_PHONE_NUMBER_1 = "218-555-1111";
5449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final String TEST_PHONE_NUMBER_2 = "218-555-2222";
55309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
5649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static final String TEST_ACCOUNT_NAME = "TEST";
57309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
588d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey    public EntityDeltaTests() {
59309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        super();
60309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
61309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
62309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    @Override
63309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void setUp() {
64309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        mContext = getContext();
65309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
66309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
6749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey    public static Entity getEntity(long contactId, long phoneId) {
68309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Build an existing contact read from database
69309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues contact = new ContentValues();
70309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        contact.put(RawContacts.VERSION, 43);
71309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        contact.put(RawContacts._ID, contactId);
72309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
73309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues phone = new ContentValues();
74309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Data._ID, phoneId);
75309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
76309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
77309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.TYPE, Phone.TYPE_HOME);
78309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
79309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = new Entity(contact);
80309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.addSubValue(Data.CONTENT_URI, phone);
81309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        return before;
82309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
83309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
84309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    /**
8549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * Test that {@link EntityDelta#mergeAfter(EntityDelta)} correctly passes
8649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * any changes through the {@link Parcel} object. This enforces that
8749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * {@link EntityDelta} should be identical when serialized against the same
8849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * "before" {@link Entity}.
89309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey     */
90309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testParcelChangesNone() {
91309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
928d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
938d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta dest = EntityDelta.fromBefore(before);
94309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
958d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        // Merge modified values and assert they match
9688d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
9788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        assertEquals("Unexpected change when merging", source, merged);
98309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
99309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
100309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testParcelChangesInsert() {
101309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
1028d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
1038d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta dest = EntityDelta.fromBefore(before);
104309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
105309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Add a new row and pass across parcel, should be same
106309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues phone = new ContentValues();
10788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
108309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
109309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.TYPE, Phone.TYPE_WORK);
1108d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        source.addEntry(ValuesDelta.fromAfter(phone));
111309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1128d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        // Merge modified values and assert they match
11388d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
11488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        assertEquals("Unexpected change when merging", source, merged);
115309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
116309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
117309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testParcelChangesUpdate() {
118309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Update existing row and pass across parcel, should be same
119309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
1208d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
1218d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta dest = EntityDelta.fromBefore(before);
122309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1238d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
1248d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        child.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
125309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1268d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        // Merge modified values and assert they match
12788d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
12888d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        assertEquals("Unexpected change when merging", source, merged);
129309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
130309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
131309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testParcelChangesDelete() {
132309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Delete a row and pass across parcel, should be same
133309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
1348d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
1358d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta dest = EntityDelta.fromBefore(before);
136309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1378d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
1388d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        child.markDeleted();
139309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1408d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        // Merge modified values and assert they match
14188d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
14288d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        assertEquals("Unexpected change when merging", source, merged);
143309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
144309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
145309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    /**
14649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * Test that {@link ValuesDelta#buildDiff(android.net.Uri)} is correctly
14749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * built for insert, update, and delete cases. Note this only tests behavior
14849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * for individual {@link Data} rows.
149309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey     */
150309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testValuesDiffNone() {
151309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues before = new ContentValues();
152309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Data._ID, TEST_PHONE_ID);
153309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
154309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1558d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromBefore(before);
156309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
157309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // None action shouldn't produce a builder
158309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Builder builder = values.buildDiff(Data.CONTENT_URI);
159309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertNull("None action produced a builder", builder);
160309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
161309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
162309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testValuesDiffInsert() {
163309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues after = new ContentValues();
164309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        after.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
165309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1668d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromAfter(after);
167309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
168309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Should produce an insert action
169309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Builder builder = values.buildDiff(Data.CONTENT_URI);
170309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final int type = builder.build().getType();
171309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertEquals("Didn't produce insert action", TYPE_INSERT, type);
172309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
173309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
174309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testValuesDiffUpdate() {
175309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues before = new ContentValues();
176309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Data._ID, TEST_PHONE_ID);
177309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
178309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1798d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromBefore(before);
180309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        values.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
181309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
182309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Should produce an update action
183309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Builder builder = values.buildDiff(Data.CONTENT_URI);
184309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final int type = builder.build().getType();
185309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertEquals("Didn't produce update action", TYPE_UPDATE, type);
186309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
187309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
188309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testValuesDiffDelete() {
189309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues before = new ContentValues();
190309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Data._ID, TEST_PHONE_ID);
191309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
192309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
1938d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromBefore(before);
194309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        values.markDeleted();
195309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
196309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Should produce a delete action
197309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Builder builder = values.buildDiff(Data.CONTENT_URI);
198309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final int type = builder.build().getType();
199309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertEquals("Didn't produce delete action", TYPE_DELETE, type);
200309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
201309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
202309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    /**
20349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey     * Test that {@link EntityDelta#buildDiff(ArrayList)} is correctly built for
204309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey     * insert, update, and delete cases. This only tests a subset of possible
205309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey     * {@link Data} row changes.
206309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey     */
207309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffNone() {
208309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
2098d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
210309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
211309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert that writing unchanged produces few operations
21249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
21349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
214309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
215309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertTrue("Created changes when none needed", (diff.size() == 0));
216309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
217309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
218309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffNoneInsert() {
219309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
2208d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
221309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
222309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Insert a new phone number
223309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues phone = new ContentValues();
22488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
225309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
226309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.TYPE, Phone.TYPE_WORK);
2278d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        source.addEntry(ValuesDelta.fromAfter(phone));
228309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
229309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert two operations: insert Data row and enforce version
23049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
23149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
23249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
233985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        assertEquals("Unexpected operations", 4, diff.size());
234309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
235309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
23614f61ab769f6e178a540a7579e446a010fb836daJeff Sharkey            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
237309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
238309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
239309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
240985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
241985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
242985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
243985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
244985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(2);
245e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
246e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
247309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
248985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
249985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(3);
250985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
251985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
252985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
253309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
254309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
255309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffUpdateInsert() {
256309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
2578d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
258309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
259309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Update parent contact values
260309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        source.getValues().put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
261309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
262309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Insert a new phone number
263309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues phone = new ContentValues();
26488d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
265309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
266309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.TYPE, Phone.TYPE_WORK);
2678d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        source.addEntry(ValuesDelta.fromAfter(phone));
268309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
269309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert three operations: update Contact, insert Data row, enforce version
27049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
27149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
27249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
273985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        assertEquals("Unexpected operations", 5, diff.size());
274309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
275309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
27614f61ab769f6e178a540a7579e446a010fb836daJeff Sharkey            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
277309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
278309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
279309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
280985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
281e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
282309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
283309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
284309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(2);
285985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
286985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
287985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
288985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
289985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(3);
290e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
291e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
292309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
293985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
294985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(4);
295985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
296985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
297985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
298309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
299309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
300309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffNoneUpdate() {
301309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
3028d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
303309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
304309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Update existing phone number
3058d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
306309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        child.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
307309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
30849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        // Assert that version is enforced
30949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
31049d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
31149d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
312985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        assertEquals("Unexpected operations", 4, diff.size());
313309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
314309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
31514f61ab769f6e178a540a7579e446a010fb836daJeff Sharkey            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
316309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
317309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
318309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
319985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
320985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
321985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
322985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
323985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(2);
324e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
325e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
326309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
327985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        {
328985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            final ContentProviderOperation oper = diff.get(3);
329985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
330985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
331985585b0557d277ee2ae3e8093cd577d0d1d59b1Jeff Sharkey        }
332309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
333309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
334309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffDelete() {
335309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
3368d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = EntityDelta.fromBefore(before);
337309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
338309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Delete entire entity
339309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        source.getValues().markDeleted();
340309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
341309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert two operations: delete Contact and enforce version
34249d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
34349d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
34449d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
345309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        assertEquals("Unexpected operations", 2, diff.size());
346309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
347309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
34814f61ab769f6e178a540a7579e446a010fb836daJeff Sharkey            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
349309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
350309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
351309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
352e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
353e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
354309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
355309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
356309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
357309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffInsert() {
358309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Insert a RawContact
359309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues after = new ContentValues();
360309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        after.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
361309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
362309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
3638d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromAfter(after);
3648d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = new EntityDelta(values);
365309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
366309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert two operations: delete Contact and enforce version
36749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
36849d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
36949d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
3703aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov        assertEquals("Unexpected operations", 2, diff.size());
371309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
372309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
373309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
374309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
375309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
376309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
377309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
378309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    public void testEntityDiffInsertInsert() {
379309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Insert a RawContact
380309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues after = new ContentValues();
381309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        after.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
382309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
383309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
3848d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final ValuesDelta values = ValuesDelta.fromAfter(after);
3858d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        final EntityDelta source = new EntityDelta(values);
386309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
387309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Insert a new phone number
388309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        final ContentValues phone = new ContentValues();
38988d00c2450a0a16bf1dd35e9f3c9ba843a97ec62Jeff Sharkey        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
390309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
391309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        phone.put(Phone.TYPE, Phone.TYPE_WORK);
3928d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        source.addEntry(ValuesDelta.fromAfter(phone));
393309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
394309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        // Assert two operations: delete Contact and enforce version
39549d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
39649d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildAssert(diff);
39749d17b3e7692ae9442c342db236fa93d4a837c28Jeff Sharkey        source.buildDiff(diff);
3983aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov        assertEquals("Unexpected operations", 3, diff.size());
399309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
400309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
401309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
402309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
403309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
404309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        {
405309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
406309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
407309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
408309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey
409309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey        }
410309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey    }
411309e89f36aeca6d6a81e13ea95b7e4af6e491073Jeff Sharkey}
412