--- /dev/null
+package uk.me.njae.sunshine;
+
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import uk.me.njae.sunshine.data.WeatherContract.LocationEntry;
+import uk.me.njae.sunshine.data.WeatherContract.WeatherEntry;
+import uk.me.njae.sunshine.data.WeatherDbHelper;
+
+public class TestProvider extends AndroidTestCase {
+
+ public static final String LOG_TAG = TestProvider.class.getSimpleName();
+
+ // brings our database to an empty state
+ public void deleteAllRecords() {
+ mContext.getContentResolver().delete(
+ WeatherEntry.CONTENT_URI,
+ null,
+ null
+ );
+ mContext.getContentResolver().delete(
+ LocationEntry.CONTENT_URI,
+ null,
+ null
+ );
+
+ Cursor cursor = mContext.getContentResolver().query(
+ WeatherEntry.CONTENT_URI,
+ null,
+ null,
+ null,
+ null
+ );
+ assertEquals(0, cursor.getCount());
+ cursor.close();
+
+ cursor = mContext.getContentResolver().query(
+ LocationEntry.CONTENT_URI,
+ null,
+ null,
+ null,
+ null
+ );
+ assertEquals(0, cursor.getCount());
+ cursor.close();
+ }
+
+ // Since we want each test to start with a clean slate, run deleteAllRecords
+ // in setUp (called by the test runner before each test).
+ public void setUp() {
+ deleteAllRecords();
+ }
+
+ public void testInsertReadProvider() {
+
+ // If there's an error in those massive SQL table creation Strings,
+ // errors will be thrown here when you try to get a writable database.
+ WeatherDbHelper dbHelper = new WeatherDbHelper(mContext);
+ // SQLiteDatabase db = dbHelper.getWritableDatabase();
+
+ // Create a new map of values, where column names are the keys
+ ContentValues locationTestValues = TestDb.createNorthPoleLocationValues();
+
+ Uri locationInsertUri = mContext.getContentResolver().insert(LocationEntry.CONTENT_URI, locationTestValues);
+ assertTrue(locationInsertUri != null);
+ long locationRowId = ContentUris.parseId(locationInsertUri);
+
+ Log.d(LOG_TAG, "New row id: " + locationRowId);
+
+ // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made
+ // the round trip.
+
+ // A cursor is your primary interface to the query results.
+ Cursor cursor = mContext.getContentResolver().query(
+ LocationEntry.CONTENT_URI, // Table to Query
+ null, // All columns
+ null, // Columns for the "where" clause
+ null, // Values for the "where" clause
+ null // columns to group by
+ );
+
+ TestDb.validateCursor(cursor, locationTestValues);
+
+ // Now see if we can successfully query if we include the row id
+ cursor = mContext.getContentResolver().query(
+ LocationEntry.buildLocationUri(locationRowId),
+ null, // leaving "columns" null just returns all the columns.
+ null, // cols for "where" clause
+ null, // values for "where" clause
+ null // sort order
+ );
+
+ TestDb.validateCursor(cursor, locationTestValues);
+
+
+ // Fantastic. Now that we have a location, add some weather!
+
+ ContentValues weatherTestValues = TestDb.createWeatherValues(locationRowId);
+
+ Uri weatherInsertUri = mContext.getContentResolver().insert(WeatherEntry.CONTENT_URI, weatherTestValues);
+ assertTrue(weatherInsertUri != null);
+
+ // A cursor is your primary interface to the query results.
+ Cursor weatherCursor = mContext.getContentResolver().query(
+ WeatherEntry.CONTENT_URI, // Table to Query
+ null, // leaving "columns" null just returns all the columns.
+ null, // cols for "where" clause
+ null, // values for "where" clause
+ null // columns to group by
+ );
+
+ TestDb.validateCursor(weatherCursor, weatherTestValues);
+
+
+ // Add the location values in with the weather data so that we can make
+ // sure that the join worked and we actually get all the values back
+ addAllContentValues(weatherTestValues, locationTestValues);
+
+ // Get the joined Weather and Location data
+ weatherCursor = mContext.getContentResolver().query(
+ WeatherEntry.buildWeatherLocation(TestDb.TEST_LOCATION),
+ null, // leaving "columns" null just returns all the columns.
+ null, // cols for "where" clause
+ null, // values for "where" clause
+ null // sort order
+ );
+ TestDb.validateCursor(weatherCursor, weatherTestValues);
+
+ // Get the joined Weather and Location data with a start date
+ weatherCursor = mContext.getContentResolver().query(
+ WeatherEntry.buildWeatherLocationWithStartDate(
+ TestDb.TEST_LOCATION, TestDb.TEST_DATE),
+ null, // leaving "columns" null just returns all the columns.
+ null, // cols for "where" clause
+ null, // values for "where" clause
+ null // sort order
+ );
+ TestDb.validateCursor(weatherCursor, weatherTestValues);
+
+ // Get the joined Weather data for a specific date
+ weatherCursor = mContext.getContentResolver().query(
+ WeatherEntry.buildWeatherLocationWithDate(TestDb.TEST_LOCATION, TestDb.TEST_DATE),
+ null,
+ null,
+ null,
+ null
+ );
+ TestDb.validateCursor(weatherCursor, weatherTestValues);
+
+ dbHelper.close();
+ }
+
+ public void testGetType() {
+ // content://uk.me.njae.sunshine/weather/
+ String type = mContext.getContentResolver().getType(WeatherEntry.CONTENT_URI);
+ // vnd.android.cursor.dir/uk.me.njae.sunshine/weather
+ assertEquals(WeatherEntry.CONTENT_TYPE, type);
+
+ String testLocation = "94074";
+ // content://uk.me.njae.sunshine/weather/94074
+ type = mContext.getContentResolver().getType(
+ WeatherEntry.buildWeatherLocation(testLocation));
+ // vnd.android.cursor.dir/uk.me.njae.sunshine/weather
+ assertEquals(WeatherEntry.CONTENT_TYPE, type);
+
+ String testDate = "20140612";
+ // content://uk.me.njae.sunshine/weather/94074/20140612
+ type = mContext.getContentResolver().getType(
+ WeatherEntry.buildWeatherLocationWithDate(testLocation, testDate));
+ // vnd.android.cursor.item/uk.me.njae.sunshine/weather
+ assertEquals(WeatherEntry.CONTENT_ITEM_TYPE, type);
+
+ // content://uk.me.njae.sunshine/location/
+ type = mContext.getContentResolver().getType(LocationEntry.CONTENT_URI);
+ // vnd.android.cursor.dir/uk.me.njae.sunshine/location
+ assertEquals(LocationEntry.CONTENT_TYPE, type);
+
+ // content://uk.me.njae.sunshine/location/1
+ type = mContext.getContentResolver().getType(LocationEntry.buildLocationUri(1L));
+ // vnd.android.cursor.item/uk.me.njae.sunshine/location
+ assertEquals(LocationEntry.CONTENT_ITEM_TYPE, type);
+ }
+
+ public void testUpdateLocation() {
+ // Create a new map of values, where column names are the keys
+ ContentValues values = TestDb.createNorthPoleLocationValues();
+
+ Uri locationUri = mContext.getContentResolver().
+ insert(LocationEntry.CONTENT_URI, values);
+ long locationRowId = ContentUris.parseId(locationUri);
+
+ // Verify we got a row back.
+ assertTrue(locationRowId != -1);
+ Log.d(LOG_TAG, "New row id: " + locationRowId);
+
+ ContentValues updatedValues = new ContentValues(values);
+ updatedValues.put(LocationEntry._ID, locationRowId);
+ updatedValues.put(LocationEntry.COLUMN_CITY_NAME, "Santa's Village");
+
+ int count = mContext.getContentResolver().update(
+ LocationEntry.CONTENT_URI, updatedValues, LocationEntry._ID + "= ?",
+ new String[] { Long.toString(locationRowId)});
+
+ assertEquals(count, 1);
+
+ // A cursor is your primary interface to the query results.
+ Cursor cursor = mContext.getContentResolver().query(
+ LocationEntry.buildLocationUri(locationRowId),
+ null,
+ null, // Columns for the "where" clause
+ null, // Values for the "where" clause
+ null // sort order
+ );
+
+ TestDb.validateCursor(cursor, updatedValues);
+ }
+
+ // Make sure we can still delete after adding/updating stuff
+ public void testDeleteRecordsAtEnd() {
+ deleteAllRecords();
+ }
+
+
+
+ // The target api annotation is needed for the call to keySet -- we wouldn't want
+ // to use this in our app, but in a test it's fine to assume a higher target.
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ void addAllContentValues(ContentValues destination, ContentValues source) {
+ for (String key : source.keySet()) {
+ destination.put(key, source.getAsString(key));
+ }
+ }
+}