1 package uk
.me
.njae
.sunshine
;
3 import android
.annotation
.TargetApi
;
4 import android
.content
.ContentUris
;
5 import android
.content
.ContentValues
;
6 import android
.database
.Cursor
;
7 import android
.net
.Uri
;
8 import android
.os
.Build
;
9 import android
.test
.AndroidTestCase
;
10 import android
.util
.Log
;
12 import uk
.me
.njae
.sunshine
.data
.WeatherContract
.LocationEntry
;
13 import uk
.me
.njae
.sunshine
.data
.WeatherContract
.WeatherEntry
;
14 import uk
.me
.njae
.sunshine
.data
.WeatherDbHelper
;
16 public class TestProvider
extends AndroidTestCase
{
18 public static final String LOG_TAG
= TestProvider
.class.getSimpleName();
20 // brings our database to an empty state
21 public void deleteAllRecords() {
22 mContext
.getContentResolver().delete(
23 WeatherEntry
.CONTENT_URI
,
27 mContext
.getContentResolver().delete(
28 LocationEntry
.CONTENT_URI
,
33 Cursor cursor
= mContext
.getContentResolver().query(
34 WeatherEntry
.CONTENT_URI
,
40 assertEquals(0, cursor
.getCount());
43 cursor
= mContext
.getContentResolver().query(
44 LocationEntry
.CONTENT_URI
,
50 assertEquals(0, cursor
.getCount());
54 // Since we want each test to start with a clean slate, run deleteAllRecords
55 // in setUp (called by the test runner before each test).
60 public void testInsertReadProvider() {
62 // If there's an error in those massive SQL table creation Strings,
63 // errors will be thrown here when you try to get a writable database.
64 WeatherDbHelper dbHelper
= new WeatherDbHelper(mContext
);
65 // SQLiteDatabase db = dbHelper.getWritableDatabase();
67 // Create a new map of values, where column names are the keys
68 ContentValues locationTestValues
= TestDb
.createNorthPoleLocationValues();
70 Uri locationInsertUri
= mContext
.getContentResolver().insert(LocationEntry
.CONTENT_URI
, locationTestValues
);
71 assertTrue(locationInsertUri
!= null);
72 long locationRowId
= ContentUris
.parseId(locationInsertUri
);
74 Log
.d(LOG_TAG
, "New row id: " + locationRowId
);
76 // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made
79 // A cursor is your primary interface to the query results.
80 Cursor cursor
= mContext
.getContentResolver().query(
81 LocationEntry
.CONTENT_URI
, // Table to Query
83 null, // Columns for the "where" clause
84 null, // Values for the "where" clause
85 null // columns to group by
88 TestDb
.validateCursor(cursor
, locationTestValues
);
90 // Now see if we can successfully query if we include the row id
91 cursor
= mContext
.getContentResolver().query(
92 LocationEntry
.buildLocationUri(locationRowId
),
93 null, // leaving "columns" null just returns all the columns.
94 null, // cols for "where" clause
95 null, // values for "where" clause
99 TestDb
.validateCursor(cursor
, locationTestValues
);
102 // Fantastic. Now that we have a location, add some weather!
104 ContentValues weatherTestValues
= TestDb
.createWeatherValues(locationRowId
);
106 Uri weatherInsertUri
= mContext
.getContentResolver().insert(WeatherEntry
.CONTENT_URI
, weatherTestValues
);
107 assertTrue(weatherInsertUri
!= null);
109 // A cursor is your primary interface to the query results.
110 Cursor weatherCursor
= mContext
.getContentResolver().query(
111 WeatherEntry
.CONTENT_URI
, // Table to Query
112 null, // leaving "columns" null just returns all the columns.
113 null, // cols for "where" clause
114 null, // values for "where" clause
115 null // columns to group by
118 TestDb
.validateCursor(weatherCursor
, weatherTestValues
);
121 // Add the location values in with the weather data so that we can make
122 // sure that the join worked and we actually get all the values back
123 addAllContentValues(weatherTestValues
, locationTestValues
);
125 // Get the joined Weather and Location data
126 weatherCursor
= mContext
.getContentResolver().query(
127 WeatherEntry
.buildWeatherLocation(TestDb
.TEST_LOCATION
),
128 null, // leaving "columns" null just returns all the columns.
129 null, // cols for "where" clause
130 null, // values for "where" clause
133 TestDb
.validateCursor(weatherCursor
, weatherTestValues
);
135 // Get the joined Weather and Location data with a start date
136 weatherCursor
= mContext
.getContentResolver().query(
137 WeatherEntry
.buildWeatherLocationWithStartDate(
138 TestDb
.TEST_LOCATION
, TestDb
.TEST_DATE
),
139 null, // leaving "columns" null just returns all the columns.
140 null, // cols for "where" clause
141 null, // values for "where" clause
144 TestDb
.validateCursor(weatherCursor
, weatherTestValues
);
146 // Get the joined Weather data for a specific date
147 weatherCursor
= mContext
.getContentResolver().query(
148 WeatherEntry
.buildWeatherLocationWithDate(TestDb
.TEST_LOCATION
, TestDb
.TEST_DATE
),
154 TestDb
.validateCursor(weatherCursor
, weatherTestValues
);
159 public void testGetType() {
160 // content://uk.me.njae.sunshine/weather/
161 String type
= mContext
.getContentResolver().getType(WeatherEntry
.CONTENT_URI
);
162 // vnd.android.cursor.dir/uk.me.njae.sunshine/weather
163 assertEquals(WeatherEntry
.CONTENT_TYPE
, type
);
165 String testLocation
= "94074";
166 // content://uk.me.njae.sunshine/weather/94074
167 type
= mContext
.getContentResolver().getType(
168 WeatherEntry
.buildWeatherLocation(testLocation
));
169 // vnd.android.cursor.dir/uk.me.njae.sunshine/weather
170 assertEquals(WeatherEntry
.CONTENT_TYPE
, type
);
172 String testDate
= "20140612";
173 // content://uk.me.njae.sunshine/weather/94074/20140612
174 type
= mContext
.getContentResolver().getType(
175 WeatherEntry
.buildWeatherLocationWithDate(testLocation
, testDate
));
176 // vnd.android.cursor.item/uk.me.njae.sunshine/weather
177 assertEquals(WeatherEntry
.CONTENT_ITEM_TYPE
, type
);
179 // content://uk.me.njae.sunshine/location/
180 type
= mContext
.getContentResolver().getType(LocationEntry
.CONTENT_URI
);
181 // vnd.android.cursor.dir/uk.me.njae.sunshine/location
182 assertEquals(LocationEntry
.CONTENT_TYPE
, type
);
184 // content://uk.me.njae.sunshine/location/1
185 type
= mContext
.getContentResolver().getType(LocationEntry
.buildLocationUri(1L));
186 // vnd.android.cursor.item/uk.me.njae.sunshine/location
187 assertEquals(LocationEntry
.CONTENT_ITEM_TYPE
, type
);
190 public void testUpdateLocation() {
191 // Create a new map of values, where column names are the keys
192 ContentValues values
= TestDb
.createNorthPoleLocationValues();
194 Uri locationUri
= mContext
.getContentResolver().
195 insert(LocationEntry
.CONTENT_URI
, values
);
196 long locationRowId
= ContentUris
.parseId(locationUri
);
198 // Verify we got a row back.
199 assertTrue(locationRowId
!= -1);
200 Log
.d(LOG_TAG
, "New row id: " + locationRowId
);
202 ContentValues updatedValues
= new ContentValues(values
);
203 updatedValues
.put(LocationEntry
._ID
, locationRowId
);
204 updatedValues
.put(LocationEntry
.COLUMN_CITY_NAME
, "Santa's Village");
206 int count
= mContext
.getContentResolver().update(
207 LocationEntry
.CONTENT_URI
, updatedValues
, LocationEntry
._ID
+ "= ?",
208 new String
[] { Long
.toString(locationRowId
)});
210 assertEquals(count
, 1);
212 // A cursor is your primary interface to the query results.
213 Cursor cursor
= mContext
.getContentResolver().query(
214 LocationEntry
.buildLocationUri(locationRowId
),
216 null, // Columns for the "where" clause
217 null, // Values for the "where" clause
221 TestDb
.validateCursor(cursor
, updatedValues
);
224 // Make sure we can still delete after adding/updating stuff
225 public void testDeleteRecordsAtEnd() {
231 // The target api annotation is needed for the call to keySet -- we wouldn't want
232 // to use this in our app, but in a test it's fine to assume a higher target.
233 @TargetApi(Build
.VERSION_CODES
.HONEYCOMB
)
234 void addAllContentValues(ContentValues destination
, ContentValues source
) {
235 for (String key
: source
.keySet()) {
236 destination
.put(key
, source
.getAsString(key
));