Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1301341f authored by Daisuke Miyakawa's avatar Daisuke Miyakawa
Browse files

Fix test breakage in vCard exporter.

Due to the change Iae8dbac1, all tests for vCard exporeter has failed.
This change fixes the breakage by using a kind of dirty Dependency Injection.

Current test framework for vCard exporter strongly depends on the assumption that
ContentValues objects are able to be directly passed to objects which use
ContentResolver, while the change above disabled the feature by removing
queryEntities().

This change makes VCardComposer forcibly uses queryEntities() via Reflection.
I agree that this change is not so clean, but works fine for now.
parent 1dabb95d
Loading
Loading
Loading
Loading
+42 −10
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Method;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -197,7 +198,7 @@ public class VCardComposer {
            if (mIsDoCoMo) {
                try {
                    // Create one empty entry.
                    mWriter.write(createOneEntryInternal("-1"));
                    mWriter.write(createOneEntryInternal("-1", null));
                } catch (IOException e) {
                    Log.e(LOG_TAG,
                            "IOException occurred during exportOneContactData: "
@@ -428,6 +429,14 @@ public class VCardComposer {
    }

    public boolean createOneEntry() {
        return createOneEntry(null);
    }

    /**
     * @param getEntityIteratorMethod For Dependency Injection.
     * @hide just for testing.
     */
    public boolean createOneEntry(Method getEntityIteratorMethod) {
        if (mCursor == null || mCursor.isAfterLast()) {
            mErrorReason = FAILURE_REASON_NOT_INITIALIZED;
            return false;
@@ -439,7 +448,8 @@ public class VCardComposer {
                vcard = createOneCallLogEntryInternal();
            } else {
                if (mIdColumn >= 0) {
                    vcard = createOneEntryInternal(mCursor.getString(mIdColumn));
                    vcard = createOneEntryInternal(mCursor.getString(mIdColumn),
                            getEntityIteratorMethod);
                } else {
                    Log.e(LOG_TAG, "Incorrect mIdColumn: " + mIdColumn);
                    return true;
@@ -475,7 +485,8 @@ public class VCardComposer {
        return true;
    }

    private String createOneEntryInternal(final String contactId) {
    private String createOneEntryInternal(final String contactId,
            Method getEntityIteratorMethod) {
        final Map<String, List<ContentValues>> contentValuesListMap =
                new HashMap<String, List<ContentValues>>();
        // The resolver may return the entity iterator with no data. It is possiible.
@@ -484,6 +495,20 @@ public class VCardComposer {
        boolean dataExists = false;
        EntityIterator entityIterator = null;
        try {

            if (getEntityIteratorMethod != null) {
                try {
                    final Uri uri = RawContacts.CONTENT_URI.buildUpon()
                            .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
                            .build();
                    final String selection = Data.CONTACT_ID + "=?";
                    final String[] selectionArgs = new String[] {contactId};
                    entityIterator = (EntityIterator)getEntityIteratorMethod.invoke(null,
                            mContentResolver, uri, selection, selectionArgs, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                final Uri uri = RawContacts.CONTENT_URI.buildUpon()
                        .appendEncodedPath(contactId)
                        .appendEncodedPath(RawContacts.Entity.CONTENT_DIRECTORY)
@@ -491,6 +516,13 @@ public class VCardComposer {
                        .build();
                entityIterator = RawContacts.newEntityIterator(mContentResolver.query(
                        uri, null, null, null, null));
            }

            if (entityIterator == null) {
                Log.e(LOG_TAG, "EntityIterator is null");
                return "";
            }

            dataExists = entityIterator.hasNext();
            while (entityIterator.hasNext()) {
                Entity entity = entityIterator.next();
+34 −1
Original line number Diff line number Diff line
@@ -110,6 +110,39 @@ import java.util.List;
        return contactEntry;
    }

    /**
     * <p>
     * An old method which had existed but was removed from ContentResolver.
     * </p>
     * <p>
     * We still keep using this method since we don't have a propeer way to know
     * which value in the ContentValue corresponds to the entry in Contacts database.
     * </p>
     * <p>
     * Detail:
     * There's an easy way to know which index "family name" corresponds to, via
     * {@link android.provider.ContactsContract}.
     * FAMILY_NAME equals DATA3, so the corresponding index
     * for "family name" should be 2 (note that index is 0-origin).
     * However, we cannot know what the index 2 corresponds to; it may be "family name",
     * "label" for now, but may be the other some column in the future. We don't have
     * convenient way to know the original data structure.
     * </p>
     */
    public EntityIterator queryEntities(Uri uri,
            String selection, String[] selectionArgs, String sortOrder) {
        mTestCase.assertTrue(uri != null);
        mTestCase.assertTrue(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
        final String authority = uri.getAuthority();
        mTestCase.assertTrue(RawContacts.CONTENT_URI.getAuthority().equals(authority));
        mTestCase.assertTrue((Data.CONTACT_ID + "=?").equals(selection));
        mTestCase.assertEquals(1, selectionArgs.length);
        final int id = Integer.parseInt(selectionArgs[0]);
        mTestCase.assertTrue(id >= 0 && id < mContactEntryList.size());

        return new MockEntityIterator(mContactEntryList.get(id).getList());
    }

    @Override
    public Cursor query(Uri uri,String[] projection,
            String selection, String[] selectionArgs, String sortOrder) {
+29 −2
Original line number Diff line number Diff line
@@ -15,8 +15,11 @@
 */
package com.android.unit_tests.vcard;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.EntityIterator;
import android.net.Uri;
import android.pim.vcard.VCardComposer;
import android.pim.vcard.VCardConfig;
import android.pim.vcard.VCardEntryConstructor;
@@ -32,6 +35,7 @@ import android.test.mock.MockContext;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Arrays;

/* package */ class CustomMockContext extends MockContext {
@@ -259,8 +263,24 @@ import java.util.Arrays;
        }
    }

    public static EntityIterator mockGetEntityIteratorMethod(
            final ContentResolver resolver,
            final Uri uri, final String selection,
            final String[] selectionArgs, final String sortOrder) {
        final ContentProvider provider =
            resolver.acquireContentProviderClient(uri).getLocalContentProvider();
        return ((ExportTestProvider)provider).queryEntities(
                uri, selection, selectionArgs, sortOrder);
    }

    private Method getMockGetEntityIteratorMethod()
            throws SecurityException, NoSuchMethodException {
        return this.getClass().getMethod("mockGetEntityIteratorMethod",
                ContentResolver.class, Uri.class, String.class, String[].class, String.class);
    }

    private void verifyForExportTest() {
        VCardComposer composer =
       final VCardComposer composer =
            new VCardComposer(new CustomMockContext(mExportTestResolver), mVCardType);
        composer.addHandler(mLineVerifier);
        composer.addHandler(mVCardVerifierInternal);
@@ -270,7 +290,14 @@ import java.util.Arrays;
        mTestCase.assertFalse(composer.isAfterLast());
        try {
            while (!composer.isAfterLast()) {
                mTestCase.assertTrue(composer.createOneEntry());
                try {
                    final Method mockGetEntityIteratorMethod = getMockGetEntityIteratorMethod();
                    mTestCase.assertTrue(
                            composer.createOneEntry(getMockGetEntityIteratorMethod()));
                } catch (Exception e) {
                    e.printStackTrace();
                    mTestCase.fail();
                }
            }
        } finally {
            composer.terminate();