| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.provider.cts.contacts; |
| |
| import com.google.android.collect.Lists; |
| import com.google.android.collect.Sets; |
| |
| import android.content.ContentProviderClient; |
| import android.content.ContentUris; |
| import android.content.ContentValues; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.provider.BaseColumns; |
| import android.provider.ContactsContract; |
| import android.provider.ContactsContract.Contacts; |
| import android.provider.ContactsContract.Data; |
| import android.provider.ContactsContract.Groups; |
| import android.provider.ContactsContract.RawContacts; |
| import android.text.TextUtils; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import junit.framework.Assert; |
| import junit.framework.ComparisonFailure; |
| |
| /** |
| * A test data builder for ContactsContract tests. |
| */ |
| public class ContactsContract_TestDataBuilder { |
| private ContentProviderClient mProvider; |
| private ArrayList<Builder<?>> mCreatedRows = Lists.newArrayList(); |
| private HashSet<Builder<?>> mLoadedRows = Sets.newHashSet(); |
| |
| private interface IdQuery { |
| String[] COLUMNS = new String[] { |
| BaseColumns._ID, |
| }; |
| |
| int _ID = 0; |
| } |
| |
| public abstract class Builder<T extends Builder<?>> extends Assert { |
| protected ContentValues mValues = new ContentValues(); |
| private Uri mUri; |
| private long mId = -1; |
| private Cursor mCursor; |
| private boolean mAlreadyDeleted; |
| |
| protected abstract Uri getContentUri(); |
| |
| public long getId() throws Exception { |
| if (mId != -1) { |
| return mId; |
| } |
| |
| assertNotNull("Row has not be inserted or loaded yet", mUri); |
| |
| Cursor cursor = mProvider.query(mUri, IdQuery.COLUMNS, null, null, null, null); |
| if (cursor != null) { |
| try { |
| cursor.moveToFirst(); |
| mId = cursor.getInt(IdQuery._ID); |
| } finally { |
| cursor.close(); |
| } |
| |
| } |
| assertTrue("Could not obtain _ID for URI: " + mUri, mId != -1); |
| return mId; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T setUri(Uri uri) { |
| mUri = uri; |
| return (T)this; |
| } |
| |
| public Uri getUri() { |
| if (mUri == null) { |
| assertTrue("Neither URI nor ID has been specified", mId != -1); |
| mUri = ContentUris.withAppendedId(getContentUri(), mId); |
| } |
| return mUri; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T with(String key, String value) { |
| mValues.put(key, value); |
| return (T)this; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T with(String key, long value) { |
| mValues.put(key, value); |
| return (T)this; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T with(String key, byte[] value) { |
| mValues.put(key, value); |
| return (T)this; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T insert() throws Exception { |
| insertDependent(); |
| mCreatedRows.add(this); |
| return (T)this; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T insertDependent() throws Exception { |
| mUri = mProvider.insert(getContentUri(), mValues); |
| assertNotNull("Could not insert a row in " + getContentUri(), mUri); |
| mId = ContentUris.parseId(mUri); |
| return (T)this; |
| } |
| |
| public void delete() throws Exception { |
| int count = mProvider.delete(getUri(), null, null); |
| assertEquals("Wrong number of rows deleted for " + getUri(), 1, count); |
| } |
| |
| public void deletePermanently() throws Exception { |
| if (mAlreadyDeleted) { |
| return; |
| } |
| Uri uri = getUri().buildUpon() |
| .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") |
| .build(); |
| int count = mProvider.delete(uri, null, null); |
| assertEquals("Wrong number of rows deleted for " + uri, 1, count); |
| mCreatedRows.remove(this); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T load() throws Exception { |
| close(); |
| mLoadedRows.add(this); |
| |
| mCursor = mProvider.query(getUri(), null, null, null, null, null); |
| if (mCursor == null || !mCursor.moveToFirst()) { |
| return null; |
| } else { |
| return (T) this; |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| public T loadUsingValues() throws Exception { |
| close(); |
| mLoadedRows.add(this); |
| |
| StringBuilder selection = new StringBuilder(); |
| ArrayList<String> selectionArgs = Lists.newArrayList(); |
| Set<Map.Entry<String, Object>> entries = mValues.valueSet(); |
| for (Map.Entry<String, Object> entry : entries) { |
| String column = entry.getKey(); |
| Object value = entry.getValue(); |
| |
| if (selection.length() != 0) { |
| selection.append(" AND "); |
| } |
| |
| selection.append(column); |
| if (value == null) { |
| selection.append(" NOT NULL"); |
| } else { |
| selection.append("=?"); |
| selectionArgs.add(value.toString()); |
| } |
| } |
| mCursor = mProvider.query(getContentUri(), null, |
| selection.toString(), |
| selectionArgs.toArray(new String[0]), null, null); |
| if (mCursor == null || !mCursor.moveToFirst()) { |
| fail("No data rows for " + getContentUri() + "[" + mValues.toString() + "]"); |
| } |
| mId = mCursor.getLong(getColumnIndex(BaseColumns._ID)); |
| return (T)this; |
| } |
| |
| public boolean isNull(String columnName) { |
| return mCursor.isNull(mCursor.getColumnIndex(columnName)); |
| } |
| |
| public long getLong(String columnName) { |
| return mCursor.getLong(mCursor.getColumnIndex(columnName)); |
| } |
| |
| public String getString(String columnName) { |
| return mCursor.getString(mCursor.getColumnIndex(columnName)); |
| } |
| |
| public void assertColumn(String columnName, long value) { |
| assertEquals(value, mCursor.getLong(getColumnIndex(columnName))); |
| } |
| |
| public void assertColumn(String columnName, String value) { |
| assertEquals(value, mCursor.getString(getColumnIndex(columnName))); |
| } |
| |
| public void assertColumn(String columnName, byte[] value) { |
| assertEquals(value, mCursor.getBlob(getColumnIndex(columnName))); |
| } |
| |
| public void assertBlobColumnNotNull(String columnName) { |
| assertNotNull(mCursor.getBlob(getColumnIndex(columnName))); |
| } |
| |
| public void assertBlobColumnNull(String columnName) { |
| assertNull(mCursor.getBlob(getColumnIndex(columnName))); |
| } |
| |
| public void assertEquals(byte[] expected, byte[] actual) { |
| assertEquals(null, expected, actual); |
| } |
| |
| public void assertEquals(String message, byte[] expected, byte[] actual) { |
| if (expected == null && actual == null) |
| return; |
| if (expected != null && Arrays.equals(actual, expected)) |
| return; |
| throw new ComparisonFailure(message, Arrays.toString(expected), Arrays.toString(actual)); |
| } |
| |
| private int getColumnIndex(String columnName) { |
| int index = mCursor.getColumnIndex(columnName); |
| assertTrue("No such column: " + columnName + |
| ". Available columns: " + TextUtils.join(", ", mCursor.getColumnNames()), |
| index != -1); |
| return index; |
| } |
| |
| public void close() { |
| if (mCursor != null) { |
| mCursor.close(); |
| mCursor = null; |
| } |
| mLoadedRows.remove(this); |
| } |
| |
| public void setAlreadyDeleted() { |
| mAlreadyDeleted = true; |
| } |
| } |
| |
| public class TestRawContact extends Builder<TestRawContact> { |
| |
| private TestContact mContact; |
| |
| @Override |
| protected Uri getContentUri() { |
| return RawContacts.CONTENT_URI; |
| } |
| |
| public TestData newDataRow(String mimeType) { |
| return new TestData(this, mimeType); |
| } |
| |
| public long getContactId() { |
| return getLong(RawContacts.CONTACT_ID); |
| } |
| |
| public TestContact getContact() throws Exception { |
| if (mContact == null) { |
| mContact = new NestedTestContact(this); |
| } |
| return mContact; |
| } |
| } |
| |
| public class TestContact extends Builder<TestContact> { |
| |
| @Override |
| protected Uri getContentUri() { |
| return Contacts.CONTENT_URI; |
| } |
| } |
| |
| private class NestedTestContact extends TestContact { |
| private final TestRawContact mRawContact; |
| |
| public NestedTestContact(TestRawContact rawContact) { |
| mRawContact = rawContact; |
| } |
| |
| @Override |
| public long getId() throws Exception { |
| return mRawContact.getContactId(); |
| } |
| |
| @Override |
| public TestContact load() throws Exception { |
| return with(Contacts._ID, mRawContact.getContactId()).loadUsingValues(); |
| } |
| } |
| |
| public class TestGroup extends Builder<TestGroup> { |
| |
| @Override |
| protected Uri getContentUri() { |
| return Groups.CONTENT_URI; |
| } |
| } |
| |
| public class TestData extends Builder<TestData> { |
| private final TestRawContact mRawContact; |
| |
| public TestData(TestRawContact rawContact, String mimeType) { |
| this.mRawContact = rawContact; |
| mValues.put(Data.MIMETYPE, mimeType); |
| } |
| |
| @Override |
| protected Uri getContentUri() { |
| return Data.CONTENT_URI; |
| } |
| |
| @Override |
| public TestData insert() throws Exception { |
| mValues.put(Data.RAW_CONTACT_ID, mRawContact.getId()); |
| return super.insertDependent(); |
| } |
| |
| public long getRawContactId() { |
| return getLong(Data.RAW_CONTACT_ID); |
| } |
| |
| public long getId() { |
| return getLong(Data._ID); |
| } |
| |
| public TestRawContact getRawContact() throws Exception { |
| return mRawContact; |
| } |
| } |
| |
| public ContactsContract_TestDataBuilder(ContentProviderClient provider) { |
| this.mProvider = provider; |
| } |
| |
| public TestRawContact newRawContact() { |
| return new TestRawContact(); |
| } |
| |
| public TestContact newContact() { |
| return new TestContact(); |
| } |
| |
| public TestGroup newGroup() { |
| return new TestGroup(); |
| } |
| |
| public void cleanup() throws Exception { |
| for (Builder<?> builder : new ArrayList<Builder<?>>(mCreatedRows)) { |
| builder.deletePermanently(); |
| } |
| |
| for (Builder<?> builder : new HashSet<Builder<?>>(mLoadedRows)) { |
| builder.close(); |
| } |
| } |
| |
| } |