EntityModifierTests.java revision fd33cc3ab956222dffa6b669a13a614747a5cdff
107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey/*
207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Copyright (C) 2009 The Android Open Source Project
307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey *
407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * you may not use this file except in compliance with the License.
607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * You may obtain a copy of the License at
707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey *
807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey *
1007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
1107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * See the License for the specific language governing permissions and
1407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * limitations under the License.
1507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */
1607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
1707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeypackage com.android.contacts;
1807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_DELETE;
206f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_INSERT;
216f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport static android.content.ContentProviderOperation.TYPE_UPDATE;
226f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
23d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport com.google.android.collect.Lists;
24d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
254597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType;
264597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.EditType;
271173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.AccountTypeManager;
28405671a7b42d97ebf7ae7c0eeb4721f881139673Daisuke Miyakawaimport com.android.contacts.model.DataKind;
291173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityDelta;
306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport com.android.contacts.model.EntityDelta.ValuesDelta;
311173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityDeltaList;
321173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.model.EntityModifier;
33d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport com.android.contacts.model.ExchangeAccountType;
34d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport com.android.contacts.model.GoogleAccountType;
35d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport com.android.contacts.tests.mocks.ContactsMockContext;
361173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport com.android.contacts.tests.mocks.MockAccountTypeManager;
37d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport com.android.contacts.tests.mocks.MockContentProvider;
3807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
396f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkeyimport android.content.ContentProviderOperation;
4007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.content.ContentValues;
41ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkeyimport android.content.Context;
4207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.content.Entity;
43d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.net.Uri;
4416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.os.Bundle;
45d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.provider.ContactsContract;
467173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email;
47d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event;
4816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Im;
4916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Organization;
5007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Phone;
5116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
5216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
531173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.Data;
541173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.Intents.Insert;
551173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
5607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.test.AndroidTestCase;
5707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport android.test.suitebuilder.annotation.LargeTest;
5807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
5907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport java.util.ArrayList;
6007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeyimport java.util.List;
6107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
6207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey/**
634597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov * Tests for {@link EntityModifier} to verify that {@link AccountType}
6407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey * constraints are being enforced correctly.
6507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey */
6607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey@LargeTest
6707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkeypublic class EntityModifierTests extends AndroidTestCase {
6807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    public static final String TAG = "EntityModifierTests";
6907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
70e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey    public static final long VER_FIRST = 100;
71e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
726f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    private static final long TEST_ID = 4;
736f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    private static final String TEST_PHONE = "218-555-1212";
7416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    private static final String TEST_NAME = "Adam Young";
7516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    private static final String TEST_NAME2 = "Breanne Duren";
7616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    private static final String TEST_IM = "example@example.com";
7716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    private static final String TEST_POSTAL = "1600 Amphitheatre Parkway";
786f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
797f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    private static final String TEST_ACCOUNT_NAME = "unittest@example.com";
807f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    private static final String TEST_ACCOUNT_TYPE = "com.example.unittest";
817f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
8207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    @Override
8307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    public void setUp() {
8407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        mContext = getContext();
8507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
8607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
874597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov    public static class MockContactsSource extends AccountType {
88b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov
89b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        MockContactsSource() {
90ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey            this.accountType = TEST_ACCOUNT_TYPE;
9107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
926c9b4b97752e415528279464b28560d389256783Daniel Lehmann            final DataKind nameKind = new DataKind(StructuredName.CONTENT_ITEM_TYPE,
93a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan                    R.string.nameLabelsGroup, -1, -1, true, -1, -1, -1);
946c9b4b97752e415528279464b28560d389256783Daniel Lehmann            nameKind.typeOverallMax = 1;
956c9b4b97752e415528279464b28560d389256783Daniel Lehmann            addKind(nameKind);
966c9b4b97752e415528279464b28560d389256783Daniel Lehmann
9707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey            // Phone allows maximum 2 home, 1 work, and unlimited other, with
9807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey            // constraint of 5 numbers maximum.
992591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            final DataKind phoneKind = new DataKind(
100a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan                    Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1, -1);
10107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
1026c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeOverallMax = 5;
1036c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeColumn = Phone.TYPE;
1046c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeList = Lists.newArrayList();
1056c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeList.add(new EditType(Phone.TYPE_HOME, -1).setSpecificMax(2));
1066c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeList.add(new EditType(Phone.TYPE_WORK, -1).setSpecificMax(1));
1076c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1).setSecondary(true));
1086c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.typeList.add(new EditType(Phone.TYPE_OTHER, -1));
10907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
1106c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.fieldList = Lists.newArrayList();
1116c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.fieldList.add(new EditField(Phone.NUMBER, -1, -1));
1126c9b4b97752e415528279464b28560d389256783Daniel Lehmann            phoneKind.fieldList.add(new EditField(Phone.LABEL, -1, -1));
1136f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
1146c9b4b97752e415528279464b28560d389256783Daniel Lehmann            addKind(phoneKind);
1157173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey
1167173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey            // Email is unlimited
1172591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            final DataKind emailKind = new DataKind(
118a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan                    Email.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1, -1);
1196c9b4b97752e415528279464b28560d389256783Daniel Lehmann            emailKind.typeOverallMax = -1;
1206c9b4b97752e415528279464b28560d389256783Daniel Lehmann            emailKind.fieldList = Lists.newArrayList();
1216c9b4b97752e415528279464b28560d389256783Daniel Lehmann            emailKind.fieldList.add(new EditField(Email.DATA, -1, -1));
1226c9b4b97752e415528279464b28560d389256783Daniel Lehmann            addKind(emailKind);
12316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
12416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey            // IM is only one
125a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan            final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10,
126a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan                    true, -1, -1, -1);
1276c9b4b97752e415528279464b28560d389256783Daniel Lehmann            imKind.typeOverallMax = 1;
1286c9b4b97752e415528279464b28560d389256783Daniel Lehmann            imKind.fieldList = Lists.newArrayList();
1296c9b4b97752e415528279464b28560d389256783Daniel Lehmann            imKind.fieldList.add(new EditField(Im.DATA, -1, -1));
1306c9b4b97752e415528279464b28560d389256783Daniel Lehmann            addKind(imKind);
1317173705177c421e0b2a3bc4579b2f8910a38a668Jeff Sharkey
13216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey            // Organization is only one
1332591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            final DataKind orgKind = new DataKind(
134a2d4a9652fb4db9ee222abc7a637366c6c50427cKatherine Kuan                    Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1, -1);
1356c9b4b97752e415528279464b28560d389256783Daniel Lehmann            orgKind.typeOverallMax = 1;
1366c9b4b97752e415528279464b28560d389256783Daniel Lehmann            orgKind.fieldList = Lists.newArrayList();
1376c9b4b97752e415528279464b28560d389256783Daniel Lehmann            orgKind.fieldList.add(new EditField(Organization.COMPANY, -1, -1));
1386c9b4b97752e415528279464b28560d389256783Daniel Lehmann            orgKind.fieldList.add(new EditField(Organization.TITLE, -1, -1));
1396c9b4b97752e415528279464b28560d389256783Daniel Lehmann            addKind(orgKind);
14007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        }
1415297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton
1425297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        @Override
1435297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        public int getHeaderColor(Context context) {
1445297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton            return 0;
1455297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        }
1465297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton
1475297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        @Override
1485297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        public int getSideBarColor(Context context) {
1495297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton            return 0xffffff;
1505297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamilton        }
151fd33cc3ab956222dffa6b669a13a614747a5cdffKatherine Kuan
152fd33cc3ab956222dffa6b669a13a614747a5cdffKatherine Kuan        @Override
153fd33cc3ab956222dffa6b669a13a614747a5cdffKatherine Kuan        public boolean isGroupMembershipEditable() {
154fd33cc3ab956222dffa6b669a13a614747a5cdffKatherine Kuan            return false;
155fd33cc3ab956222dffa6b669a13a614747a5cdffKatherine Kuan        }
156ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey    }
15707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
158ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey    /**
1594597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikov     * Build a {@link AccountType} that has various odd constraints for
160ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey     * testing purposes.
161ab066931efd4b6408b5f57026b421eb4a7934a39Jeff Sharkey     */
162b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov    protected AccountType getAccountType() {
163b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        return new MockContactsSource();
16407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
16507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
16607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
167a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov     * Build {@link AccountTypeManager} instance.
1687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey     */
169a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov    protected AccountTypeManager getAccountTypes(AccountType... types) {
1701173ae29217fc83f254404f8a5fa10419ee83c93Dmitri Plotnikov        return new MockAccountTypeManager(types, null);
1717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    }
1727f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
1737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    /**
17407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * Build an {@link Entity} with the requested set of phone numbers.
17507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
1767f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    protected EntityDelta getEntity(Long existingId, ContentValues... entries) {
17707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final ContentValues contact = new ContentValues();
1787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        if (existingId != null) {
1797f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            contact.put(RawContacts._ID, existingId);
1807f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
1817f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        contact.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
1827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE);
1837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
18407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final Entity before = new Entity(contact);
1856f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        for (ContentValues values : entries) {
1866f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            before.addSubValue(Data.CONTENT_URI, values);
1876f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
1888d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey        return EntityDelta.fromBefore(before);
18907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
19007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
19107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
19207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * Assert this {@link List} contains the given {@link Object}.
19307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
19407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    protected void assertContains(List<?> list, Object object) {
19507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertTrue("Missing expected value", list.contains(object));
19607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
19707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
19807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
19907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * Assert this {@link List} does not contain the given {@link Object}.
20007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
20107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    protected void assertNotContains(List<?> list, Object object) {
20207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertFalse("Contained unexpected value", list.contains(object));
20307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
20407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
20507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
20607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * Insert various rows to test
2078d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey     * {@link EntityModifier#getValidTypes(EntityDelta, DataKind, EditType)}
20807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
20907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    public void testValidTypes() {
21007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Build a source and pull specific types
211b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
21207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
21307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
21407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
21507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
21607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
21707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        List<EditType> validTypes;
21807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
21907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add first home, first work
2207f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
22107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
22207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeWork);
22307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
22407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Expecting home, other
22507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
22607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertContains(validTypes, typeHome);
22707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeWork);
22807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertContains(validTypes, typeOther);
22907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
23007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add second home
23107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
23207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
23307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Expecting other
23407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
23507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeHome);
23607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeWork);
23707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertContains(validTypes, typeOther);
23807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
23907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add third and fourth home (invalid, but possible)
24007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
24107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
24207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
24307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Expecting none
24407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
24507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeHome);
24607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeWork);
24707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertNotContains(validTypes, typeOther);
24807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
24907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
25007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
2518d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey     * Test {@link EntityModifier#canInsert(EntityDelta, DataKind)} by
25207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * inserting various rows.
25307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
25407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    public void testCanInsert() {
25507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Build a source and pull specific types
256b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
25707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
25807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
25907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
26007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
26107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
26207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add first home, first work
2637f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
26407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
26507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeWork);
26607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
26707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
26807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add two other, which puts us just under "5" overall limit
26907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeOther);
27007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeOther);
27107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
27207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
27307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add second home, which should push to snug limit
27407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
27507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertFalse("Able to insert", EntityModifier.canInsert(state, kindPhone));
27607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
27707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
27807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    /**
279d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey     * Test
280d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey     * {@link EntityModifier#getBestValidType(EntityDelta, DataKind, boolean, int)}
28107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     * by asserting expected best options in various states.
28207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey     */
28307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    public void testBestValidType() {
28407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Build a source and pull specific types
285b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
28607c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
28707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
28807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
28907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeFaxWork = EntityModifier.getType(kindPhone, Phone.TYPE_FAX_WORK);
29007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
29107c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
29207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EditType suggested;
29307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
29407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Default suggestion should be home
2957f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
296d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey        suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
29707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertEquals("Unexpected suggestion", typeHome, suggested);
29807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
29907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add first home, should now suggest work
30007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeHome);
301d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey        suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
30207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertEquals("Unexpected suggestion", typeWork, suggested);
30307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
30407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add work fax, should still suggest work
30507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeFaxWork);
306d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey        suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
30707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertEquals("Unexpected suggestion", typeWork, suggested);
30807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
30907c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add other, should still suggest work
31007c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeOther);
311d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey        suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
31207c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertEquals("Unexpected suggestion", typeWork, suggested);
31307c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey
31407c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        // Add work, now should suggest other
31507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        EntityModifier.insertChild(state, kindPhone, typeWork);
316d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey        suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
31707c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey        assertEquals("Unexpected suggestion", typeOther, suggested);
31807c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey    }
3196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3206f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void testIsEmptyEmpty() {
321b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
3226f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
3236f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3246f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Test entirely empty row
3256f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ContentValues after = new ContentValues();
3266f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ValuesDelta values = ValuesDelta.fromAfter(after);
3276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3286f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone));
3296f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
3306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3316f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void testIsEmptyDirectFields() {
332b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
3336f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
3346f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
3356f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3366f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Test row that has type values, but core fields are empty
3377f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
3386f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
3396f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3406f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone));
3416f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3426f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Insert some data to trigger non-empty state
3436f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        values.put(Phone.NUMBER, TEST_PHONE);
3446f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3456f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertFalse("Expected non-empty", EntityModifier.isEmpty(values, kindPhone));
3466f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
3476f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3486f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void testTrimEmptySingle() {
349b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
3506f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
3516f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
3526f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3536f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Test row that has type values, but core fields are empty
3547f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
3556c9b4b97752e415528279464b28560d389256783Daniel Lehmann        EntityModifier.insertChild(state, kindPhone, typeHome);
3566f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3576f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Build diff, expecting insert for data row and update enforcement
3586f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
3596f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
3606f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 3, diff.size());
3616f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
3626f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(0);
3636f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
3646f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
3656f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
3666f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
3676f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(1);
3686f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
3696f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
3706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
3716f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
3726f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(2);
3736f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
3746f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
3756f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
3766f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
3777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Trim empty rows and try again, expecting delete of overall contact
3787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        EntityModifier.trimEmpty(state, source);
3796f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        diff.clear();
3806f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
3817f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 1, diff.size());
3827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
3837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
3847f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
3857f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
3867f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
3876f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
3886f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
389e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey    public void testTrimEmptySpaces() {
390b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
391e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
392e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
393e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
394e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Test row that has type values, but values are spaces
395ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST);
396e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
397e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        values.put(Phone.NUMBER, "   ");
398e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
399e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Build diff, expecting insert for data row and update enforcement
400ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        EntityDeltaListTests.assertDiffPattern(state,
401ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildAssertVersion(VER_FIRST),
402ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationSuspended(),
403ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
404ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                        EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
405ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationDefault());
406e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
407e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Trim empty rows and try again, expecting delete of overall contact
408e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        EntityModifier.trimEmpty(state, source);
409ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        EntityDeltaListTests.assertDiffPattern(state,
410ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildAssertVersion(VER_FIRST),
411ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildDelete(RawContacts.CONTENT_URI));
412e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey    }
413e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
414e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey    public void testTrimLeaveValid() {
415b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
416e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
417e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
418e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
419e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Test row that has type values with valid number
420ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST);
421e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
422e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        values.put(Phone.NUMBER, TEST_PHONE);
423e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
424e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Build diff, expecting insert for data row and update enforcement
425ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        EntityDeltaListTests.assertDiffPattern(state,
426ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildAssertVersion(VER_FIRST),
427ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationSuspended(),
428ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
429ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                        EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
430ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationDefault());
431e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
432e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        // Trim empty rows and try again, expecting no differences
433e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey        EntityModifier.trimEmpty(state, source);
434ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        EntityDeltaListTests.assertDiffPattern(state,
435ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildAssertVersion(VER_FIRST),
436ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationSuspended(),
437ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
438ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                        EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
439ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann                EntityDeltaListTests.buildUpdateAggregationDefault());
440e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey    }
441e31dac84479a4c7b356edfc062a447cdfb5efc69Jeff Sharkey
4426f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void testTrimEmptyUntouched() {
443b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
4446f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
4456c9b4b97752e415528279464b28560d389256783Daniel Lehmann        EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
4466f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4476f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Build "before" that has empty row
4487f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
4496f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ContentValues before = new ContentValues();
4506f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(Data._ID, TEST_ID);
4516f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
4526f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.addEntry(ValuesDelta.fromBefore(before));
4536f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4546f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Build diff, expecting no changes
4556f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
4566f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
4576f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
4586f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4596f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Try trimming existing empty, which we shouldn't touch
4607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        EntityModifier.trimEmpty(state, source);
4616f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        diff.clear();
4626f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
4636f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
4646f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
4656f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4666f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void testTrimEmptyAfterUpdate() {
467b77be6d2ad06edfd8751f55043e4aa9fd9f36015Dmitri Plotnikov        final AccountType source = getAccountType();
4686f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
4696f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
4706f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4716f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Build "before" that has row with some phone number
4726f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ContentValues before = new ContentValues();
4736f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(Data._ID, TEST_ID);
4746f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
4756f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(kindPhone.typeColumn, typeHome.rawValue);
4766f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        before.put(Phone.NUMBER, TEST_PHONE);
4777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID, before);
4786f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4796f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Build diff, expecting no changes
4806f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
4816f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
4826f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
4836f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
4846f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Now update row by changing number to empty string, expecting single update
4856f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        final ValuesDelta child = state.getEntry(TEST_ID);
4866f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        child.put(Phone.NUMBER, "");
4876f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        diff.clear();
4886f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
4896f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 3, diff.size());
4906f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
4916f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(0);
4926f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
4936f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
4946f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
4956f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
4966f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(1);
4976f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
4986f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
4996f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
5006f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
5016f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(2);
5026f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
5036f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
5046f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
5056f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
5066f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Now run trim, which should turn that update into delete
5077f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        EntityModifier.trimEmpty(state, source);
5087f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
5097f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
5107f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 1, diff.size());
5117f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
5127f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
5137f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
5147f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
5157f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
5167f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    }
5177f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5187f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    public void testTrimInsertEmpty() {
519a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
520a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = getAccountTypes(accountType);
521a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
5226c9b4b97752e415528279464b28560d389256783Daniel Lehmann        EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
5237f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5247f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Try creating a contact without any child entries
5257f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(null);
526ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDeltaList set = EntityDeltaList.fromSingle(state);
5277f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5287f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build diff, expecting single insert
5297f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
5307f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
5313aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov        assertEquals("Unexpected operations", 2, diff.size());
5327f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
5337f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
5347f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
5357f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
5367f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
5377f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5387f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Trim empty rows and try again, expecting no insert
539a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.trimEmpty(set, accountTypes);
5407f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
5417f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
5427f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
5437f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    }
5447f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5457f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    public void testTrimInsertInsert() {
546a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
547a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = getAccountTypes(accountType);
548a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
5497f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
5507f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5517f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Try creating a contact with single empty entry
5527f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(null);
5536c9b4b97752e415528279464b28560d389256783Daniel Lehmann        EntityModifier.insertChild(state, kindPhone, typeHome);
554ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDeltaList set = EntityDeltaList.fromSingle(state);
5557f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5567f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build diff, expecting two insert operations
5577f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
5587f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
5593aba36cc373e82ca3a3331bb77bd1278d0afde06Dmitri Plotnikov        assertEquals("Unexpected operations", 3, diff.size());
5607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
5617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
5627f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
5637f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
5647f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
5657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
5667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
5677f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
5687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
5697f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
5707f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Trim empty rows and try again, expecting silence
572a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.trimEmpty(set, accountTypes);
5737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
5747f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
5757f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
5767f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    }
5777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    public void testTrimUpdateRemain() {
579a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
580a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = getAccountTypes(accountType);
581a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
5827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
5837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5847f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build "before" with two phone numbers
5857f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ContentValues first = new ContentValues();
5867f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Data._ID, TEST_ID);
5877f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
5887f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(kindPhone.typeColumn, typeHome.rawValue);
5897f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Phone.NUMBER, TEST_PHONE);
5907f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5917f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ContentValues second = new ContentValues();
5927f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        second.put(Data._ID, TEST_ID);
5937f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        second.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
5947f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        second.put(kindPhone.typeColumn, typeHome.rawValue);
5957f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        second.put(Phone.NUMBER, TEST_PHONE);
5967f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
5977f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID, first, second);
598ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDeltaList set = EntityDeltaList.fromSingle(state);
5997f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6007f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build diff, expecting no changes
6017f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
6027f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
6037f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
6047f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6057f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Now update row by changing number to empty string, expecting single update
6067f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ValuesDelta child = state.getEntry(TEST_ID);
6077f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        child.put(Phone.NUMBER, "");
6087f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
6097f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
6107f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 3, diff.size());
6117f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6127f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
6137f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6147f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6157f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6167f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6177f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
6187f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
6197f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
6207f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6217f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6227f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(2);
6237f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6247f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6257f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6267f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6277f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Now run trim, which should turn that update into delete
628a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.trimEmpty(set, accountTypes);
6296f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        diff.clear();
6306f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        state.buildDiff(diff);
6316f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        assertEquals("Unexpected operations", 3, diff.size());
6326f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
6336f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(0);
6346f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6356f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6366f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
6376f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
6386f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(1);
6396f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
6406f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
6416f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
6426f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        {
6436f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            final ContentProviderOperation oper = diff.get(2);
6446f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6456f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6466f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        }
6476f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
6487f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6497f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    public void testTrimUpdateUpdate() {
650a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
651a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountTypeManager accountTypes = getAccountTypes(accountType);
652a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
6537f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
6547f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6557f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build "before" with two phone numbers
6567f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ContentValues first = new ContentValues();
6577f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Data._ID, TEST_ID);
6587f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
6597f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(kindPhone.typeColumn, typeHome.rawValue);
6607f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        first.put(Phone.NUMBER, TEST_PHONE);
6617f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6627f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID, first);
663ca98444277723c60be83062cf5a25ec7ca1fdb34Daniel Lehmann        final EntityDeltaList set = EntityDeltaList.fromSingle(state);
6647f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6657f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Build diff, expecting no changes
6667f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
6677f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
6687f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 0, diff.size());
6697f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6707f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Now update row by changing number to empty string, expecting single update
6717f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        final ValuesDelta child = state.getEntry(TEST_ID);
6727f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        child.put(Phone.NUMBER, "");
6737f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
6747f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
6757f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 3, diff.size());
6767f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6777f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
6787f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6797f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6807f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6817f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6827f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(1);
6837f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
6847f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
6857f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6867f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6877f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(2);
6887f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
6897f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
6907f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
6917f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey
6927f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        // Now run trim, which should turn into deleting the whole contact
693a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.trimEmpty(set, accountTypes);
6947f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        diff.clear();
6957f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        state.buildDiff(diff);
6967f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        assertEquals("Unexpected operations", 1, diff.size());
6977f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        {
6987f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            final ContentProviderOperation oper = diff.get(0);
6997f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
7007f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
7017f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey        }
7027f86847eddbec5dff4d87ac9243d839593582e42Jeff Sharkey    }
70316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
70416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    public void testParseExtrasExistingName() {
705a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
70616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
70716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        // Build "before" name
70816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final ContentValues first = new ContentValues();
70916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(Data._ID, TEST_ID);
71016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
71116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(StructuredName.GIVEN_NAME, TEST_NAME);
71216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
71316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        // Parse extras, making sure we keep single name
71416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID, first);
71516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final Bundle extras = new Bundle();
71616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        extras.putString(Insert.NAME, TEST_NAME2);
717a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.parseExtras(mContext, accountType, state, extras);
71816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
71916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final int nameCount = state.getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true);
72016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        assertEquals("Unexpected names", 1, nameCount);
72116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    }
72216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
72316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    public void testParseExtrasIgnoreLimit() {
724a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
72516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
72616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        // Build "before" IM
72716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final ContentValues first = new ContentValues();
72816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(Data._ID, TEST_ID);
72916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
73016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        first.put(Im.DATA, TEST_IM);
73116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
73216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID, first);
73316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final int beforeCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
73416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
735a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        // We should ignore data that doesn't fit account type rules, since account type
73616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        // only allows single Im
73716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final Bundle extras = new Bundle();
73816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        extras.putInt(Insert.IM_PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
73916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        extras.putString(Insert.IM_HANDLE, TEST_IM);
740a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.parseExtras(mContext, accountType, state, extras);
74116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
74216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final int afterCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
743a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        assertEquals("Broke account type rules", beforeCount, afterCount);
74416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    }
74516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
74616c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    public void testParseExtrasIgnoreUnhandled() {
747a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
74816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
74916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
750a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        // We should silently ignore types unsupported by account type
75116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final Bundle extras = new Bundle();
75216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        extras.putString(Insert.POSTAL, TEST_POSTAL);
753a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.parseExtras(mContext, accountType, state, extras);
75416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
755a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        assertNull("Broke accoun type rules",
756a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov                state.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE));
75716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    }
75816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
75916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    public void testParseExtrasJobTitle() {
760a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        final AccountType accountType = getAccountType();
76116c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final EntityDelta state = getEntity(TEST_ID);
76216c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
76316c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        // Make sure that we create partial Organizations
76416c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final Bundle extras = new Bundle();
76516c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        extras.putString(Insert.JOB_TITLE, TEST_NAME);
766a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        EntityModifier.parseExtras(mContext, accountType, state, extras);
76716c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey
76816c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        final int count = state.getMimeEntries(Organization.CONTENT_ITEM_TYPE).size();
76916c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey        assertEquals("Expected to create organization", 1, count);
77016c364a557d619a0396ed35249478dcf2c1ffba5Jeff Sharkey    }
771d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
772d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateWithDisplayNameFromGoogleToExchange1() {
773d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
774d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
775d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
776d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
777d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContactsMockContext context = new ContactsMockContext(getContext());
778d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
779d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
780d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
781d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
782d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.PREFIX, "prefix");
783d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.GIVEN_NAME, "given");
784d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.MIDDLE_NAME, "middle");
785d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.FAMILY_NAME, "family");
786d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.SUFFIX, "suffix");
787d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "PHONETIC_FAMILY");
788d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "PHONETIC_MIDDLE");
789d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "PHONETIC_GIVEN");
790d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
791d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
792d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
793d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateStructuredName(context, oldState, newState, kind);
794d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
795d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
796d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
797d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues output = list.get(0).getAfter();
798d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("prefix", output.getAsString(StructuredName.PREFIX));
799d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("given", output.getAsString(StructuredName.GIVEN_NAME));
800d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("middle", output.getAsString(StructuredName.MIDDLE_NAME));
801d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("family", output.getAsString(StructuredName.FAMILY_NAME));
802d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("suffix", output.getAsString(StructuredName.SUFFIX));
803d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Phonetic middle name isn't supported by Exchange.
804d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("PHONETIC_FAMILY", output.getAsString(StructuredName.PHONETIC_FAMILY_NAME));
805d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("PHONETIC_GIVEN", output.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
806d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
807d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
808d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateWithDisplayNameFromGoogleToExchange2() {
809d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
810d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
811d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
812d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
813d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContactsMockContext context = new ContactsMockContext(getContext());
814d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        MockContentProvider provider = context.getContactsProvider();
815d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
816d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        String inputDisplayName = "prefix given middle family suffix";
817d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // The method will ask the provider to split/join StructuredName.
818d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        Uri uriForBuildDisplayName =
819d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                ContactsContract.AUTHORITY_URI
820d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .buildUpon()
821d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendPath("complete_name")
822d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.DISPLAY_NAME, inputDisplayName)
823d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .build();
824d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        provider.expectQuery(uriForBuildDisplayName)
825d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                .returnRow("prefix", "given", "middle", "family", "suffix")
826d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                .withProjection(StructuredName.PREFIX, StructuredName.GIVEN_NAME,
827d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        StructuredName.MIDDLE_NAME, StructuredName.FAMILY_NAME,
828d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        StructuredName.SUFFIX);
829d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
830d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
831d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
832d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
833d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.DISPLAY_NAME, inputDisplayName);
834d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
835d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
836d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
837d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateStructuredName(context, oldState, newState, kind);
838d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
839d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
840d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
841d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
842d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("prefix", outputValues.getAsString(StructuredName.PREFIX));
843d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("given", outputValues.getAsString(StructuredName.GIVEN_NAME));
844d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("middle", outputValues.getAsString(StructuredName.MIDDLE_NAME));
845d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("family", outputValues.getAsString(StructuredName.FAMILY_NAME));
846d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("suffix", outputValues.getAsString(StructuredName.SUFFIX));
847d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
848d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
849d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateWithStructuredNameFromExchangeToGoogle() {
850d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new ExchangeAccountType(getContext(), "");
851d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new GoogleAccountType(getContext(), "");
852d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
853d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
854d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContactsMockContext context = new ContactsMockContext(getContext());
855d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        MockContentProvider provider = context.getContactsProvider();
856d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
857d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // The method will ask the provider to split/join StructuredName.
858d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        Uri uriForBuildDisplayName =
859d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                ContactsContract.AUTHORITY_URI
860d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .buildUpon()
861d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendPath("complete_name")
862d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.PREFIX, "prefix")
863d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.GIVEN_NAME, "given")
864d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.MIDDLE_NAME, "middle")
865d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.FAMILY_NAME, "family")
866d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .appendQueryParameter(StructuredName.SUFFIX, "suffix")
867d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                        .build();
868d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        provider.expectQuery(uriForBuildDisplayName)
869d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                .returnRow("prefix given middle family suffix")
870d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                .withProjection(StructuredName.DISPLAY_NAME);
871d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
872d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
873d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
874d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
875d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.PREFIX, "prefix");
876d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.GIVEN_NAME, "given");
877d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.MIDDLE_NAME, "middle");
878d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.FAMILY_NAME, "family");
879d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredName.SUFFIX, "suffix");
880d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
881d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
882d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
883d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateStructuredName(context, oldState, newState, kind);
884d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
885d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
886d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
887d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
888d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
889d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("prefix given middle family suffix",
890d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                outputValues.getAsString(StructuredName.DISPLAY_NAME));
891d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
892d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
893d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigratePostalFromGoogleToExchange() {
894d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
895d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
896d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
897d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
898d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
899d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
900d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
901d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.FORMATTED_ADDRESS, "formatted_address");
902d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
903d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
904d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
905d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migratePostal(oldState, newState, kind);
906d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
907d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
908d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
909d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
910d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
911d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // FORMATTED_ADDRESS isn't supported by Exchange.
912d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNull(outputValues.getAsString(StructuredPostal.FORMATTED_ADDRESS));
913d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("formatted_address", outputValues.getAsString(StructuredPostal.STREET));
914d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
915d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
916d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigratePostalFromExchangeToGoogle() {
917d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new ExchangeAccountType(getContext(), "");
918d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new GoogleAccountType(getContext(), "");
919d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
920d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
921d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
922d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
923d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
924d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.COUNTRY, "country");
925d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.POSTCODE, "postcode");
926d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.REGION, "region");
927d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.CITY, "city");
928d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(StructuredPostal.STREET, "street");
929d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
930d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
931d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
932d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migratePostal(oldState, newState, kind);
933d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
934d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
935d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
936d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
937d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
938d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
939d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Check FORMATTED_ADDRESS contains all info.
940d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        String formattedAddress = outputValues.getAsString(StructuredPostal.FORMATTED_ADDRESS);
941d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(formattedAddress);
942d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("country"));
943d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("postcode"));
944d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("region"));
945d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("postcode"));
946d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("city"));
947d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertTrue(formattedAddress.contains("street"));
948d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
949d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
950d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateEventFromGoogleToExchange1() {
951d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        testMigrateEventCommon(new GoogleAccountType(getContext(), ""),
952d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                new ExchangeAccountType(getContext(), ""));
953d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
954d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
955d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateEventFromExchangeToGoogle() {
956d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        testMigrateEventCommon(new ExchangeAccountType(getContext(), ""),
957d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                new GoogleAccountType(getContext(), ""));
958d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
959d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
960d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    private void testMigrateEventCommon(AccountType oldAccountType, AccountType newAccountType) {
961d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
962d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
963d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
964d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
965d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
966d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.START_DATE, "1972-02-08");
967d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
968d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
969d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
970d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
971d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateEvent(oldState, newState, kind, 1990);
972d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
973d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
974d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
975d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());  // Anniversary should be dropped.
976d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
977d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
978d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("1972-02-08", outputValues.getAsString(Event.START_DATE));
979d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Event.TYPE_BIRTHDAY, outputValues.getAsInteger(Event.TYPE).intValue());
980d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
981d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
982d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateEventFromGoogleToExchange2() {
983d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
984d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
985d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
986d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
987d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
988d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
989d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
990d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // No year format is not supported by Exchange.
991d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.START_DATE, "--06-01");
992d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
993d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
994d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
995d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
996d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.START_DATE, "1980-08-02");
997d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Anniversary is not supported by Exchange
998d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Event.TYPE, Event.TYPE_ANNIVERSARY);
999d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1000d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1001d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
1002d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateEvent(oldState, newState, kind, 1990);
1003d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1004d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
1005d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
1006d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());  // Anniversary should be dropped.
1007d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
1008d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1009d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Default year should be used.
1010d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("1990-06-01", outputValues.getAsString(Event.START_DATE));
1011d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Event.TYPE_BIRTHDAY, outputValues.getAsInteger(Event.TYPE).intValue());
1012d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
1013d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1014d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateEmailFromGoogleToExchange() {
1015d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
1016d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
1017d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Email.CONTENT_ITEM_TYPE);
1018d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1019d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
1020d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
1021d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
1022d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.TYPE, Email.TYPE_CUSTOM);
1023d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.LABEL, "custom_type");
1024d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.ADDRESS, "address1");
1025d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1026d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1027d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
1028d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.TYPE, Email.TYPE_HOME);
1029d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.ADDRESS, "address2");
1030d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1031d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1032d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
1033d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.TYPE, Email.TYPE_WORK);
1034d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.ADDRESS, "address3");
1035d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1036d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Exchange can have up to 3 email entries. This 4th entry should be dropped.
1037d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1038d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
1039d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.TYPE, Email.TYPE_OTHER);
1040d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Email.ADDRESS, "address4");
1041d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1042d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1043d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
1044d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
1045d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1046d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Email.CONTENT_ITEM_TYPE);
1047d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
1048d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(3, list.size());
1049d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1050d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
1051d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Email.TYPE_CUSTOM, outputValues.getAsInteger(Email.TYPE).intValue());
1052d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("custom_type", outputValues.getAsString(Email.LABEL));
1053d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("address1", outputValues.getAsString(Email.ADDRESS));
1054d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1055d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(1).getAfter();
1056d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Email.TYPE_HOME, outputValues.getAsInteger(Email.TYPE).intValue());
1057d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("address2", outputValues.getAsString(Email.ADDRESS));
1058d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1059d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(2).getAfter();
1060d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Email.TYPE_WORK, outputValues.getAsInteger(Email.TYPE).intValue());
1061d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("address3", outputValues.getAsString(Email.ADDRESS));
1062d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
1063d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1064d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateImFromGoogleToExchange() {
1065d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
1066d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
1067d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Im.CONTENT_ITEM_TYPE);
1068d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1069d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
1070d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
1071d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
1072d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Exchange doesn't support TYPE_HOME
1073d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.TYPE, Im.TYPE_HOME);
1074d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_JABBER);
1075d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.DATA, "im1");
1076d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1077d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1078d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1079d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
1080d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Exchange doesn't support TYPE_WORK
1081d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.TYPE, Im.TYPE_WORK);
1082d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_YAHOO);
1083d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.DATA, "im2");
1084d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1085d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1086d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1087d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
1088d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.TYPE, Im.TYPE_OTHER);
1089d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_CUSTOM);
1090d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.CUSTOM_PROTOCOL, "custom_protocol");
1091d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.DATA, "im3");
1092d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1093d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1094d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Exchange can have up to 3 IM entries. This 4th entry should be dropped.
1095d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1096d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
1097d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.TYPE, Im.TYPE_OTHER);
1098d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
1099d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Im.DATA, "im4");
1100d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1101d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1102d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
1103d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
1104d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1105d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Im.CONTENT_ITEM_TYPE);
1106d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
1107d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(3, list.size());
1108d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1109d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(kind.defaultValues.getAsInteger(Im.TYPE));
1110d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1111d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        int defaultType = kind.defaultValues.getAsInteger(Im.TYPE);
1112d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1113d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
1114d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // HOME should become default type.
1115d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
1116d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Im.PROTOCOL_JABBER, outputValues.getAsInteger(Im.PROTOCOL).intValue());
1117d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("im1", outputValues.getAsString(Im.DATA));
1118d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1119d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(1).getAfter();
1120d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
1121d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Im.PROTOCOL_YAHOO, outputValues.getAsInteger(Im.PROTOCOL).intValue());
1122d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("im2", outputValues.getAsString(Im.DATA));
1123d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1124d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(2).getAfter();
1125d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
1126d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Im.PROTOCOL_CUSTOM, outputValues.getAsInteger(Im.PROTOCOL).intValue());
1127d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("custom_protocol", outputValues.getAsString(Im.CUSTOM_PROTOCOL));
1128d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("im3", outputValues.getAsString(Im.DATA));
1129d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
1130d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1131d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigratePhoneFromGoogleToExchange() {
1132d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
1133d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
1134d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
1135d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1136d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
1137d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
1138d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1139d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.TYPE, Phone.TYPE_HOME);
1140d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.NUMBER, "1");
1141d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1142d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1143d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1144d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.TYPE, Phone.TYPE_MOBILE);
1145d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.NUMBER, "2");
1146d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1147d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1148d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1149d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // Exchange doesn't support this type. Default to HOME
1150d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
1151d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.LABEL, "custom_type");
1152d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.NUMBER, "3");
1153d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1154d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1155d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1156d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK);
1157d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.NUMBER, "4");
1158d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1159d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues = new ContentValues();
1160d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1161d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // This field should be ignored, as Exchange only allows 2 HOME phone numbers while we
1162d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        // already have that number of HOME phones.
1163d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1164d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
1165d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Phone.NUMBER, "5");
1166d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1167d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1168d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
1169d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
1170d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1171d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
1172d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
1173d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(4, list.size());
1174d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1175d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        int defaultType = kind.typeList.get(0).rawValue;
1176d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1177d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
1178d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Phone.TYPE_HOME, outputValues.getAsInteger(Phone.TYPE).intValue());
1179d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("1", outputValues.getAsString(Phone.NUMBER));
1180d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(1).getAfter();
1181d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Phone.TYPE_MOBILE, outputValues.getAsInteger(Phone.TYPE).intValue());
1182d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("2", outputValues.getAsString(Phone.NUMBER));
1183d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(2).getAfter();
1184d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(defaultType, outputValues.getAsInteger(Phone.TYPE).intValue());
1185d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNull(outputValues.getAsInteger(Phone.LABEL));
1186d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("3", outputValues.getAsString(Phone.NUMBER));
1187d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        outputValues = list.get(3).getAfter();
1188d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(Phone.TYPE_WORK, outputValues.getAsInteger(Phone.TYPE).intValue());
1189d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("4", outputValues.getAsString(Phone.NUMBER));
1190d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
1191d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1192d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public void testMigrateOrganizationFromGoogleToExchange() {
1193d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
1194d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        AccountType newAccountType = new ExchangeAccountType(getContext(), "");
1195d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        DataKind kind = newAccountType.getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
1196d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1197d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta oldState = new EntityDelta();
1198d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues mockNameValues = new ContentValues();
1199d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
1200d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Organization.COMPANY, "company1");
1201d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        mockNameValues.put(Organization.DEPARTMENT, "department1");
1202d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
1203d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1204d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityDelta newState = new EntityDelta();
1205d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        EntityModifier.migrateGenericWithoutTypeColumn(oldState, newState, kind);
1206d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1207d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        List<ValuesDelta> list = newState.getMimeEntries(Organization.CONTENT_ITEM_TYPE);
1208d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertNotNull(list);
1209d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals(1, list.size());
1210d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1211d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        ContentValues outputValues = list.get(0).getAfter();
1212d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("company1", outputValues.getAsString(Organization.COMPANY));
1213d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        assertEquals("department1", outputValues.getAsString(Organization.DEPARTMENT));
1214d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
121507c2e41b5ce7abeb9dd14e5d700a8fb928723330Jeff Sharkey}
1216