diff options
Diffstat (limited to 'tests/src/com/android/photos/data/PhotoProviderTest.java')
-rw-r--r-- | tests/src/com/android/photos/data/PhotoProviderTest.java | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/tests/src/com/android/photos/data/PhotoProviderTest.java b/tests/src/com/android/photos/data/PhotoProviderTest.java new file mode 100644 index 000000000..685946ef0 --- /dev/null +++ b/tests/src/com/android/photos/data/PhotoProviderTest.java @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2013 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 com.android.photos.data; + +import android.content.ContentProviderOperation; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.OperationApplicationException; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.net.Uri; +import android.os.RemoteException; +import android.provider.BaseColumns; +import android.test.ProviderTestCase2; + +import com.android.photos.data.PhotoProvider.Accounts; +import com.android.photos.data.PhotoProvider.Albums; +import com.android.photos.data.PhotoProvider.Metadata; +import com.android.photos.data.PhotoProvider.Photos; + +import java.util.ArrayList; + +public class PhotoProviderTest extends ProviderTestCase2<PhotoProvider> { + @SuppressWarnings("unused") + private static final String TAG = PhotoProviderTest.class.getSimpleName(); + + private static final String MIME_TYPE = "test/test"; + private static final String ALBUM_TITLE = "My Album"; + private static final long ALBUM_PARENT_ID = 100; + private static final String META_KEY = "mykey"; + private static final String META_VALUE = "myvalue"; + private static final String ACCOUNT_NAME = "foo@bar.com"; + + private static final Uri NO_TABLE_URI = PhotoProvider.BASE_CONTENT_URI; + private static final Uri BAD_TABLE_URI = Uri.withAppendedPath(PhotoProvider.BASE_CONTENT_URI, + "bad_table"); + + private static final String WHERE_METADATA_PHOTOS_ID = Metadata.PHOTO_ID + " = ?"; + private static final String WHERE_METADATA = Metadata.PHOTO_ID + " = ? AND " + Metadata.KEY + + " = ?"; + + private long mAlbumId; + private long mPhotoId; + private long mMetadataId; + private long mAccountId; + + private SQLiteOpenHelper mDBHelper; + private ContentResolver mResolver; + private NotificationWatcher mNotifications = new NotificationWatcher(); + + public PhotoProviderTest() { + super(PhotoProvider.class, PhotoProvider.AUTHORITY); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mResolver = getMockContentResolver(); + PhotoProvider provider = (PhotoProvider) getProvider(); + provider.setMockNotification(mNotifications); + mDBHelper = provider.getDatabaseHelper(); + SQLiteDatabase db = mDBHelper.getWritableDatabase(); + db.beginTransaction(); + try { + PhotoDatabaseUtils.insertAccount(db, ACCOUNT_NAME); + mAccountId = PhotoDatabaseUtils.queryAccountIdFromName(db, ACCOUNT_NAME); + PhotoDatabaseUtils.insertAlbum(db, ALBUM_PARENT_ID, ALBUM_TITLE, + Albums.VISIBILITY_PRIVATE, mAccountId); + mAlbumId = PhotoDatabaseUtils.queryAlbumIdFromParentId(db, ALBUM_PARENT_ID); + PhotoDatabaseUtils.insertPhoto(db, 100, 100, System.currentTimeMillis(), mAlbumId, + MIME_TYPE, mAccountId); + mPhotoId = PhotoDatabaseUtils.queryPhotoIdFromAlbumId(db, mAlbumId); + PhotoDatabaseUtils.insertMetadata(db, mPhotoId, META_KEY, META_VALUE); + String[] projection = { + BaseColumns._ID, + }; + Cursor cursor = db.query(Metadata.TABLE, projection, null, null, null, null, null); + cursor.moveToNext(); + mMetadataId = cursor.getLong(0); + cursor.close(); + db.setTransactionSuccessful(); + mNotifications.reset(); + } finally { + db.endTransaction(); + } + } + + @Override + protected void tearDown() throws Exception { + mDBHelper.close(); + mDBHelper = null; + super.tearDown(); + getMockContext().deleteDatabase(PhotoProvider.DB_NAME); + } + + public void testDelete() { + try { + mResolver.delete(NO_TABLE_URI, null, null); + fail("Exeption should be thrown when no table given"); + } catch (Exception e) { + // expected exception + } + try { + mResolver.delete(BAD_TABLE_URI, null, null); + fail("Exeption should be thrown when deleting from a table that doesn't exist"); + } catch (Exception e) { + // expected exception + } + + String[] selectionArgs = { + String.valueOf(mPhotoId) + }; + // Delete some metadata + assertEquals(1, + mResolver.delete(Metadata.CONTENT_URI, WHERE_METADATA_PHOTOS_ID, selectionArgs)); + Uri photoUri = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId); + assertEquals(1, mResolver.delete(photoUri, null, null)); + Uri albumUri = ContentUris.withAppendedId(Albums.CONTENT_URI, mAlbumId); + assertEquals(1, mResolver.delete(albumUri, null, null)); + // now delete something that isn't there + assertEquals(0, mResolver.delete(photoUri, null, null)); + } + + public void testDeleteMetadataId() { + Uri metadataUri = ContentUris.withAppendedId(Metadata.CONTENT_URI, mMetadataId); + assertEquals(1, mResolver.delete(metadataUri, null, null)); + Cursor cursor = mResolver.query(Metadata.CONTENT_URI, null, null, null, null); + assertEquals(0, cursor.getCount()); + cursor.close(); + } + + // Delete the album and ensure that the photos referring to the album are + // deleted. + public void testDeleteAlbumCascade() { + Uri albumUri = ContentUris.withAppendedId(Albums.CONTENT_URI, mAlbumId); + mResolver.delete(albumUri, null, null); + assertTrue(mNotifications.isNotified(Photos.CONTENT_URI)); + assertTrue(mNotifications.isNotified(Metadata.CONTENT_URI)); + assertTrue(mNotifications.isNotified(albumUri)); + assertEquals(3, mNotifications.notificationCount()); + Cursor cursor = mResolver.query(Photos.CONTENT_URI, PhotoDatabaseUtils.PROJECTION_PHOTOS, + null, null, null); + assertEquals(0, cursor.getCount()); + cursor.close(); + } + + // Delete all albums and ensure that photos in any album are deleted. + public void testDeleteAlbumCascade2() { + mResolver.delete(Albums.CONTENT_URI, null, null); + assertTrue(mNotifications.isNotified(Photos.CONTENT_URI)); + assertTrue(mNotifications.isNotified(Metadata.CONTENT_URI)); + assertTrue(mNotifications.isNotified(Albums.CONTENT_URI)); + assertEquals(3, mNotifications.notificationCount()); + Cursor cursor = mResolver.query(Photos.CONTENT_URI, PhotoDatabaseUtils.PROJECTION_PHOTOS, + null, null, null); + assertEquals(0, cursor.getCount()); + cursor.close(); + } + + // Delete a photo and ensure that the metadata for that photo are deleted. + public void testDeletePhotoCascade() { + Uri photoUri = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId); + mResolver.delete(photoUri, null, null); + assertTrue(mNotifications.isNotified(photoUri)); + assertTrue(mNotifications.isNotified(Metadata.CONTENT_URI)); + assertEquals(2, mNotifications.notificationCount()); + Cursor cursor = mResolver.query(Metadata.CONTENT_URI, + PhotoDatabaseUtils.PROJECTION_METADATA, null, null, null); + assertEquals(0, cursor.getCount()); + cursor.close(); + } + + public void testDeleteAccountCascade() { + Uri accountUri = ContentUris.withAppendedId(Accounts.CONTENT_URI, mAccountId); + SQLiteDatabase db = mDBHelper.getWritableDatabase(); + db.beginTransaction(); + PhotoDatabaseUtils.insertPhoto(db, 100, 100, System.currentTimeMillis(), null, + "image/jpeg", mAccountId); + PhotoDatabaseUtils.insertPhoto(db, 100, 100, System.currentTimeMillis(), null, + "image/jpeg", 0L); + PhotoDatabaseUtils.insertAlbum(db, null, "title", Albums.VISIBILITY_PRIVATE, 10630L); + db.setTransactionSuccessful(); + db.endTransaction(); + // ensure all pictures are there: + Cursor cursor = mResolver.query(Photos.CONTENT_URI, null, null, null, null); + assertEquals(3, cursor.getCount()); + cursor.close(); + // delete the account + assertEquals(1, mResolver.delete(accountUri, null, null)); + // now ensure that all associated photos were deleted + cursor = mResolver.query(Photos.CONTENT_URI, null, null, null, null); + assertEquals(1, cursor.getCount()); + cursor.close(); + // now ensure all associated albums were deleted. + cursor = mResolver.query(Albums.CONTENT_URI, null, null, null, null); + assertEquals(1, cursor.getCount()); + cursor.close(); + } + + public void testGetType() { + // We don't return types for albums + assertNull(mResolver.getType(Albums.CONTENT_URI)); + + Uri noImage = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId + 1); + assertNull(mResolver.getType(noImage)); + + Uri image = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId); + assertEquals(MIME_TYPE, mResolver.getType(image)); + } + + public void testInsert() { + ContentValues values = new ContentValues(); + values.put(Albums.TITLE, "add me"); + values.put(Albums.VISIBILITY, Albums.VISIBILITY_PRIVATE); + values.put(Albums.ACCOUNT_ID, 100L); + values.put(Albums.DATE_MODIFIED, 100L); + values.put(Albums.DATE_PUBLISHED, 100L); + values.put(Albums.LOCATION_STRING, "Home"); + values.put(Albums.TITLE, "hello world"); + values.putNull(Albums.PARENT_ID); + values.put(Albums.SUMMARY, "Nothing much to say about this"); + Uri insertedUri = mResolver.insert(Albums.CONTENT_URI, values); + assertNotNull(insertedUri); + Cursor cursor = mResolver.query(insertedUri, PhotoDatabaseUtils.PROJECTION_ALBUMS, null, + null, null); + assertNotNull(cursor); + assertEquals(1, cursor.getCount()); + cursor.close(); + } + + public void testUpdate() { + ContentValues values = new ContentValues(); + // Normal update -- use an album. + values.put(Albums.TITLE, "foo"); + Uri albumUri = ContentUris.withAppendedId(Albums.CONTENT_URI, mAlbumId); + assertEquals(1, mResolver.update(albumUri, values, null, null)); + String[] projection = { + Albums.TITLE, + }; + Cursor cursor = mResolver.query(albumUri, projection, null, null, null); + assertEquals(1, cursor.getCount()); + assertTrue(cursor.moveToNext()); + assertEquals("foo", cursor.getString(0)); + cursor.close(); + + // Update a row that doesn't exist. + Uri noAlbumUri = ContentUris.withAppendedId(Albums.CONTENT_URI, mAlbumId + 1); + values.put(Albums.TITLE, "bar"); + assertEquals(0, mResolver.update(noAlbumUri, values, null, null)); + + // Update a metadata value that exists. + ContentValues metadata = new ContentValues(); + metadata.put(Metadata.PHOTO_ID, mPhotoId); + metadata.put(Metadata.KEY, META_KEY); + metadata.put(Metadata.VALUE, "new value"); + assertEquals(1, mResolver.update(Metadata.CONTENT_URI, metadata, null, null)); + + projection = new String[] { + Metadata.VALUE, + }; + + String[] selectionArgs = { + String.valueOf(mPhotoId), META_KEY, + }; + + cursor = mResolver.query(Metadata.CONTENT_URI, projection, WHERE_METADATA, selectionArgs, + null); + assertEquals(1, cursor.getCount()); + assertTrue(cursor.moveToNext()); + assertEquals("new value", cursor.getString(0)); + cursor.close(); + + // Update a metadata value that doesn't exist. + metadata.put(Metadata.KEY, "other stuff"); + assertEquals(1, mResolver.update(Metadata.CONTENT_URI, metadata, null, null)); + + selectionArgs[1] = "other stuff"; + cursor = mResolver.query(Metadata.CONTENT_URI, projection, WHERE_METADATA, selectionArgs, + null); + assertEquals(1, cursor.getCount()); + assertTrue(cursor.moveToNext()); + assertEquals("new value", cursor.getString(0)); + cursor.close(); + + // Remove a metadata value using update. + metadata.putNull(Metadata.VALUE); + assertEquals(1, mResolver.update(Metadata.CONTENT_URI, metadata, null, null)); + cursor = mResolver.query(Metadata.CONTENT_URI, projection, WHERE_METADATA, selectionArgs, + null); + assertEquals(0, cursor.getCount()); + cursor.close(); + } + + public void testQuery() { + // Query a photo that exists. + Cursor cursor = mResolver.query(Photos.CONTENT_URI, PhotoDatabaseUtils.PROJECTION_PHOTOS, + null, null, null); + assertNotNull(cursor); + assertEquals(1, cursor.getCount()); + assertTrue(cursor.moveToNext()); + assertEquals(mPhotoId, cursor.getLong(0)); + cursor.close(); + + // Query a photo that doesn't exist. + Uri noPhotoUri = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId + 1); + cursor = mResolver.query(noPhotoUri, PhotoDatabaseUtils.PROJECTION_PHOTOS, null, null, + null); + assertNotNull(cursor); + assertEquals(0, cursor.getCount()); + cursor.close(); + + // Query a photo that exists using selection arguments. + String[] selectionArgs = { + String.valueOf(mPhotoId), + }; + + cursor = mResolver.query(Photos.CONTENT_URI, PhotoDatabaseUtils.PROJECTION_PHOTOS, + Photos._ID + " = ?", selectionArgs, null); + assertNotNull(cursor); + assertEquals(1, cursor.getCount()); + assertTrue(cursor.moveToNext()); + assertEquals(mPhotoId, cursor.getLong(0)); + cursor.close(); + } + + public void testUpdatePhotoNotification() { + Uri photoUri = ContentUris.withAppendedId(Photos.CONTENT_URI, mPhotoId); + ContentValues values = new ContentValues(); + values.put(Photos.MIME_TYPE, "not-a/mime-type"); + mResolver.update(photoUri, values, null, null); + assertTrue(mNotifications.isNotified(photoUri)); + } + + public void testUpdateMetadataNotification() { + ContentValues values = new ContentValues(); + values.put(Metadata.PHOTO_ID, mPhotoId); + values.put(Metadata.KEY, META_KEY); + values.put(Metadata.VALUE, "hello world"); + mResolver.update(Metadata.CONTENT_URI, values, null, null); + assertTrue(mNotifications.isNotified(Metadata.CONTENT_URI)); + } + + public void testBatchTransaction() throws RemoteException, OperationApplicationException { + ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(); + ContentProviderOperation.Builder insert = ContentProviderOperation + .newInsert(Photos.CONTENT_URI); + insert.withValue(Photos.WIDTH, 200L); + insert.withValue(Photos.HEIGHT, 100L); + insert.withValue(Photos.DATE_TAKEN, System.currentTimeMillis()); + insert.withValue(Photos.ALBUM_ID, 1000L); + insert.withValue(Photos.MIME_TYPE, "image/jpg"); + insert.withValue(Photos.ACCOUNT_ID, 1L); + operations.add(insert.build()); + ContentProviderOperation.Builder update = ContentProviderOperation.newUpdate(Photos.CONTENT_URI); + update.withValue(Photos.DATE_MODIFIED, System.currentTimeMillis()); + String[] whereArgs = { + "100", + }; + String where = Photos.WIDTH + " = ?"; + update.withSelection(where, whereArgs); + operations.add(update.build()); + ContentProviderOperation.Builder delete = ContentProviderOperation + .newDelete(Photos.CONTENT_URI); + delete.withSelection(where, whereArgs); + operations.add(delete.build()); + mResolver.applyBatch(PhotoProvider.AUTHORITY, operations); + assertEquals(3, mNotifications.notificationCount()); + SQLiteDatabase db = mDBHelper.getReadableDatabase(); + long id = PhotoDatabaseUtils.queryPhotoIdFromAlbumId(db, 1000L); + Uri uri = ContentUris.withAppendedId(Photos.CONTENT_URI, id); + assertTrue(mNotifications.isNotified(uri)); + assertTrue(mNotifications.isNotified(Metadata.CONTENT_URI)); + assertTrue(mNotifications.isNotified(Photos.CONTENT_URI)); + } + +} |