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

Commit 66da163d authored by Daisuke Miyakawa's avatar Daisuke Miyakawa
Browse files

Move some useful logic to VCardTestsBase.java

Internal issue number: 2195990
parent 21cbd52b
Loading
Loading
Loading
Loading
+0 −380
Original line number Diff line number Diff line
@@ -16,32 +16,9 @@

package com.android.unit_tests.vcard;

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.content.EntityIterator;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
import android.database.IContentObserver;
import android.net.Uri;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.pim.vcard.VCardComposer;
import android.pim.vcard.VCardConfig;
import android.pim.vcard.VCardParser;
import android.pim.vcard.VCardParser_V21;
import android.pim.vcard.VCardParser_V30;
import android.pim.vcard.exception.VCardException;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -53,102 +30,10 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.mock.MockCursor;
import android.util.Log;

import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;

import junit.framework.TestCase;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
 * class extends ContentProvider, not implementing IContentProvider,
 * so that MockContentResolver is able to accept this class :(
 */
class MockContentProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public int bulkInsert(Uri url, ContentValues[] initialValues) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @SuppressWarnings("unused")
    public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sortOrder, IContentObserver observer,
            CursorWindow window) throws RemoteException {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    @SuppressWarnings("unused")
    public int delete(Uri url, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public String getType(Uri url) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public Uri insert(Uri url, ContentValues initialValues) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public ParcelFileDescriptor openFile(Uri url, String mode) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    /**
     * @hide
     */
    @Override
    public EntityIterator queryEntities(Uri url, String selection, String[] selectionArgs,
            String sortOrder) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    public IBinder asBinder() {
        throw new UnsupportedOperationException("unimplemented mock method");
    }
}

/**
 * Tests for the code related to vCard exporter, inculding vCard composer.
@@ -156,274 +41,9 @@ class MockContentProvider extends ContentProvider {
 * the result of this class will not be reliable.
 */
public class VCardExporterTests extends VCardTestsBase {
    private static final int V21 = 0;
    private static final int V30 = 1;

    private static final byte[] sPhotoByteArray =
        VCardImporterTests.sPhotoByteArrayForComplicatedCase;

    public class ExportTestResolver extends MockContentResolver {
        ExportTestProvider mProvider = new ExportTestProvider();
        public ExportTestResolver() {
            addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
            addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
        }

        public ContentValues buildData(String mimeType) {
            return mProvider.buildData(mimeType);
        }
    }

    public static class MockEntityIterator implements EntityIterator {
        Collection<Entity> mEntityCollection;
        Iterator<Entity> mIterator;

        // TODO: Support multiple vCard entries.
        public MockEntityIterator(Collection<ContentValues> contentValuesCollection) {
            mEntityCollection = new ArrayList<Entity>();
            Entity entity = new Entity(new ContentValues());
            for (ContentValues contentValues : contentValuesCollection) {
                entity.addSubValue(Data.CONTENT_URI, contentValues);
            }
            mEntityCollection.add(entity);
            mIterator = mEntityCollection.iterator();
        }

        public boolean hasNext() {
            return mIterator.hasNext();
        }

        public Entity next() {
            return mIterator.next();
        }

        public void reset() {
            mIterator = mEntityCollection.iterator();
        }

        public void close() {
        }
    }

    public class ExportTestProvider extends MockContentProvider {
        List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
        public ContentValues buildData(String mimeType) {
            ContentValues contentValues = new ContentValues();
            contentValues.put(Data.MIMETYPE, mimeType);
            mContentValuesList.add(contentValues);
            return contentValues;
        }

        @Override
        public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
                String sortOrder) {
            assert(uri != null);
            assert(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
            final String authority = uri.getAuthority();
            assert(RawContacts.CONTENT_URI.getAuthority().equals(authority));

            return new MockEntityIterator(mContentValuesList);
        }

        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                String sortOrder) {
            assert(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
            // Support multiple rows.
            return new MockCursor() {
                int mCurrentPosition = -1;

                @Override
                public int getCount() {
                    return 1;
                }

                @Override
                public boolean moveToFirst() {
                    mCurrentPosition = 0;
                    return true;
                }

                @Override
                public boolean moveToNext() {
                    if (mCurrentPosition == 0 || mCurrentPosition == -1) {
                        mCurrentPosition++;
                        return true;
                    } else {
                        return false;
                    }
                }

                @Override
                public boolean isBeforeFirst() {
                    return mCurrentPosition < 0;
                }

                @Override
                public boolean isAfterLast() {
                    return mCurrentPosition > 0;
                }

                @Override
                public int getColumnIndex(String columnName) {
                    assertEquals(Contacts._ID, columnName);
                    return 0;
                }

                @Override
                public int getInt(int columnIndex) {
                    assertEquals(0, columnIndex);
                    return 0;
                }

                @Override
                public String getString(int columnIndex) {
                    return String.valueOf(getInt(columnIndex));
                }

                @Override
                public void close() {
                }
            };
        }
    }

    public static class VCardVerificationHandler implements VCardComposer.OneEntryHandler {
        final private TestCase mTestCase;
        final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
        final private boolean mIsV30;
        // To allow duplication, use list instead of set.
        // TODO: support multiple vCard entries.
        final private List<String> mExpectedLineList;
        final private ContactStructVerifier mContactStructVerifier;
        final private int mVCardType;
        int mCount;

        public VCardVerificationHandler(final TestCase testCase, final int version) {
            this(testCase, null, version);
        }

        public VCardVerificationHandler(final TestCase testCase,
                ContactStructVerifier contactStructVerifier, final int version) {
            mTestCase = testCase;
            mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
            mIsV30 = (version == V30);
            mExpectedLineList = new ArrayList<String>();
            mContactStructVerifier = contactStructVerifier;
            mVCardType = (version == V30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
                    : VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
            mCount = 1;
        }

        public PropertyNodesVerifier addNewVerifier() {
            PropertyNodesVerifier verifier = new PropertyNodesVerifier(mTestCase);
            mPropertyNodesVerifierList.add(verifier);
            verifier.addNodeWithOrder("VERSION", mIsV30 ? "3.0" : "2.1");
            return verifier;
        }

        public PropertyNodesVerifier addNewVerifierWithEmptyName() {
            PropertyNodesVerifier verifier = addNewVerifier();
            if (mIsV30) {
                verifier.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
            }
            return verifier;
        }

        public VCardVerificationHandler addExpectedLine(String line) {
            mExpectedLineList.add(line);
            return this;
        }

        public boolean onInit(final Context context) {
            return true;
        }

        public boolean onEntryCreated(final String vcard) {
            if (!mExpectedLineList.isEmpty()) {
                verifyLines(vcard);
            }
            verifyNodes(vcard);
            return true;
        }

        private void verifyLines(final String vcard) {
            final String[] lineArray = vcard.split("\\r?\\n");
            final int length = lineArray.length;
            for (int i = 0; i < length; i++) {
                final String line = lineArray[i];
                // TODO: support multiple vcard entries.
                if ("BEGIN:VCARD".equals(line) || "END:VCARD".equals(line) ||
                        (mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equals(line)) {
                    continue;
                }
                final int index = mExpectedLineList.indexOf(line);
                if (index >= 0) {
                    mExpectedLineList.remove(index);
                } else {
                    mTestCase.fail("Unexpected line: " + line);
                }
            }
            if (!mExpectedLineList.isEmpty()) {
                StringBuffer buffer = new StringBuffer();
                for (String expectedLine : mExpectedLineList) {
                    buffer.append(expectedLine);
                    buffer.append("\n");
                }
                mTestCase.fail("Expected line(s) not found:" + buffer.toString());
            }
        }

        private void verifyNodes(final String vcard) {
            if (mPropertyNodesVerifierList.size() == 0) {
                mTestCase.fail("Too many vCard entries seems to be inserted(No."
                        + mCount + " of the entries (No.1 is the first entry))");
            }
            PropertyNodesVerifier propertyNodesVerifier =
                mPropertyNodesVerifierList.get(0);
            mPropertyNodesVerifierList.remove(0);
            VCardParser parser = (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
            VNodeBuilder builder = new VNodeBuilder();
            InputStream is;
            try {
                is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
                mTestCase.assertEquals(true, parser.parse(is, null, builder));
                is.close();
                mTestCase.assertEquals(1, builder.vNodeList.size());
                propertyNodesVerifier.verify(builder.vNodeList.get(0));
                if (mContactStructVerifier != null) {
                    Log.d("@@@", vcard);
                    is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
                    mContactStructVerifier.verify(is, mVCardType);
                    is.close();
                }
            } catch (IOException e) {
                mTestCase.fail("Unexpected IOException: " + e.getMessage());
            } catch (VCardException e) {
                mTestCase.fail("Unexpected VCardException: " + e.getMessage());
            } finally {
                mCount++;
            }
        }

        public void onTerminate() {
        }
    }

    private class CustomMockContext extends MockContext {
        final ContentResolver mResolver;
        public CustomMockContext(ContentResolver resolver) {
            mResolver = resolver;
        }

        @Override
        public ContentResolver getContentResolver() {
            return mResolver;
        }
    }

    //// Followings are actual tests ////

    private void verifyOneComposition(ExportTestResolver resolver,
            VCardVerificationHandler handler, int version) {
        final boolean isV30 = (version == V30);
+367 −5

File changed.

Preview size limit exceeded, changes collapsed.