package com.truckmuncher.app.data; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.truckmuncher.app.data.sql.SqlOpenHelper; import com.truckmuncher.app.data.sql.Tables; import com.truckmuncher.app.data.sql.WhereClause; import com.truckmuncher.testlib.ReadableRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.shadows.ShadowContentResolver; import static com.truckmuncher.app.data.sql.WhereClause.Operator.EQUALS; import static org.assertj.core.api.Assertions.assertThat; @RunWith(ReadableRobolectricTestRunner.class) public class TruckMuncherContentProviderTest { private ContentResolver resolver; @Before public void setUp() { ContentProvider provider = new TruckMuncherContentProvider(); provider.onCreate(); ShadowContentResolver.registerProvider(PublicContract.CONTENT_AUTHORITY, provider); resolver = Robolectric.application.getContentResolver(); } @Test public void queryCategoryHitsCategoryTable() { // Populate some data ContentValues values = new ContentValues(); values.put(PublicContract.Category.NAME, "Sandwiches"); SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.CATEGORY, null, values); // Make sure we got our data Cursor cursor = resolver.query(PublicContract.CATEGORY_URI, new String[]{PublicContract.Category.NAME}, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); // Verifies the behavior because the rest of the database is empty assertThat(cursor.getColumnCount()).isEqualTo(1); // Verifies that the projection is respected // Make sure selection is respected WhereClause whereClause = new WhereClause.Builder() .where(PublicContract.Category.NAME, EQUALS, "Soups") .build(); cursor = resolver.query(PublicContract.CATEGORY_URI, null, whereClause.selection, whereClause.selectionArgs, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isZero(); } @Test public void queryMenuItemHitsMenuItemTable() { // Populate some data ContentValues values = new ContentValues(); values.put(PublicContract.MenuItem.NAME, "BLT"); SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.MENU_ITEM, null, values); // Make sure we got our data Cursor cursor = resolver.query(PublicContract.MENU_ITEM_URI, new String[]{PublicContract.MenuItem.NAME}, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); // Verifies the behavior because the rest of the database is empty assertThat(cursor.getColumnCount()).isEqualTo(1); // Verifies that the projection is respected // Make sure selection is respected WhereClause whereClause = new WhereClause.Builder() .where(PublicContract.MenuItem.NAME, EQUALS, "Turkey") .build(); cursor = resolver.query(PublicContract.MENU_ITEM_URI, null, whereClause.selection, whereClause.selectionArgs, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isZero(); } @Test public void queryTruckHitsTruckView() { SQLiteDatabase db = SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase(); // Populate some data ContentValues values = new ContentValues(); values.put(PublicContract.Truck.ID, "Truck_1"); values.put(PublicContract.Truck.NAME, "The Sandwich Makers"); db.insert(Tables.TRUCK_PROPERTIES, null, values); ContentValues stateValues = new ContentValues(); stateValues.put(PublicContract.Truck.ID, "Truck_1"); stateValues.put(PublicContract.Truck.IS_SERVING, true); db.insert(Tables.TRUCK_STATE, null, stateValues); // Make sure we got our data WhereClause whereClause = new WhereClause.Builder() .where(PublicContract.Truck.NAME, EQUALS, "The Sandwich Makers") .where(PublicContract.Truck.IS_SERVING, EQUALS, true) .build(); String[] projection = new String[]{PublicContract.Truck.NAME}; Cursor cursor = resolver.query(PublicContract.TRUCK_URI, projection, whereClause.selection, whereClause.selectionArgs, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); // Verifies the behavior because only the view has both of those columns assertThat(cursor.getColumnCount()).isEqualTo(1); // Verifies that the projection is respected } @Test public void queryTruckStateHitsTruckStateTable() { // Populate some data ContentValues values = new ContentValues(); values.put(Contract.TruckState.IS_DIRTY, true); SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.TRUCK_STATE, null, values); // Make sure we got our data Cursor cursor = resolver.query(Contract.TRUCK_STATE_URI, new String[]{Contract.TruckState.IS_DIRTY}, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); // Verifies the behavior because the rest of the database is empty assertThat(cursor.getColumnCount()).isEqualTo(1); // Verifies that the projection is respected // Make sure selection is respected WhereClause whereClause = new WhereClause.Builder() .where(Contract.TruckState.IS_DIRTY, EQUALS, false) .build(); cursor = resolver.query(Contract.TRUCK_STATE_URI, null, whereClause.selection, whereClause.selectionArgs, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isZero(); } @Test public void queryMenuHitsMenuView() { SQLiteDatabase db = SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase(); // Populate some data ContentValues truckValues = new ContentValues(); truckValues.put(PublicContract.Truck.ID, "Truck_1"); db.insert(Tables.TRUCK_PROPERTIES, null, truckValues); ContentValues categoryValues = new ContentValues(); categoryValues.put(PublicContract.Category.NAME, "Sandwiches"); categoryValues.put(PublicContract.Category.ID, "Category_1"); categoryValues.put(PublicContract.Category.TRUCK_ID, "Truck_1"); db.insert(Tables.CATEGORY, null, categoryValues); ContentValues itemValues = new ContentValues(); itemValues.put(PublicContract.MenuItem.NAME, "BLT"); itemValues.put(PublicContract.MenuItem.CATEGORY_ID, "Category_1"); db.insert(Tables.MENU_ITEM, null, itemValues); // Make sure we got our data WhereClause whereClause = new WhereClause.Builder() .where(PublicContract.Menu.CATEGORY_NAME, EQUALS, "Sandwiches") .where(PublicContract.Menu.MENU_ITEM_NAME, EQUALS, "BLT") .build(); String[] projection = new String[]{PublicContract.Menu.CATEGORY_NAME}; Cursor cursor = resolver.query(PublicContract.MENU_URI, projection, whereClause.selection, whereClause.selectionArgs, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); // Verifies the behavior because only the view has both of those columns assertThat(cursor.getColumnCount()).isEqualTo(1); // Verifies that the projection is respected } @Test public void getTypeWorksForKnownUris() { String type; // Category type = resolver.getType(PublicContract.CATEGORY_URI); assertThat(type).isEqualTo(PublicContract.URI_TYPE_CATEGORY); // Menu Item type = resolver.getType(PublicContract.MENU_ITEM_URI); assertThat(type).isEqualTo(PublicContract.URI_TYPE_MENU_ITEM); // Truck type = resolver.getType(PublicContract.TRUCK_URI); assertThat(type).isEqualTo(PublicContract.URI_TYPE_TRUCK); // Menu type = resolver.getType(PublicContract.MENU_URI); assertThat(type).isEqualTo(PublicContract.URI_TYPE_MENU); } @Test(expected = UnsupportedOperationException.class) public void insertThrowsUnsupportedOperationException() { resolver.insert(PublicContract.CATEGORY_URI, null); } @Test public void deleteTruckStateHitsTruckStateTable() { // Populate some data queryTruckStateHitsTruckStateTable(); // Make sure the selection is respected WhereClause whereClause = new WhereClause.Builder() .where(Contract.TruckState.IS_DIRTY, EQUALS, false) .build(); int deletedCount = resolver.delete(Contract.TRUCK_STATE_URI, whereClause.selection, whereClause.selectionArgs); assertThat(deletedCount).isZero(); // Make sure it gets deleted whereClause = new WhereClause.Builder() .where(Contract.TruckState.IS_DIRTY, EQUALS, true) .build(); deletedCount = resolver.delete(Contract.TRUCK_STATE_URI, whereClause.selection, whereClause.selectionArgs); assertThat(deletedCount).isEqualTo(1); } @Test public void updateTruckStateHitsTruckStateTable() { // Populate some data queryTruckStateHitsTruckStateTable(); ContentValues values = new ContentValues(); values.put(PublicContract.Truck.ID, "The Sandwich Makers"); // Make sure the selection is respected WhereClause whereClause = new WhereClause.Builder() .where(Contract.TruckState.IS_DIRTY, EQUALS, false) .build(); int updatedCount = resolver.update(Contract.TRUCK_STATE_URI, values, whereClause.selection, whereClause.selectionArgs); assertThat(updatedCount).isZero(); // Make sure the right table is hit updatedCount = resolver.update(Contract.TRUCK_STATE_URI, values, null, null); assertThat(updatedCount).isEqualTo(1); } @Test public void bulkInsertMenuItemAddsNewData() { ContentValues blt = new ContentValues(); blt.put(PublicContract.MenuItem.ID, "BLT"); ContentValues turkey = new ContentValues(); turkey.put(PublicContract.MenuItem.ID, "Turkey"); ContentValues[] valuesList = new ContentValues[]{blt, turkey}; int inserted = resolver.bulkInsert(PublicContract.MENU_ITEM_URI, valuesList); assertThat(inserted).isEqualTo(2); } @Test public void bulkInsertMenuItemUpdatesOldData() { // Add some "existing" mock data ContentValues existing = new ContentValues(); existing.put(PublicContract.MenuItem.ID, "BLT"); existing.put(PublicContract.MenuItem.PRICE, 5.99); assertThat(SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.MENU_ITEM, null, existing)).isEqualTo(1); // Update the mock data ContentValues updated = new ContentValues(); updated.put(PublicContract.MenuItem.ID, "BLT"); updated.put(PublicContract.MenuItem.PRICE, 6.99); int inserted = resolver.bulkInsert(PublicContract.MENU_ITEM_URI, new ContentValues[]{updated}); assertThat(inserted).isEqualTo(1); // Verify that the mock data indeed exists Cursor cursor = resolver.query(PublicContract.MENU_ITEM_URI, null, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); cursor.moveToFirst(); assertThat(cursor.getString(cursor.getColumnIndex(PublicContract.MenuItem.ID))).isEqualTo("BLT"); assertThat(cursor.getDouble(cursor.getColumnIndex(PublicContract.MenuItem.PRICE))).isEqualTo(6.99); } @Test public void bulkInsertCategoryAddsNewData() { ContentValues sandwiches = new ContentValues(); sandwiches.put(PublicContract.Category.ID, "Sandwiches"); ContentValues soups = new ContentValues(); soups.put(PublicContract.Category.ID, "Soups"); ContentValues[] valuesList = new ContentValues[]{sandwiches, soups}; int inserted = resolver.bulkInsert(PublicContract.CATEGORY_URI, valuesList); assertThat(inserted).isEqualTo(2); } @Test public void bulkInsertCategoryUpdatesOldData() { // Add some "existing" mock data ContentValues existing = new ContentValues(); existing.put(PublicContract.Category.ID, "Sandwiches"); existing.put(PublicContract.Category.ORDER_IN_MENU, 1); assertThat(SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.CATEGORY, null, existing)).isEqualTo(1); // Update the mock data ContentValues updated = new ContentValues(); updated.put(PublicContract.Category.ID, "Sandwiches"); updated.put(PublicContract.Category.ORDER_IN_MENU, 2); int inserted = resolver.bulkInsert(PublicContract.CATEGORY_URI, new ContentValues[]{updated}); assertThat(inserted).isEqualTo(1); // Verify that the mock data indeed exists Cursor cursor = resolver.query(PublicContract.CATEGORY_URI, null, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); cursor.moveToFirst(); assertThat(cursor.getString(cursor.getColumnIndex(PublicContract.Category.ID))).isEqualTo("Sandwiches"); assertThat(cursor.getInt(cursor.getColumnIndex(PublicContract.Category.ORDER_IN_MENU))).isEqualTo(2); } @Test public void bulkInsertTruckStateAddsNewData() { ContentValues sandwich = new ContentValues(); sandwich.put(PublicContract.Truck.ID, "The Sandwich Makers"); ContentValues soup = new ContentValues(); soup.put(PublicContract.Truck.ID, "The Soup Makers"); ContentValues[] valuesList = new ContentValues[]{sandwich, soup}; int inserted = resolver.bulkInsert(Contract.TRUCK_STATE_URI, valuesList); assertThat(inserted).isEqualTo(2); } @Test public void bulkInsertTruckStateUpdatesOldData() { // Add some "existing" mock data ContentValues existing = new ContentValues(); existing.put(PublicContract.Truck.IS_SERVING, true); existing.put(PublicContract.Truck.ID, "The Sandwich Makers"); assertThat(SqlOpenHelper.newInstance(Robolectric.application).getWritableDatabase().insert(Tables.TRUCK_STATE, null, existing)).isEqualTo(1); // Update the mock data ContentValues updated = new ContentValues(); updated.put(PublicContract.Truck.ID, "The Sandwich Makers"); updated.put(PublicContract.Truck.IS_SERVING, false); int inserted = resolver.bulkInsert(Contract.TRUCK_STATE_URI, new ContentValues[]{updated}); assertThat(inserted).isEqualTo(1); // Verify that the mock data indeed exists Cursor cursor = resolver.query(Contract.TRUCK_STATE_URI, null, null, null, null); assertThat(cursor).isNotNull(); assertThat(cursor.getCount()).isEqualTo(1); cursor.moveToFirst(); assertThat(cursor.getString(cursor.getColumnIndex(PublicContract.Truck.ID))).isEqualTo("The Sandwich Makers"); assertThat(cursor.getInt(cursor.getColumnIndex(PublicContract.Truck.IS_SERVING)) == 1).isFalse(); } }