1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/tests/testBrowserProvider.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1859 @@ 1.4 +package org.mozilla.gecko.tests; 1.5 + 1.6 +import java.util.ArrayList; 1.7 +import java.util.Random; 1.8 + 1.9 +import org.mozilla.gecko.db.BrowserContract; 1.10 + 1.11 +import android.content.ContentProviderOperation; 1.12 +import android.content.ContentProviderResult; 1.13 +import android.content.ContentUris; 1.14 +import android.content.ContentValues; 1.15 +import android.content.OperationApplicationException; 1.16 +import android.database.Cursor; 1.17 +import android.net.Uri; 1.18 +import android.os.Build; 1.19 +import android.util.Log; 1.20 + 1.21 +/* 1.22 + * This test is meant to exercise all operations exposed by Fennec's 1.23 + * history and bookmarks content provider. It does so in an isolated 1.24 + * environment (see ContentProviderTest) without affecting any UI-related 1.25 + * code. 1.26 + */ 1.27 +public class testBrowserProvider extends ContentProviderTest { 1.28 + private long mMobileFolderId; 1.29 + 1.30 + private void loadMobileFolderId() throws Exception { 1.31 + Cursor c = null; 1.32 + try { 1.33 + c = getBookmarkByGuid(BrowserContract.Bookmarks.MOBILE_FOLDER_GUID); 1.34 + mAsserter.is(c.moveToFirst(), true, "Mobile bookmarks folder is present"); 1.35 + 1.36 + mMobileFolderId = c.getLong(c.getColumnIndex(BrowserContract.Bookmarks._ID)); 1.37 + } finally { 1.38 + if (c != null) { 1.39 + c.close(); 1.40 + } 1.41 + } 1.42 + } 1.43 + 1.44 + private void ensureEmptyDatabase() throws Exception { 1.45 + Cursor c = null; 1.46 + 1.47 + String guid = BrowserContract.Bookmarks.GUID; 1.48 + 1.49 + mProvider.delete(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), 1.50 + guid + " != ? AND " + 1.51 + guid + " != ? AND " + 1.52 + guid + " != ? AND " + 1.53 + guid + " != ? AND " + 1.54 + guid + " != ? AND " + 1.55 + guid + " != ? AND " + 1.56 + guid + " != ?", 1.57 + new String[] { BrowserContract.Bookmarks.PLACES_FOLDER_GUID, 1.58 + BrowserContract.Bookmarks.MOBILE_FOLDER_GUID, 1.59 + BrowserContract.Bookmarks.MENU_FOLDER_GUID, 1.60 + BrowserContract.Bookmarks.TAGS_FOLDER_GUID, 1.61 + BrowserContract.Bookmarks.TOOLBAR_FOLDER_GUID, 1.62 + BrowserContract.Bookmarks.UNFILED_FOLDER_GUID, 1.63 + BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID }); 1.64 + 1.65 + c = mProvider.query(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), null, null, null, null); 1.66 + assertCountIsAndClose(c, 7, "All non-special bookmarks and folders were deleted"); 1.67 + 1.68 + mProvider.delete(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), null, null); 1.69 + c = mProvider.query(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), null, null, null, null); 1.70 + assertCountIsAndClose(c, 0, "All history entries were deleted"); 1.71 + 1.72 + /** 1.73 + * There's no reason why the following two parts should fail. 1.74 + * But sometimes they do, and I'm not going to spend the time 1.75 + * to figure out why in an unrelated bug. 1.76 + */ 1.77 + 1.78 + mProvider.delete(appendUriParam(BrowserContract.Favicons.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), null, null); 1.79 + c = mProvider.query(appendUriParam(BrowserContract.Favicons.CONTENT_URI, 1.80 + BrowserContract.PARAM_SHOW_DELETED, "1"), 1.81 + null, null, null, null); 1.82 + 1.83 + if (c.getCount() > 0) { 1.84 + mAsserter.dumpLog("Unexpected favicons in ensureEmptyDatabase."); 1.85 + } 1.86 + c.close(); 1.87 + 1.88 + mAsserter.dumpLog("ensureEmptyDatabase: Favicon deletion completed."); // Bug 968951 debug. 1.89 + // assertCountIsAndClose(c, 0, "All favicons were deleted"); 1.90 + 1.91 + mProvider.delete(appendUriParam(BrowserContract.Thumbnails.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), null, null); 1.92 + c = mProvider.query(appendUriParam(BrowserContract.Thumbnails.CONTENT_URI, 1.93 + BrowserContract.PARAM_SHOW_DELETED, "1"), 1.94 + null, null, null, null); 1.95 + 1.96 + if (c.getCount() > 0) { 1.97 + mAsserter.dumpLog("Unexpected thumbnails in ensureEmptyDatabase."); 1.98 + } 1.99 + c.close(); 1.100 + 1.101 + mAsserter.dumpLog("ensureEmptyDatabase: Thumbnail deletion completed."); // Bug 968951 debug. 1.102 + // assertCountIsAndClose(c, 0, "All thumbnails were deleted"); 1.103 + } 1.104 + 1.105 + private ContentValues createBookmark(String title, String url, long parentId, 1.106 + int type, int position, String tags, String description, String keyword) throws Exception { 1.107 + ContentValues bookmark = new ContentValues(); 1.108 + 1.109 + bookmark.put(BrowserContract.Bookmarks.TITLE, title); 1.110 + bookmark.put(BrowserContract.Bookmarks.URL, url); 1.111 + bookmark.put(BrowserContract.Bookmarks.PARENT, parentId); 1.112 + bookmark.put(BrowserContract.Bookmarks.TYPE, type); 1.113 + bookmark.put(BrowserContract.Bookmarks.POSITION, position); 1.114 + bookmark.put(BrowserContract.Bookmarks.TAGS, tags); 1.115 + bookmark.put(BrowserContract.Bookmarks.DESCRIPTION, description); 1.116 + bookmark.put(BrowserContract.Bookmarks.KEYWORD, keyword); 1.117 + 1.118 + return bookmark; 1.119 + } 1.120 + 1.121 + private ContentValues createOneBookmark() throws Exception { 1.122 + return createBookmark("Example", "http://example.com", mMobileFolderId, 1.123 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.124 + } 1.125 + 1.126 + private Cursor getBookmarksByParent(long parent) throws Exception { 1.127 + // Order by position. 1.128 + return mProvider.query(BrowserContract.Bookmarks.CONTENT_URI, null, 1.129 + BrowserContract.Bookmarks.PARENT + " = ?", 1.130 + new String[] { String.valueOf(parent) }, 1.131 + BrowserContract.Bookmarks.POSITION); 1.132 + } 1.133 + 1.134 + private Cursor getBookmarkByGuid(String guid) throws Exception { 1.135 + return mProvider.query(BrowserContract.Bookmarks.CONTENT_URI, null, 1.136 + BrowserContract.Bookmarks.GUID + " = ?", 1.137 + new String[] { guid }, 1.138 + null); 1.139 + } 1.140 + 1.141 + private Cursor getBookmarkById(long id) throws Exception { 1.142 + return getBookmarkById(BrowserContract.Bookmarks.CONTENT_URI, id, null); 1.143 + } 1.144 + 1.145 + private Cursor getBookmarkById(long id, String[] projection) throws Exception { 1.146 + return getBookmarkById(BrowserContract.Bookmarks.CONTENT_URI, id, projection); 1.147 + } 1.148 + 1.149 + private Cursor getBookmarkById(Uri bookmarksUri, long id) throws Exception { 1.150 + return getBookmarkById(bookmarksUri, id, null); 1.151 + } 1.152 + 1.153 + private Cursor getBookmarkById(Uri bookmarksUri, long id, String[] projection) throws Exception { 1.154 + return mProvider.query(bookmarksUri, projection, 1.155 + BrowserContract.Bookmarks._ID + " = ?", 1.156 + new String[] { String.valueOf(id) }, 1.157 + null); 1.158 + } 1.159 + 1.160 + private ContentValues createHistoryEntry(String title, String url, int visits, long lastVisited) throws Exception { 1.161 + ContentValues historyEntry = new ContentValues(); 1.162 + 1.163 + historyEntry.put(BrowserContract.History.TITLE, title); 1.164 + historyEntry.put(BrowserContract.History.URL, url); 1.165 + historyEntry.put(BrowserContract.History.VISITS, visits); 1.166 + historyEntry.put(BrowserContract.History.DATE_LAST_VISITED, lastVisited); 1.167 + 1.168 + return historyEntry; 1.169 + } 1.170 + 1.171 + private ContentValues createFaviconEntry(String pageUrl, String data) throws Exception { 1.172 + ContentValues faviconEntry = new ContentValues(); 1.173 + 1.174 + faviconEntry.put(BrowserContract.Favicons.PAGE_URL, pageUrl); 1.175 + faviconEntry.put(BrowserContract.Favicons.URL, pageUrl + "/favicon.ico"); 1.176 + faviconEntry.put(BrowserContract.Favicons.DATA, data.getBytes("UTF8")); 1.177 + 1.178 + return faviconEntry; 1.179 + } 1.180 + 1.181 + private ContentValues createThumbnailEntry(String pageUrl, String data) throws Exception { 1.182 + ContentValues thumbnailEntry = new ContentValues(); 1.183 + 1.184 + thumbnailEntry.put(BrowserContract.Thumbnails.URL, pageUrl); 1.185 + thumbnailEntry.put(BrowserContract.Thumbnails.DATA, data.getBytes("UTF8")); 1.186 + 1.187 + return thumbnailEntry; 1.188 + } 1.189 + 1.190 + private ContentValues createOneHistoryEntry() throws Exception { 1.191 + return createHistoryEntry("Example", "http://example.com", 10, System.currentTimeMillis()); 1.192 + } 1.193 + 1.194 + private Cursor getHistoryEntryById(long id) throws Exception { 1.195 + return getHistoryEntryById(BrowserContract.History.CONTENT_URI, id, null); 1.196 + } 1.197 + 1.198 + private Cursor getHistoryEntryById(long id, String[] projection) throws Exception { 1.199 + return getHistoryEntryById(BrowserContract.History.CONTENT_URI, id, projection); 1.200 + } 1.201 + 1.202 + private Cursor getHistoryEntryById(Uri historyUri, long id) throws Exception { 1.203 + return getHistoryEntryById(historyUri, id, null); 1.204 + } 1.205 + 1.206 + private Cursor getHistoryEntryById(Uri historyUri, long id, String[] projection) throws Exception { 1.207 + return mProvider.query(historyUri, projection, 1.208 + BrowserContract.History._ID + " = ?", 1.209 + new String[] { String.valueOf(id) }, 1.210 + null); 1.211 + } 1.212 + 1.213 + private Cursor getFaviconsByUrl(String url) throws Exception { 1.214 + return mProvider.query(BrowserContract.Combined.CONTENT_URI, null, 1.215 + BrowserContract.Combined.URL + " = ?", 1.216 + new String[] { url }, 1.217 + null); 1.218 + } 1.219 + 1.220 + private Cursor getThumbnailByUrl(String url) throws Exception { 1.221 + return mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, 1.222 + BrowserContract.Thumbnails.URL + " = ?", 1.223 + new String[] { url }, 1.224 + null); 1.225 + } 1.226 + 1.227 + @Override 1.228 + public void setUp() throws Exception { 1.229 + super.setUp(sBrowserProviderCallable, BrowserContract.AUTHORITY, "browser.db"); 1.230 + 1.231 + mTests.add(new TestSpecialFolders()); 1.232 + 1.233 + mTests.add(new TestInsertBookmarks()); 1.234 + mTests.add(new TestInsertBookmarksFavicons()); 1.235 + mTests.add(new TestDeleteBookmarks()); 1.236 + mTests.add(new TestDeleteBookmarksFavicons()); 1.237 + mTests.add(new TestUpdateBookmarks()); 1.238 + mTests.add(new TestUpdateBookmarksFavicons()); 1.239 + mTests.add(new TestPositionBookmarks()); 1.240 + 1.241 + mTests.add(new TestInsertHistory()); 1.242 + mTests.add(new TestInsertHistoryFavicons()); 1.243 + mTests.add(new TestDeleteHistory()); 1.244 + mTests.add(new TestDeleteHistoryFavicons()); 1.245 + mTests.add(new TestUpdateHistory()); 1.246 + mTests.add(new TestUpdateHistoryFavicons()); 1.247 + mTests.add(new TestUpdateOrInsertHistory()); 1.248 + mTests.add(new TestInsertHistoryThumbnails()); 1.249 + mTests.add(new TestUpdateHistoryThumbnails()); 1.250 + mTests.add(new TestDeleteHistoryThumbnails()); 1.251 + 1.252 + mTests.add(new TestBatchOperations()); 1.253 + 1.254 + mTests.add(new TestCombinedView()); 1.255 + mTests.add(new TestCombinedViewDisplay()); 1.256 + mTests.add(new TestCombinedViewWithDeletedBookmark()); 1.257 + mTests.add(new TestCombinedViewWithDeletedReadingListItem()); 1.258 + mTests.add(new TestExpireHistory()); 1.259 + 1.260 + mTests.add(new TestBrowserProviderNotifications()); 1.261 + } 1.262 + 1.263 + public void testBrowserProvider() throws Exception { 1.264 + loadMobileFolderId(); 1.265 + 1.266 + for (int i = 0; i < mTests.size(); i++) { 1.267 + Runnable test = mTests.get(i); 1.268 + 1.269 + final String testName = test.getClass().getSimpleName(); 1.270 + setTestName(testName); 1.271 + ensureEmptyDatabase(); 1.272 + mAsserter.dumpLog("testBrowserProvider: Database empty - Starting " + testName + "."); 1.273 + test.run(); 1.274 + } 1.275 + } 1.276 + 1.277 + private class TestBatchOperations extends TestCase { 1.278 + static final int TESTCOUNT = 100; 1.279 + 1.280 + public void testApplyBatch() throws Exception { 1.281 + ArrayList<ContentProviderOperation> mOperations 1.282 + = new ArrayList<ContentProviderOperation>(); 1.283 + 1.284 + // Test a bunch of inserts with applyBatch 1.285 + ContentValues values = new ContentValues(); 1.286 + ContentProviderOperation.Builder builder = null; 1.287 + 1.288 + for (int i = 0; i < TESTCOUNT; i++) { 1.289 + values.clear(); 1.290 + values.put(BrowserContract.History.VISITS, i); 1.291 + values.put(BrowserContract.History.TITLE, "Test" + i); 1.292 + values.put(BrowserContract.History.URL, "http://www.test.org/" + i); 1.293 + 1.294 + // Insert 1.295 + builder = ContentProviderOperation.newInsert(BrowserContract.History.CONTENT_URI); 1.296 + builder.withValues(values); 1.297 + // Queue the operation 1.298 + mOperations.add(builder.build()); 1.299 + } 1.300 + 1.301 + ContentProviderResult[] applyResult = 1.302 + mProvider.applyBatch(mOperations); 1.303 + 1.304 + boolean allFound = true; 1.305 + for (int i = 0; i < TESTCOUNT; i++) { 1.306 + Cursor cursor = mProvider.query(BrowserContract.History.CONTENT_URI, 1.307 + null, 1.308 + BrowserContract.History.URL + " = ?", 1.309 + new String[] { "http://www.test.org/" + i }, 1.310 + null); 1.311 + 1.312 + if (!cursor.moveToFirst()) 1.313 + allFound = false; 1.314 + cursor.close(); 1.315 + } 1.316 + mAsserter.is(allFound, true, "Found all batchApply entries"); 1.317 + mOperations.clear(); 1.318 + 1.319 + // Update all visits to 1 1.320 + values.clear(); 1.321 + values.put(BrowserContract.History.VISITS, 1); 1.322 + for (int i = 0; i < TESTCOUNT; i++) { 1.323 + builder = ContentProviderOperation.newUpdate(BrowserContract.History.CONTENT_URI); 1.324 + builder.withSelection(BrowserContract.History.URL + " = ?", 1.325 + new String[] {"http://www.test.org/" + i}); 1.326 + builder.withValues(values); 1.327 + builder.withExpectedCount(1); 1.328 + // Queue the operation 1.329 + mOperations.add(builder.build()); 1.330 + } 1.331 + 1.332 + boolean seenException = false; 1.333 + try { 1.334 + applyResult = mProvider.applyBatch(mOperations); 1.335 + } catch (OperationApplicationException ex) { 1.336 + seenException = true; 1.337 + } 1.338 + mAsserter.is(seenException, false, "Batch updating succeded"); 1.339 + mOperations.clear(); 1.340 + 1.341 + // Delete all visits 1.342 + for (int i = 0; i < TESTCOUNT; i++) { 1.343 + builder = ContentProviderOperation.newDelete(BrowserContract.History.CONTENT_URI); 1.344 + builder.withSelection(BrowserContract.History.URL + " = ?", 1.345 + new String[] {"http://www.test.org/" + i}); 1.346 + builder.withExpectedCount(1); 1.347 + // Queue the operation 1.348 + mOperations.add(builder.build()); 1.349 + } 1.350 + try { 1.351 + applyResult = mProvider.applyBatch(mOperations); 1.352 + } catch (OperationApplicationException ex) { 1.353 + seenException = true; 1.354 + } 1.355 + mAsserter.is(seenException, false, "Batch deletion succeeded"); 1.356 + } 1.357 + 1.358 + // Force a Constraint error, see if later operations still apply correctly 1.359 + public void testApplyBatchErrors() throws Exception { 1.360 + ArrayList<ContentProviderOperation> mOperations 1.361 + = new ArrayList<ContentProviderOperation>(); 1.362 + 1.363 + // Test a bunch of inserts with applyBatch 1.364 + ContentProviderOperation.Builder builder = null; 1.365 + ContentValues values = createFaviconEntry("http://www.test.org", "FAVICON"); 1.366 + builder = ContentProviderOperation.newInsert(BrowserContract.Favicons.CONTENT_URI); 1.367 + builder.withValues(values); 1.368 + mOperations.add(builder.build()); 1.369 + 1.370 + // Make a duplicate, this will fail because of a UNIQUE constraint 1.371 + builder = ContentProviderOperation.newInsert(BrowserContract.Favicons.CONTENT_URI); 1.372 + builder.withValues(values); 1.373 + mOperations.add(builder.build()); 1.374 + 1.375 + // This is valid and should be in the table afterwards 1.376 + values.put(BrowserContract.Favicons.URL, "http://www.test.org/valid.ico"); 1.377 + builder = ContentProviderOperation.newInsert(BrowserContract.Favicons.CONTENT_URI); 1.378 + builder.withValues(values); 1.379 + mOperations.add(builder.build()); 1.380 + 1.381 + boolean seenException = false; 1.382 + 1.383 + try { 1.384 + ContentProviderResult[] applyResult = 1.385 + mProvider.applyBatch(mOperations); 1.386 + } catch (OperationApplicationException ex) { 1.387 + seenException = true; 1.388 + } 1.389 + 1.390 + // This test may need to go away if Bug 717428 is fixed. 1.391 + mAsserter.is(seenException, true, "Expected failure in favicons table"); 1.392 + 1.393 + boolean allFound = true; 1.394 + Cursor cursor = mProvider.query(BrowserContract.Favicons.CONTENT_URI, 1.395 + null, 1.396 + BrowserContract.Favicons.URL + " = ?", 1.397 + new String[] { "http://www.test.org/valid.ico" }, 1.398 + null); 1.399 + 1.400 + if (!cursor.moveToFirst()) 1.401 + allFound = false; 1.402 + cursor.close(); 1.403 + 1.404 + mAsserter.is(allFound, true, "Found all applyBatch (with error) entries"); 1.405 + } 1.406 + 1.407 + public void testBulkInsert() throws Exception { 1.408 + // Test a bunch of inserts with bulkInsert 1.409 + ContentValues allVals[] = new ContentValues[TESTCOUNT]; 1.410 + for (int i = 0; i < TESTCOUNT; i++) { 1.411 + allVals[i] = new ContentValues(); 1.412 + allVals[i].put(BrowserContract.History.URL, i); 1.413 + allVals[i].put(BrowserContract.History.TITLE, "Test" + i); 1.414 + allVals[i].put(BrowserContract.History.URL, "http://www.test.org/" + i); 1.415 + } 1.416 + 1.417 + int inserts = mProvider.bulkInsert(BrowserContract.History.CONTENT_URI, allVals); 1.418 + mAsserter.is(inserts, TESTCOUNT, "Excepted number of inserts matches"); 1.419 + 1.420 + boolean allFound = true; 1.421 + for (int i = 0; i < TESTCOUNT; i++) { 1.422 + Cursor cursor = mProvider.query(BrowserContract.History.CONTENT_URI, 1.423 + null, 1.424 + BrowserContract.History.URL + " = ?", 1.425 + new String[] { "http://www.test.org/" + i }, 1.426 + null); 1.427 + 1.428 + if (!cursor.moveToFirst()) 1.429 + allFound = false; 1.430 + cursor.close(); 1.431 + } 1.432 + mAsserter.is(allFound, true, "Found all bulkInsert entries"); 1.433 + } 1.434 + 1.435 + @Override 1.436 + public void test() throws Exception { 1.437 + testApplyBatch(); 1.438 + // Clean up 1.439 + ensureEmptyDatabase(); 1.440 + 1.441 + testBulkInsert(); 1.442 + ensureEmptyDatabase(); 1.443 + 1.444 + testApplyBatchErrors(); 1.445 + } 1.446 + } 1.447 + 1.448 + private class TestSpecialFolders extends TestCase { 1.449 + @Override 1.450 + public void test() throws Exception { 1.451 + Cursor c = mProvider.query(BrowserContract.Bookmarks.CONTENT_URI, 1.452 + new String[] { BrowserContract.Bookmarks._ID, 1.453 + BrowserContract.Bookmarks.GUID, 1.454 + BrowserContract.Bookmarks.PARENT }, 1.455 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.456 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.457 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.458 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.459 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.460 + BrowserContract.Bookmarks.GUID + " = ? OR " + 1.461 + BrowserContract.Bookmarks.GUID + " = ?", 1.462 + new String[] { BrowserContract.Bookmarks.PLACES_FOLDER_GUID, 1.463 + BrowserContract.Bookmarks.MOBILE_FOLDER_GUID, 1.464 + BrowserContract.Bookmarks.MENU_FOLDER_GUID, 1.465 + BrowserContract.Bookmarks.TAGS_FOLDER_GUID, 1.466 + BrowserContract.Bookmarks.TOOLBAR_FOLDER_GUID, 1.467 + BrowserContract.Bookmarks.UNFILED_FOLDER_GUID, 1.468 + BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID }, 1.469 + null); 1.470 + 1.471 + mAsserter.is(c.getCount(), 7, "Right number of special folders"); 1.472 + 1.473 + int rootId = BrowserContract.Bookmarks.FIXED_ROOT_ID; 1.474 + int readingListId = BrowserContract.Bookmarks.FIXED_READING_LIST_ID; 1.475 + 1.476 + while (c.moveToNext()) { 1.477 + int id = c.getInt(c.getColumnIndex(BrowserContract.Bookmarks._ID)); 1.478 + String guid = c.getString(c.getColumnIndex(BrowserContract.Bookmarks.GUID)); 1.479 + int parentId = c.getInt(c.getColumnIndex(BrowserContract.Bookmarks.PARENT)); 1.480 + 1.481 + if (guid.equals(BrowserContract.Bookmarks.PLACES_FOLDER_GUID)) { 1.482 + mAsserter.is(new Integer(id), new Integer(rootId), "The id of places folder is correct"); 1.483 + } else if (guid.equals(BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID)) { 1.484 + mAsserter.is(new Integer(id), new Integer(readingListId), "The id of reading list folder is correct"); 1.485 + } 1.486 + 1.487 + mAsserter.is(new Integer(parentId), new Integer(rootId), 1.488 + "The PARENT of the " + guid + " special folder is correct"); 1.489 + } 1.490 + 1.491 + c.close(); 1.492 + } 1.493 + } 1.494 + 1.495 + private class TestInsertBookmarks extends TestCase { 1.496 + private long insertWithNullCol(String colName) throws Exception { 1.497 + ContentValues b = createOneBookmark(); 1.498 + b.putNull(colName); 1.499 + long id = -1; 1.500 + 1.501 + try { 1.502 + id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.503 + } catch (Exception e) {} 1.504 + 1.505 + return id; 1.506 + } 1.507 + 1.508 + @Override 1.509 + public void test() throws Exception { 1.510 + ContentValues b = createOneBookmark(); 1.511 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.512 + Cursor c = getBookmarkById(id); 1.513 + 1.514 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.515 + 1.516 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TITLE)), b.getAsString(BrowserContract.Bookmarks.TITLE), 1.517 + "Inserted bookmark has correct title"); 1.518 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.URL)), b.getAsString(BrowserContract.Bookmarks.URL), 1.519 + "Inserted bookmark has correct URL"); 1.520 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TAGS)), b.getAsString(BrowserContract.Bookmarks.TAGS), 1.521 + "Inserted bookmark has correct tags"); 1.522 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.KEYWORD)), b.getAsString(BrowserContract.Bookmarks.KEYWORD), 1.523 + "Inserted bookmark has correct keyword"); 1.524 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.DESCRIPTION)), b.getAsString(BrowserContract.Bookmarks.DESCRIPTION), 1.525 + "Inserted bookmark has correct description"); 1.526 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.POSITION)), b.getAsString(BrowserContract.Bookmarks.POSITION), 1.527 + "Inserted bookmark has correct position"); 1.528 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TYPE)), b.getAsString(BrowserContract.Bookmarks.TYPE), 1.529 + "Inserted bookmark has correct type"); 1.530 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.PARENT)), b.getAsString(BrowserContract.Bookmarks.PARENT), 1.531 + "Inserted bookmark has correct parent ID"); 1.532 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.IS_DELETED)), String.valueOf(0), 1.533 + "Inserted bookmark has correct is-deleted state"); 1.534 + 1.535 + id = insertWithNullCol(BrowserContract.Bookmarks.POSITION); 1.536 + mAsserter.is(new Long(id), new Long(-1), 1.537 + "Should not be able to insert bookmark with null position"); 1.538 + 1.539 + id = insertWithNullCol(BrowserContract.Bookmarks.TYPE); 1.540 + mAsserter.is(new Long(id), new Long(-1), 1.541 + "Should not be able to insert bookmark with null type"); 1.542 + 1.543 + if (Build.VERSION.SDK_INT >= 8 && 1.544 + Build.VERSION.SDK_INT < 16) { 1.545 + b = createOneBookmark(); 1.546 + b.put(BrowserContract.Bookmarks.PARENT, -1); 1.547 + id = -1; 1.548 + 1.549 + try { 1.550 + id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.551 + } catch (Exception e) {} 1.552 + 1.553 + mAsserter.is(new Long(id), new Long(-1), 1.554 + "Should not be able to insert bookmark with invalid parent"); 1.555 + } 1.556 + 1.557 + b = createOneBookmark(); 1.558 + b.remove(BrowserContract.Bookmarks.TYPE); 1.559 + id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.560 + c = getBookmarkById(id); 1.561 + 1.562 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.563 + 1.564 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TYPE)), String.valueOf(BrowserContract.Bookmarks.TYPE_BOOKMARK), 1.565 + "Inserted bookmark has correct default type"); 1.566 + c.close(); 1.567 + } 1.568 + } 1.569 + 1.570 + private class TestInsertBookmarksFavicons extends TestCase { 1.571 + @Override 1.572 + public void test() throws Exception { 1.573 + ContentValues b = createOneBookmark(); 1.574 + 1.575 + final String favicon = "FAVICON"; 1.576 + final String pageUrl = b.getAsString(BrowserContract.Bookmarks.URL); 1.577 + 1.578 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.579 + 1.580 + // Insert the favicon into the favicons table 1.581 + mProvider.insert(BrowserContract.Favicons.CONTENT_URI, createFaviconEntry(pageUrl, favicon)); 1.582 + 1.583 + Cursor c = getBookmarkById(id, new String[] { BrowserContract.Bookmarks.FAVICON }); 1.584 + 1.585 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.586 + 1.587 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Bookmarks.FAVICON)), "UTF8"), 1.588 + favicon, "Inserted bookmark has corresponding favicon image"); 1.589 + c.close(); 1.590 + 1.591 + c = getFaviconsByUrl(pageUrl); 1.592 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.593 + 1.594 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.595 + favicon, "Inserted favicon has corresponding favicon image"); 1.596 + c.close(); 1.597 + } 1.598 + } 1.599 + 1.600 + private class TestDeleteBookmarks extends TestCase { 1.601 + private long insertOneBookmark() throws Exception { 1.602 + ContentValues b = createOneBookmark(); 1.603 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.604 + 1.605 + Cursor c = getBookmarkById(id); 1.606 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.607 + c.close(); 1.608 + 1.609 + return id; 1.610 + } 1.611 + 1.612 + @Override 1.613 + public void test() throws Exception { 1.614 + long id = insertOneBookmark(); 1.615 + 1.616 + int deleted = mProvider.delete(BrowserContract.Bookmarks.CONTENT_URI, 1.617 + BrowserContract.Bookmarks._ID + " = ?", 1.618 + new String[] { String.valueOf(id) }); 1.619 + 1.620 + mAsserter.is((deleted == 1), true, "Inserted bookmark was deleted"); 1.621 + 1.622 + Cursor c = getBookmarkById(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), id); 1.623 + mAsserter.is(c.moveToFirst(), true, "Deleted bookmark was only marked as deleted"); 1.624 + c.close(); 1.625 + 1.626 + deleted = mProvider.delete(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), 1.627 + BrowserContract.Bookmarks._ID + " = ?", 1.628 + new String[] { String.valueOf(id) }); 1.629 + 1.630 + mAsserter.is((deleted == 1), true, "Inserted bookmark was deleted"); 1.631 + 1.632 + c = getBookmarkById(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), id); 1.633 + mAsserter.is(c.moveToFirst(), false, "Inserted bookmark is now actually deleted"); 1.634 + c.close(); 1.635 + 1.636 + id = insertOneBookmark(); 1.637 + 1.638 + deleted = mProvider.delete(ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), null, null); 1.639 + mAsserter.is((deleted == 1), true, 1.640 + "Inserted bookmark was deleted using URI with id"); 1.641 + 1.642 + c = getBookmarkById(id); 1.643 + mAsserter.is(c.moveToFirst(), false, 1.644 + "Inserted bookmark can't be found after deletion using URI with ID"); 1.645 + c.close(); 1.646 + 1.647 + if (Build.VERSION.SDK_INT >= 8 && 1.648 + Build.VERSION.SDK_INT < 16) { 1.649 + ContentValues b = createBookmark("Folder", null, mMobileFolderId, 1.650 + BrowserContract.Bookmarks.TYPE_FOLDER, 0, "folderTags", "folderDescription", "folderKeyword"); 1.651 + 1.652 + long parentId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.653 + c = getBookmarkById(parentId); 1.654 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmarks folder found"); 1.655 + c.close(); 1.656 + 1.657 + b = createBookmark("Example", "http://example.com", parentId, 1.658 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.659 + 1.660 + id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.661 + c = getBookmarkById(id); 1.662 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.663 + c.close(); 1.664 + 1.665 + deleted = 0; 1.666 + try { 1.667 + Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, parentId); 1.668 + deleted = mProvider.delete(appendUriParam(uri, BrowserContract.PARAM_IS_SYNC, "1"), null, null); 1.669 + } catch(Exception e) {} 1.670 + 1.671 + mAsserter.is((deleted == 0), true, 1.672 + "Should not be able to delete folder that causes orphan bookmarks"); 1.673 + } 1.674 + } 1.675 + } 1.676 + 1.677 + private class TestDeleteBookmarksFavicons extends TestCase { 1.678 + @Override 1.679 + public void test() throws Exception { 1.680 + ContentValues b = createOneBookmark(); 1.681 + 1.682 + final String pageUrl = b.getAsString(BrowserContract.Bookmarks.URL); 1.683 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.684 + 1.685 + // Insert the favicon into the favicons table 1.686 + mProvider.insert(BrowserContract.Favicons.CONTENT_URI, createFaviconEntry(pageUrl, "FAVICON")); 1.687 + 1.688 + Cursor c = getFaviconsByUrl(pageUrl); 1.689 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.690 + c.close(); 1.691 + 1.692 + mProvider.delete(ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), null, null); 1.693 + 1.694 + c = getFaviconsByUrl(pageUrl); 1.695 + mAsserter.is(c.moveToFirst(), false, "Favicon is deleted with last reference to it"); 1.696 + c.close(); 1.697 + } 1.698 + } 1.699 + 1.700 + private class TestUpdateBookmarks extends TestCase { 1.701 + private int updateWithNullCol(long id, String colName) throws Exception { 1.702 + ContentValues u = new ContentValues(); 1.703 + u.putNull(colName); 1.704 + 1.705 + int updated = 0; 1.706 + 1.707 + try { 1.708 + updated = mProvider.update(BrowserContract.Bookmarks.CONTENT_URI, u, 1.709 + BrowserContract.Bookmarks._ID + " = ?", 1.710 + new String[] { String.valueOf(id) }); 1.711 + } catch (Exception e) {} 1.712 + 1.713 + return updated; 1.714 + } 1.715 + 1.716 + @Override 1.717 + public void test() throws Exception { 1.718 + ContentValues b = createOneBookmark(); 1.719 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b)); 1.720 + 1.721 + Cursor c = getBookmarkById(id); 1.722 + mAsserter.is(c.moveToFirst(), true, "Inserted bookmark found"); 1.723 + 1.724 + long dateCreated = c.getLong(c.getColumnIndex(BrowserContract.Bookmarks.DATE_CREATED)); 1.725 + long dateModified = c.getLong(c.getColumnIndex(BrowserContract.Bookmarks.DATE_MODIFIED)); 1.726 + 1.727 + ContentValues u = new ContentValues(); 1.728 + u.put(BrowserContract.Bookmarks.TITLE, b.getAsString(BrowserContract.Bookmarks.TITLE) + "CHANGED"); 1.729 + u.put(BrowserContract.Bookmarks.URL, b.getAsString(BrowserContract.Bookmarks.URL) + "/more/stuff"); 1.730 + u.put(BrowserContract.Bookmarks.TAGS, b.getAsString(BrowserContract.Bookmarks.TAGS) + "CHANGED"); 1.731 + u.put(BrowserContract.Bookmarks.DESCRIPTION, b.getAsString(BrowserContract.Bookmarks.DESCRIPTION) + "CHANGED"); 1.732 + u.put(BrowserContract.Bookmarks.KEYWORD, b.getAsString(BrowserContract.Bookmarks.KEYWORD) + "CHANGED"); 1.733 + u.put(BrowserContract.Bookmarks.TYPE, BrowserContract.Bookmarks.TYPE_FOLDER); 1.734 + u.put(BrowserContract.Bookmarks.POSITION, 10); 1.735 + 1.736 + int updated = mProvider.update(BrowserContract.Bookmarks.CONTENT_URI, u, 1.737 + BrowserContract.Bookmarks._ID + " = ?", 1.738 + new String[] { String.valueOf(id) }); 1.739 + 1.740 + mAsserter.is((updated == 1), true, "Inserted bookmark was updated"); 1.741 + c.close(); 1.742 + 1.743 + c = getBookmarkById(id); 1.744 + mAsserter.is(c.moveToFirst(), true, "Updated bookmark found"); 1.745 + 1.746 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TITLE)), u.getAsString(BrowserContract.Bookmarks.TITLE), 1.747 + "Inserted bookmark has correct title"); 1.748 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.URL)), u.getAsString(BrowserContract.Bookmarks.URL), 1.749 + "Inserted bookmark has correct URL"); 1.750 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TAGS)), u.getAsString(BrowserContract.Bookmarks.TAGS), 1.751 + "Inserted bookmark has correct tags"); 1.752 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.KEYWORD)), u.getAsString(BrowserContract.Bookmarks.KEYWORD), 1.753 + "Inserted bookmark has correct keyword"); 1.754 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.DESCRIPTION)), u.getAsString(BrowserContract.Bookmarks.DESCRIPTION), 1.755 + "Inserted bookmark has correct description"); 1.756 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.POSITION)), u.getAsString(BrowserContract.Bookmarks.POSITION), 1.757 + "Inserted bookmark has correct position"); 1.758 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.TYPE)), u.getAsString(BrowserContract.Bookmarks.TYPE), 1.759 + "Inserted bookmark has correct type"); 1.760 + 1.761 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Bookmarks.DATE_CREATED))), 1.762 + new Long(dateCreated), 1.763 + "Updated bookmark has same creation date"); 1.764 + 1.765 + mAsserter.isnot(new Long(c.getLong(c.getColumnIndex(BrowserContract.Bookmarks.DATE_MODIFIED))), 1.766 + new Long(dateModified), 1.767 + "Updated bookmark has new modification date"); 1.768 + 1.769 + updated = updateWithNullCol(id, BrowserContract.Bookmarks.POSITION); 1.770 + mAsserter.is((updated > 0), false, 1.771 + "Should not be able to update bookmark with null position"); 1.772 + 1.773 + updated = updateWithNullCol(id, BrowserContract.Bookmarks.TYPE); 1.774 + mAsserter.is((updated > 0), false, 1.775 + "Should not be able to update bookmark with null type"); 1.776 + 1.777 + u = new ContentValues(); 1.778 + u.put(BrowserContract.Bookmarks.URL, "http://examples2.com"); 1.779 + 1.780 + updated = mProvider.update(ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), u, null, null); 1.781 + c.close(); 1.782 + 1.783 + c = getBookmarkById(id); 1.784 + mAsserter.is(c.moveToFirst(), true, "Updated bookmark found"); 1.785 + 1.786 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Bookmarks.URL)), u.getAsString(BrowserContract.Bookmarks.URL), 1.787 + "Updated bookmark has correct URL using URI with id"); 1.788 + c.close(); 1.789 + } 1.790 + } 1.791 + 1.792 + private class TestUpdateBookmarksFavicons extends TestCase { 1.793 + @Override 1.794 + public void test() throws Exception { 1.795 + ContentValues b = createOneBookmark(); 1.796 + 1.797 + final String favicon = "FAVICON"; 1.798 + final String newFavicon = "NEW_FAVICON"; 1.799 + final String pageUrl = b.getAsString(BrowserContract.Bookmarks.URL); 1.800 + 1.801 + mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, b); 1.802 + 1.803 + // Insert the favicon into the favicons table 1.804 + ContentValues f = createFaviconEntry(pageUrl, favicon); 1.805 + long faviconId = ContentUris.parseId(mProvider.insert(BrowserContract.Favicons.CONTENT_URI, f)); 1.806 + 1.807 + Cursor c = getFaviconsByUrl(pageUrl); 1.808 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.809 + 1.810 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.811 + favicon, "Inserted favicon has corresponding favicon image"); 1.812 + 1.813 + ContentValues u = createFaviconEntry(pageUrl, newFavicon); 1.814 + mProvider.update(BrowserContract.Favicons.CONTENT_URI, u, null, null); 1.815 + c.close(); 1.816 + 1.817 + c = getFaviconsByUrl(pageUrl); 1.818 + mAsserter.is(c.moveToFirst(), true, "Updated favicon found"); 1.819 + 1.820 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.821 + newFavicon, "Updated favicon has corresponding favicon image"); 1.822 + c.close(); 1.823 + } 1.824 + } 1.825 + 1.826 + /** 1.827 + * Create a folder of one thousand and one bookmarks, then impose an order 1.828 + * on them. 1.829 + * 1.830 + * Verify that the reordering worked by querying. 1.831 + */ 1.832 + private class TestPositionBookmarks extends TestCase { 1.833 + 1.834 + public String makeGUID(final long in) { 1.835 + String part = String.valueOf(in); 1.836 + return "aaaaaaaaaaaa".substring(0, (12 - part.length())) + part; 1.837 + } 1.838 + 1.839 + public void compareCursorToItems(final Cursor c, final String[] items, final int count) { 1.840 + mAsserter.is(c.moveToFirst(), true, "Folder has children."); 1.841 + 1.842 + int posColumn = c.getColumnIndex(BrowserContract.Bookmarks.POSITION); 1.843 + int guidColumn = c.getColumnIndex(BrowserContract.Bookmarks.GUID); 1.844 + int i = 0; 1.845 + 1.846 + while (!c.isAfterLast()) { 1.847 + String guid = c.getString(guidColumn); 1.848 + long pos = c.getLong(posColumn); 1.849 + if ((pos != i) || (guid == null) || (!guid.equals(items[i]))) { 1.850 + mAsserter.is(pos, (long) i, "Position matches sequence."); 1.851 + mAsserter.is(guid, items[i], "GUID matches sequence."); 1.852 + } 1.853 + ++i; 1.854 + c.moveToNext(); 1.855 + } 1.856 + 1.857 + mAsserter.is(i, count, "Folder has the right number of children."); 1.858 + c.close(); 1.859 + } 1.860 + 1.861 + public static final int NUMBER_OF_CHILDREN = 1001; 1.862 + @Override 1.863 + public void test() throws Exception { 1.864 + // Create the containing folder. 1.865 + ContentValues folder = createBookmark("FolderFolder", "", mMobileFolderId, 1.866 + BrowserContract.Bookmarks.TYPE_FOLDER, 0, "", 1.867 + "description", "keyword"); 1.868 + folder.put(BrowserContract.Bookmarks.GUID, "folderfolder"); 1.869 + long folderId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, folder)); 1.870 + 1.871 + mAsserter.dumpLog("TestPositionBookmarks: Folder inserted"); // Bug 968951 debug. 1.872 + 1.873 + // Create the children. 1.874 + String[] items = new String[NUMBER_OF_CHILDREN]; 1.875 + 1.876 + // Reuse the same ContentValues. 1.877 + ContentValues item = createBookmark("Test Bookmark", "http://example.com", folderId, 1.878 + BrowserContract.Bookmarks.TYPE_FOLDER, 0, "", 1.879 + "description", "keyword"); 1.880 + 1.881 + for (int i = 0; i < NUMBER_OF_CHILDREN; ++i) { 1.882 + String guid = makeGUID(i); 1.883 + items[i] = guid; 1.884 + item.put(BrowserContract.Bookmarks.GUID, guid); 1.885 + item.put(BrowserContract.Bookmarks.POSITION, i); 1.886 + item.put(BrowserContract.Bookmarks.URL, "http://example.com/" + guid); 1.887 + item.put(BrowserContract.Bookmarks.TITLE, "Test Bookmark " + guid); 1.888 + mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, item); 1.889 + } 1.890 + 1.891 + mAsserter.dumpLog("TestPositionBookmarks: Bookmarks inserted"); // Bug 968951 debug. 1.892 + 1.893 + Cursor c; 1.894 + 1.895 + // Verify insertion. 1.896 + c = getBookmarksByParent(folderId); 1.897 + mAsserter.dumpLog("TestPositionBookmarks: Got bookmarks by parent"); // Bug 968951 debug. 1.898 + compareCursorToItems(c, items, NUMBER_OF_CHILDREN); 1.899 + c.close(); 1.900 + 1.901 + // Now permute the items array. 1.902 + Random rand = new Random(); 1.903 + for (int i = 0; i < NUMBER_OF_CHILDREN; ++i) { 1.904 + final int newPosition = rand.nextInt(NUMBER_OF_CHILDREN); 1.905 + final String switched = items[newPosition]; 1.906 + items[newPosition] = items[i]; 1.907 + items[i] = switched; 1.908 + } 1.909 + 1.910 + // Impose the positions. 1.911 + long updated = mProvider.update(BrowserContract.Bookmarks.POSITIONS_CONTENT_URI, null, null, items); 1.912 + mAsserter.is(updated, (long) NUMBER_OF_CHILDREN, "Updated " + NUMBER_OF_CHILDREN + " positions."); 1.913 + 1.914 + // Verify that the database was updated. 1.915 + c = getBookmarksByParent(folderId); 1.916 + compareCursorToItems(c, items, NUMBER_OF_CHILDREN); 1.917 + c.close(); 1.918 + } 1.919 + } 1.920 + 1.921 + private class TestInsertHistory extends TestCase { 1.922 + private long insertWithNullCol(String colName) throws Exception { 1.923 + ContentValues h = createOneHistoryEntry(); 1.924 + h.putNull(colName); 1.925 + long id = -1; 1.926 + 1.927 + try { 1.928 + id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.929 + } catch (Exception e) {} 1.930 + 1.931 + return id; 1.932 + } 1.933 + 1.934 + @Override 1.935 + public void test() throws Exception { 1.936 + ContentValues h = createOneHistoryEntry(); 1.937 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.938 + Cursor c = getHistoryEntryById(id); 1.939 + 1.940 + mAsserter.is(c.moveToFirst(), true, "Inserted history entry found"); 1.941 + 1.942 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), h.getAsString(BrowserContract.History.TITLE), 1.943 + "Inserted history entry has correct title"); 1.944 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.URL)), h.getAsString(BrowserContract.History.URL), 1.945 + "Inserted history entry has correct URL"); 1.946 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.VISITS)), h.getAsString(BrowserContract.History.VISITS), 1.947 + "Inserted history entry has correct number of visits"); 1.948 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.DATE_LAST_VISITED)), h.getAsString(BrowserContract.History.DATE_LAST_VISITED), 1.949 + "Inserted history entry has correct last visited date"); 1.950 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.IS_DELETED)), String.valueOf(0), 1.951 + "Inserted history entry has correct is-deleted state"); 1.952 + 1.953 + id = insertWithNullCol(BrowserContract.History.URL); 1.954 + mAsserter.is(new Long(id), new Long(-1), 1.955 + "Should not be able to insert history with null URL"); 1.956 + 1.957 + id = insertWithNullCol(BrowserContract.History.VISITS); 1.958 + mAsserter.is(new Long(id), new Long(-1), 1.959 + "Should not be able to insert history with null number of visits"); 1.960 + c.close(); 1.961 + } 1.962 + } 1.963 + 1.964 + private class TestInsertHistoryFavicons extends TestCase { 1.965 + @Override 1.966 + public void test() throws Exception { 1.967 + ContentValues h = createOneHistoryEntry(); 1.968 + 1.969 + final String favicon = "FAVICON"; 1.970 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.971 + 1.972 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.973 + 1.974 + // Insert the favicon into the favicons table 1.975 + mProvider.insert(BrowserContract.Favicons.CONTENT_URI, createFaviconEntry(pageUrl, favicon)); 1.976 + 1.977 + Cursor c = getHistoryEntryById(id, new String[] { BrowserContract.History.FAVICON }); 1.978 + 1.979 + mAsserter.is(c.moveToFirst(), true, "Inserted history entry found"); 1.980 + 1.981 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.History.FAVICON)), "UTF8"), 1.982 + favicon, "Inserted history entry has corresponding favicon image"); 1.983 + c.close(); 1.984 + 1.985 + c = getFaviconsByUrl(pageUrl); 1.986 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.987 + 1.988 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.989 + favicon, "Inserted favicon has corresponding favicon image"); 1.990 + c.close(); 1.991 + } 1.992 + } 1.993 + 1.994 + private class TestDeleteHistory extends TestCase { 1.995 + private long insertOneHistoryEntry() throws Exception { 1.996 + ContentValues h = createOneHistoryEntry(); 1.997 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.998 + 1.999 + Cursor c = getHistoryEntryById(id); 1.1000 + mAsserter.is(c.moveToFirst(), true, "Inserted history entry found"); 1.1001 + c.close(); 1.1002 + 1.1003 + return id; 1.1004 + } 1.1005 + 1.1006 + @Override 1.1007 + public void test() throws Exception { 1.1008 + long id = insertOneHistoryEntry(); 1.1009 + 1.1010 + int deleted = mProvider.delete(BrowserContract.History.CONTENT_URI, 1.1011 + BrowserContract.History._ID + " = ?", 1.1012 + new String[] { String.valueOf(id) }); 1.1013 + 1.1014 + mAsserter.is((deleted == 1), true, "Inserted history entry was deleted"); 1.1015 + 1.1016 + Cursor c = getHistoryEntryById(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), id); 1.1017 + mAsserter.is(c.moveToFirst(), true, "Deleted history entry was only marked as deleted"); 1.1018 + 1.1019 + deleted = mProvider.delete(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), 1.1020 + BrowserContract.History._ID + " = ?", 1.1021 + new String[] { String.valueOf(id) }); 1.1022 + 1.1023 + mAsserter.is((deleted == 1), true, "Inserted history entry was deleted"); 1.1024 + c.close(); 1.1025 + 1.1026 + c = getHistoryEntryById(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), id); 1.1027 + mAsserter.is(c.moveToFirst(), false, "Inserted history is now actually deleted"); 1.1028 + 1.1029 + id = insertOneHistoryEntry(); 1.1030 + 1.1031 + deleted = mProvider.delete(ContentUris.withAppendedId(BrowserContract.History.CONTENT_URI, id), null, null); 1.1032 + mAsserter.is((deleted == 1), true, 1.1033 + "Inserted history entry was deleted using URI with id"); 1.1034 + c.close(); 1.1035 + 1.1036 + c = getHistoryEntryById(id); 1.1037 + mAsserter.is(c.moveToFirst(), false, 1.1038 + "Inserted history entry can't be found after deletion using URI with ID"); 1.1039 + c.close(); 1.1040 + } 1.1041 + } 1.1042 + 1.1043 + private class TestDeleteHistoryFavicons extends TestCase { 1.1044 + @Override 1.1045 + public void test() throws Exception { 1.1046 + ContentValues h = createOneHistoryEntry(); 1.1047 + 1.1048 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.1049 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.1050 + 1.1051 + // Insert the favicon into the favicons table 1.1052 + mProvider.insert(BrowserContract.Favicons.CONTENT_URI, createFaviconEntry(pageUrl, "FAVICON")); 1.1053 + 1.1054 + Cursor c = getFaviconsByUrl(pageUrl); 1.1055 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.1056 + 1.1057 + mProvider.delete(ContentUris.withAppendedId(BrowserContract.History.CONTENT_URI, id), null, null); 1.1058 + c.close(); 1.1059 + 1.1060 + c = getFaviconsByUrl(pageUrl); 1.1061 + mAsserter.is(c.moveToFirst(), false, "Favicon is deleted with last reference to it"); 1.1062 + c.close(); 1.1063 + } 1.1064 + } 1.1065 + 1.1066 + private class TestUpdateHistory extends TestCase { 1.1067 + private int updateWithNullCol(long id, String colName) throws Exception { 1.1068 + ContentValues u = new ContentValues(); 1.1069 + u.putNull(colName); 1.1070 + 1.1071 + int updated = 0; 1.1072 + 1.1073 + try { 1.1074 + updated = mProvider.update(BrowserContract.History.CONTENT_URI, u, 1.1075 + BrowserContract.History._ID + " = ?", 1.1076 + new String[] { String.valueOf(id) }); 1.1077 + } catch (Exception e) {} 1.1078 + 1.1079 + return updated; 1.1080 + } 1.1081 + 1.1082 + @Override 1.1083 + public void test() throws Exception { 1.1084 + ContentValues h = createOneHistoryEntry(); 1.1085 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.1086 + 1.1087 + Cursor c = getHistoryEntryById(id); 1.1088 + mAsserter.is(c.moveToFirst(), true, "Inserted history entry found"); 1.1089 + 1.1090 + long dateCreated = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED)); 1.1091 + long dateModified = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED)); 1.1092 + 1.1093 + ContentValues u = new ContentValues(); 1.1094 + u.put(BrowserContract.History.VISITS, h.getAsInteger(BrowserContract.History.VISITS) + 1); 1.1095 + u.put(BrowserContract.History.DATE_LAST_VISITED, System.currentTimeMillis()); 1.1096 + u.put(BrowserContract.History.TITLE, h.getAsString(BrowserContract.History.TITLE) + "CHANGED"); 1.1097 + u.put(BrowserContract.History.URL, h.getAsString(BrowserContract.History.URL) + "/more/stuff"); 1.1098 + 1.1099 + int updated = mProvider.update(BrowserContract.History.CONTENT_URI, u, 1.1100 + BrowserContract.History._ID + " = ?", 1.1101 + new String[] { String.valueOf(id) }); 1.1102 + 1.1103 + mAsserter.is((updated == 1), true, "Inserted history entry was updated"); 1.1104 + c.close(); 1.1105 + 1.1106 + c = getHistoryEntryById(id); 1.1107 + mAsserter.is(c.moveToFirst(), true, "Updated history entry found"); 1.1108 + 1.1109 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), u.getAsString(BrowserContract.History.TITLE), 1.1110 + "Updated history entry has correct title"); 1.1111 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.URL)), u.getAsString(BrowserContract.History.URL), 1.1112 + "Updated history entry has correct URL"); 1.1113 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.VISITS)), u.getAsString(BrowserContract.History.VISITS), 1.1114 + "Updated history entry has correct number of visits"); 1.1115 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.DATE_LAST_VISITED)), u.getAsString(BrowserContract.History.DATE_LAST_VISITED), 1.1116 + "Updated history entry has correct last visited date"); 1.1117 + 1.1118 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED))), 1.1119 + new Long(dateCreated), 1.1120 + "Updated history entry has same creation date"); 1.1121 + 1.1122 + mAsserter.isnot(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED))), 1.1123 + new Long(dateModified), 1.1124 + "Updated history entry has new modification date"); 1.1125 + 1.1126 + updated = updateWithNullCol(id, BrowserContract.History.URL); 1.1127 + mAsserter.is((updated > 0), false, 1.1128 + "Should not be able to update history with null URL"); 1.1129 + 1.1130 + updated = updateWithNullCol(id, BrowserContract.History.VISITS); 1.1131 + mAsserter.is((updated > 0), false, 1.1132 + "Should not be able to update history with null number of visits"); 1.1133 + 1.1134 + u = new ContentValues(); 1.1135 + u.put(BrowserContract.History.URL, "http://examples2.com"); 1.1136 + 1.1137 + updated = mProvider.update(ContentUris.withAppendedId(BrowserContract.History.CONTENT_URI, id), u, null, null); 1.1138 + c.close(); 1.1139 + 1.1140 + c = getHistoryEntryById(id); 1.1141 + mAsserter.is(c.moveToFirst(), true, "Updated history entry found"); 1.1142 + 1.1143 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.URL)), u.getAsString(BrowserContract.History.URL), 1.1144 + "Updated history entry has correct URL using URI with id"); 1.1145 + c.close(); 1.1146 + } 1.1147 + } 1.1148 + 1.1149 + private class TestUpdateHistoryFavicons extends TestCase { 1.1150 + @Override 1.1151 + public void test() throws Exception { 1.1152 + ContentValues h = createOneHistoryEntry(); 1.1153 + 1.1154 + final String favicon = "FAVICON"; 1.1155 + final String newFavicon = "NEW_FAVICON"; 1.1156 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.1157 + 1.1158 + mProvider.insert(BrowserContract.History.CONTENT_URI, h); 1.1159 + 1.1160 + // Insert the favicon into the favicons table 1.1161 + mProvider.insert(BrowserContract.Favicons.CONTENT_URI, createFaviconEntry(pageUrl, favicon)); 1.1162 + 1.1163 + Cursor c = getFaviconsByUrl(pageUrl); 1.1164 + mAsserter.is(c.moveToFirst(), true, "Inserted favicon found"); 1.1165 + 1.1166 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.1167 + favicon, "Inserted favicon has corresponding favicon image"); 1.1168 + 1.1169 + ContentValues u = createFaviconEntry(pageUrl, newFavicon); 1.1170 + 1.1171 + mProvider.update(BrowserContract.Favicons.CONTENT_URI, u, null, null); 1.1172 + c.close(); 1.1173 + 1.1174 + c = getFaviconsByUrl(pageUrl); 1.1175 + mAsserter.is(c.moveToFirst(), true, "Updated favicon found"); 1.1176 + 1.1177 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Combined.FAVICON)), "UTF8"), 1.1178 + newFavicon, "Updated favicon has corresponding favicon image"); 1.1179 + c.close(); 1.1180 + } 1.1181 + } 1.1182 + 1.1183 + private class TestUpdateOrInsertHistory extends TestCase { 1.1184 + private final String TEST_URL_1 = "http://example.com"; 1.1185 + private final String TEST_URL_2 = "http://example.org"; 1.1186 + private final String TEST_TITLE = "Example"; 1.1187 + 1.1188 + private long getHistoryEntryIdByUrl(String url) { 1.1189 + Cursor c = mProvider.query(BrowserContract.History.CONTENT_URI, 1.1190 + new String[] { BrowserContract.History._ID }, 1.1191 + BrowserContract.History.URL + " = ?", 1.1192 + new String[] { url }, 1.1193 + null); 1.1194 + c.moveToFirst(); 1.1195 + long id = c.getLong(0); 1.1196 + c.close(); 1.1197 + 1.1198 + return id; 1.1199 + } 1.1200 + 1.1201 + @Override 1.1202 + public void test() throws Exception { 1.1203 + Uri updateHistoryUri = BrowserContract.History.CONTENT_URI.buildUpon(). 1.1204 + appendQueryParameter("increment_visits", "true").build(); 1.1205 + Uri updateOrInsertHistoryUri = BrowserContract.History.CONTENT_URI.buildUpon(). 1.1206 + appendQueryParameter("insert_if_needed", "true"). 1.1207 + appendQueryParameter("increment_visits", "true").build(); 1.1208 + 1.1209 + // Update a non-existent history entry, without specifying visits or title 1.1210 + ContentValues values = new ContentValues(); 1.1211 + values.put(BrowserContract.History.URL, TEST_URL_1); 1.1212 + 1.1213 + int updated = mProvider.update(updateHistoryUri, values, 1.1214 + BrowserContract.History.URL + " = ?", 1.1215 + new String[] { TEST_URL_1 }); 1.1216 + mAsserter.is((updated == 0), true, "History entry was not updated"); 1.1217 + Cursor c = mProvider.query(BrowserContract.History.CONTENT_URI, null, null, null, null); 1.1218 + mAsserter.is(c.moveToFirst(), false, "History entry was not inserted"); 1.1219 + c.close(); 1.1220 + 1.1221 + // Now let's try with update-or-insert. 1.1222 + updated = mProvider.update(updateOrInsertHistoryUri, values, 1.1223 + BrowserContract.History.URL + " = ?", 1.1224 + new String[] { TEST_URL_1 }); 1.1225 + mAsserter.is((updated == 1), true, "History entry was inserted"); 1.1226 + 1.1227 + long id = getHistoryEntryIdByUrl(TEST_URL_1); 1.1228 + c = getHistoryEntryById(id); 1.1229 + mAsserter.is(c.moveToFirst(), true, "History entry was inserted"); 1.1230 + 1.1231 + long dateCreated = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED)); 1.1232 + long dateModified = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED)); 1.1233 + 1.1234 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.VISITS))), new Long(1), 1.1235 + "Inserted history entry has correct default number of visits"); 1.1236 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), TEST_URL_1, 1.1237 + "Inserted history entry has correct default title"); 1.1238 + 1.1239 + // Update the history entry, without specifying an additional visit count 1.1240 + values = new ContentValues(); 1.1241 + values.put(BrowserContract.History.DATE_LAST_VISITED, System.currentTimeMillis()); 1.1242 + values.put(BrowserContract.History.TITLE, TEST_TITLE); 1.1243 + 1.1244 + updated = mProvider.update(updateOrInsertHistoryUri, values, 1.1245 + BrowserContract.History._ID + " = ?", 1.1246 + new String[] { String.valueOf(id) }); 1.1247 + mAsserter.is((updated == 1), true, "Inserted history entry was updated"); 1.1248 + c.close(); 1.1249 + 1.1250 + c = getHistoryEntryById(id); 1.1251 + mAsserter.is(c.moveToFirst(), true, "Updated history entry found"); 1.1252 + 1.1253 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), TEST_TITLE, 1.1254 + "Updated history entry has correct title"); 1.1255 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.VISITS))), new Long(2), 1.1256 + "Updated history entry has correct number of visits"); 1.1257 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED))), new Long(dateCreated), 1.1258 + "Updated history entry has same creation date"); 1.1259 + mAsserter.isnot(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED))), new Long(dateModified), 1.1260 + "Updated history entry has new modification date"); 1.1261 + 1.1262 + // Create a new history entry, specifying visits and history 1.1263 + values = new ContentValues(); 1.1264 + values.put(BrowserContract.History.URL, TEST_URL_2); 1.1265 + values.put(BrowserContract.History.TITLE, TEST_TITLE); 1.1266 + values.put(BrowserContract.History.VISITS, 10); 1.1267 + 1.1268 + updated = mProvider.update(updateOrInsertHistoryUri, values, 1.1269 + BrowserContract.History.URL + " = ?", 1.1270 + new String[] { values.getAsString(BrowserContract.History.URL) }); 1.1271 + mAsserter.is((updated == 1), true, "History entry was inserted"); 1.1272 + 1.1273 + id = getHistoryEntryIdByUrl(TEST_URL_2); 1.1274 + c.close(); 1.1275 + 1.1276 + c = getHistoryEntryById(id); 1.1277 + mAsserter.is(c.moveToFirst(), true, "History entry was inserted"); 1.1278 + 1.1279 + dateCreated = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED)); 1.1280 + dateModified = c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED)); 1.1281 + 1.1282 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.VISITS))), new Long(10), 1.1283 + "Inserted history entry has correct specified number of visits"); 1.1284 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), TEST_TITLE, 1.1285 + "Inserted history entry has correct specified title"); 1.1286 + 1.1287 + // Update the history entry, specifying additional visit count 1.1288 + values = new ContentValues(); 1.1289 + values.put(BrowserContract.History.VISITS, 10); 1.1290 + 1.1291 + updated = mProvider.update(updateOrInsertHistoryUri, values, 1.1292 + BrowserContract.History._ID + " = ?", 1.1293 + new String[] { String.valueOf(id) }); 1.1294 + mAsserter.is((updated == 1), true, "Inserted history entry was updated"); 1.1295 + c.close(); 1.1296 + 1.1297 + c = getHistoryEntryById(id); 1.1298 + mAsserter.is(c.moveToFirst(), true, "Updated history entry found"); 1.1299 + 1.1300 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.TITLE)), TEST_TITLE, 1.1301 + "Updated history entry has correct unchanged title"); 1.1302 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.History.URL)), TEST_URL_2, 1.1303 + "Updated history entry has correct unchanged URL"); 1.1304 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.VISITS))), new Long(20), 1.1305 + "Updated history entry has correct number of visits"); 1.1306 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_CREATED))), new Long(dateCreated), 1.1307 + "Updated history entry has same creation date"); 1.1308 + mAsserter.isnot(new Long(c.getLong(c.getColumnIndex(BrowserContract.History.DATE_MODIFIED))), new Long(dateModified), 1.1309 + "Updated history entry has new modification date"); 1.1310 + c.close(); 1.1311 + 1.1312 + } 1.1313 + } 1.1314 + 1.1315 + private class TestInsertHistoryThumbnails extends TestCase { 1.1316 + @Override 1.1317 + public void test() throws Exception { 1.1318 + ContentValues h = createOneHistoryEntry(); 1.1319 + 1.1320 + final String thumbnail = "THUMBNAIL"; 1.1321 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.1322 + 1.1323 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.1324 + 1.1325 + // Insert the thumbnail into the thumbnails table 1.1326 + mProvider.insert(BrowserContract.Thumbnails.CONTENT_URI, createThumbnailEntry(pageUrl, thumbnail)); 1.1327 + 1.1328 + Cursor c = getThumbnailByUrl(pageUrl); 1.1329 + mAsserter.is(c.moveToFirst(), true, "Inserted thumbnail found"); 1.1330 + 1.1331 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Thumbnails.DATA)), "UTF8"), 1.1332 + thumbnail, "Inserted thumbnail has corresponding thumbnail image"); 1.1333 + c.close(); 1.1334 + } 1.1335 + } 1.1336 + 1.1337 + private class TestUpdateHistoryThumbnails extends TestCase { 1.1338 + @Override 1.1339 + public void test() throws Exception { 1.1340 + ContentValues h = createOneHistoryEntry(); 1.1341 + 1.1342 + final String thumbnail = "THUMBNAIL"; 1.1343 + final String newThumbnail = "NEW_THUMBNAIL"; 1.1344 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.1345 + 1.1346 + mProvider.insert(BrowserContract.History.CONTENT_URI, h); 1.1347 + 1.1348 + // Insert the thumbnail into the thumbnails table 1.1349 + mProvider.insert(BrowserContract.Thumbnails.CONTENT_URI, createThumbnailEntry(pageUrl, thumbnail)); 1.1350 + 1.1351 + Cursor c = getThumbnailByUrl(pageUrl); 1.1352 + mAsserter.is(c.moveToFirst(), true, "Inserted thumbnail found"); 1.1353 + 1.1354 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Thumbnails.DATA)), "UTF8"), 1.1355 + thumbnail, "Inserted thumbnail has corresponding thumbnail image"); 1.1356 + 1.1357 + ContentValues u = createThumbnailEntry(pageUrl, newThumbnail); 1.1358 + 1.1359 + mProvider.update(BrowserContract.Thumbnails.CONTENT_URI, u, null, null); 1.1360 + c.close(); 1.1361 + 1.1362 + c = getThumbnailByUrl(pageUrl); 1.1363 + mAsserter.is(c.moveToFirst(), true, "Updated thumbnail found"); 1.1364 + 1.1365 + mAsserter.is(new String(c.getBlob(c.getColumnIndex(BrowserContract.Thumbnails.DATA)), "UTF8"), 1.1366 + newThumbnail, "Updated thumbnail has corresponding thumbnail image"); 1.1367 + c.close(); 1.1368 + } 1.1369 + } 1.1370 + 1.1371 + private class TestDeleteHistoryThumbnails extends TestCase { 1.1372 + @Override 1.1373 + public void test() throws Exception { 1.1374 + ContentValues h = createOneHistoryEntry(); 1.1375 + 1.1376 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.1377 + final String pageUrl = h.getAsString(BrowserContract.History.URL); 1.1378 + 1.1379 + // Insert the thumbnail into the thumbnails table 1.1380 + mProvider.insert(BrowserContract.Thumbnails.CONTENT_URI, createThumbnailEntry(pageUrl, "THUMBNAIL")); 1.1381 + 1.1382 + Cursor c = getThumbnailByUrl(pageUrl); 1.1383 + mAsserter.is(c.moveToFirst(), true, "Inserted thumbnail found"); 1.1384 + 1.1385 + mProvider.delete(ContentUris.withAppendedId(BrowserContract.History.CONTENT_URI, id), null, null); 1.1386 + c.close(); 1.1387 + 1.1388 + c = getThumbnailByUrl(pageUrl); 1.1389 + mAsserter.is(c.moveToFirst(), false, "Thumbnail is deleted with last reference to it"); 1.1390 + c.close(); 1.1391 + } 1.1392 + } 1.1393 + 1.1394 + private class TestCombinedView extends TestCase { 1.1395 + @Override 1.1396 + public void test() throws Exception { 1.1397 + final String TITLE_1 = "Test Page 1"; 1.1398 + final String TITLE_2 = "Test Page 2"; 1.1399 + final String TITLE_3_HISTORY = "Test Page 3 (History Entry)"; 1.1400 + final String TITLE_3_BOOKMARK = "Test Page 3 (Bookmark Entry)"; 1.1401 + final String TITLE_3_BOOKMARK2 = "Test Page 3 (Bookmark Entry 2)"; 1.1402 + 1.1403 + final String URL_1 = "http://example1.com"; 1.1404 + final String URL_2 = "http://example2.com"; 1.1405 + final String URL_3 = "http://example3.com"; 1.1406 + 1.1407 + final int VISITS = 10; 1.1408 + final long LAST_VISITED = System.currentTimeMillis(); 1.1409 + 1.1410 + // Create a basic history entry 1.1411 + ContentValues basicHistory = createHistoryEntry(TITLE_1, URL_1, VISITS, LAST_VISITED); 1.1412 + long basicHistoryId = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, basicHistory)); 1.1413 + 1.1414 + // Create a basic bookmark entry 1.1415 + ContentValues basicBookmark = createBookmark(TITLE_2, URL_2, mMobileFolderId, 1.1416 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1417 + long basicBookmarkId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, basicBookmark)); 1.1418 + 1.1419 + // Create a history entry and bookmark entry with the same URL to 1.1420 + // represent a visited bookmark 1.1421 + ContentValues combinedHistory = createHistoryEntry(TITLE_3_HISTORY, URL_3, VISITS, LAST_VISITED); 1.1422 + long combinedHistoryId = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, combinedHistory)); 1.1423 + 1.1424 + 1.1425 + ContentValues combinedBookmark = createBookmark(TITLE_3_BOOKMARK, URL_3, mMobileFolderId, 1.1426 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1427 + long combinedBookmarkId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, combinedBookmark)); 1.1428 + 1.1429 + ContentValues combinedBookmark2 = createBookmark(TITLE_3_BOOKMARK2, URL_3, mMobileFolderId, 1.1430 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1431 + long combinedBookmarkId2 = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, combinedBookmark2)); 1.1432 + 1.1433 + // Create a bookmark folder to make sure it _doesn't_ show up in the results 1.1434 + ContentValues folderBookmark = createBookmark("", "", mMobileFolderId, 1.1435 + BrowserContract.Bookmarks.TYPE_FOLDER, 0, "tags", "description", "keyword"); 1.1436 + mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, folderBookmark); 1.1437 + 1.1438 + // Sort entries by url so we can check them individually 1.1439 + Cursor c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, BrowserContract.Combined.URL); 1.1440 + 1.1441 + mAsserter.is(c.getCount(), 3, "3 combined entries found"); 1.1442 + 1.1443 + // First combined entry is basic history entry 1.1444 + mAsserter.is(c.moveToFirst(), true, "Found basic history entry"); 1.1445 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined._ID))), new Long(0), 1.1446 + "Combined _id column should always be 0"); 1.1447 + // TODO: Should we change BrowserProvider to make this return -1, not 0? 1.1448 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(0), 1.1449 + "Bookmark id should be 0 for basic history entry"); 1.1450 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.HISTORY_ID))), new Long(basicHistoryId), 1.1451 + "Basic history entry has correct history id"); 1.1452 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.TITLE)), TITLE_1, 1.1453 + "Basic history entry has correct title"); 1.1454 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.URL)), URL_1, 1.1455 + "Basic history entry has correct url"); 1.1456 + mAsserter.is(c.getInt(c.getColumnIndex(BrowserContract.Combined.VISITS)), VISITS, 1.1457 + "Basic history entry has correct number of visits"); 1.1458 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.DATE_LAST_VISITED))), new Long(LAST_VISITED), 1.1459 + "Basic history entry has correct last visit time"); 1.1460 + 1.1461 + // Second combined entry is basic bookmark entry 1.1462 + mAsserter.is(c.moveToNext(), true, "Found basic bookmark entry"); 1.1463 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined._ID))), new Long(0), 1.1464 + "Combined _id column should always be 0"); 1.1465 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(basicBookmarkId), 1.1466 + "Basic bookmark entry has correct bookmark id"); 1.1467 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.HISTORY_ID))), new Long(-1), 1.1468 + "History id should be -1 for basic bookmark entry"); 1.1469 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.TITLE)), TITLE_2, 1.1470 + "Basic bookmark entry has correct title"); 1.1471 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.URL)), URL_2, 1.1472 + "Basic bookmark entry has correct url"); 1.1473 + mAsserter.is(c.getInt(c.getColumnIndex(BrowserContract.Combined.VISITS)), -1, 1.1474 + "Visits should be -1 for basic bookmark entry"); 1.1475 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.DATE_LAST_VISITED))), new Long(-1), 1.1476 + "Basic entry has correct last visit time"); 1.1477 + 1.1478 + // Third combined entry is a combined history/bookmark entry 1.1479 + mAsserter.is(c.moveToNext(), true, "Found third combined entry"); 1.1480 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined._ID))), new Long(0), 1.1481 + "Combined _id column should always be 0"); 1.1482 + // The bookmark data (bookmark_id and title) associated with the combined entry is non-deterministic, 1.1483 + // it might end up with data coming from any of the matching bookmark entries. 1.1484 + mAsserter.is(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID)) == combinedBookmarkId || 1.1485 + c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID)) == combinedBookmarkId2, true, 1.1486 + "Combined entry has correct bookmark id"); 1.1487 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.TITLE)).equals(TITLE_3_BOOKMARK) || 1.1488 + c.getString(c.getColumnIndex(BrowserContract.Combined.TITLE)).equals(TITLE_3_BOOKMARK2), true, 1.1489 + "Combined entry has title corresponding to bookmark entry"); 1.1490 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.HISTORY_ID))), new Long(combinedHistoryId), 1.1491 + "Combined entry has correct history id"); 1.1492 + mAsserter.is(c.getString(c.getColumnIndex(BrowserContract.Combined.URL)), URL_3, 1.1493 + "Combined entry has correct url"); 1.1494 + mAsserter.is(c.getInt(c.getColumnIndex(BrowserContract.Combined.VISITS)), VISITS, 1.1495 + "Combined entry has correct number of visits"); 1.1496 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.DATE_LAST_VISITED))), new Long(LAST_VISITED), 1.1497 + "Combined entry has correct last visit time"); 1.1498 + c.close(); 1.1499 + } 1.1500 + } 1.1501 + 1.1502 + private class TestCombinedViewDisplay extends TestCase { 1.1503 + @Override 1.1504 + public void test() throws Exception { 1.1505 + final String TITLE_1 = "Test Page 1"; 1.1506 + final String TITLE_2 = "Test Page 2"; 1.1507 + final String TITLE_3_HISTORY = "Test Page 3 (History Entry)"; 1.1508 + final String TITLE_3_BOOKMARK = "Test Page 3 (Bookmark Entry)"; 1.1509 + final String TITLE_4 = "Test Page 4"; 1.1510 + 1.1511 + final String URL_1 = "http://example.com"; 1.1512 + final String URL_2 = "http://example.org"; 1.1513 + final String URL_3 = "http://examples2.com"; 1.1514 + final String URL_4 = "http://readinglist.com"; 1.1515 + 1.1516 + final int VISITS = 10; 1.1517 + final long LAST_VISITED = System.currentTimeMillis(); 1.1518 + 1.1519 + // Create a basic history entry 1.1520 + ContentValues basicHistory = createHistoryEntry(TITLE_1, URL_1, VISITS, LAST_VISITED); 1.1521 + ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, basicHistory)); 1.1522 + 1.1523 + // Create a basic bookmark entry 1.1524 + ContentValues basicBookmark = createBookmark(TITLE_2, URL_2, mMobileFolderId, 1.1525 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1526 + mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, basicBookmark); 1.1527 + 1.1528 + // Create a history entry and bookmark entry with the same URL to 1.1529 + // represent a visited bookmark 1.1530 + ContentValues combinedHistory = createHistoryEntry(TITLE_3_HISTORY, URL_3, VISITS, LAST_VISITED); 1.1531 + mProvider.insert(BrowserContract.History.CONTENT_URI, combinedHistory); 1.1532 + 1.1533 + ContentValues combinedBookmark = createBookmark(TITLE_3_BOOKMARK, URL_3, mMobileFolderId, 1.1534 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1535 + mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, combinedBookmark); 1.1536 + 1.1537 + // Create a reading list entries 1.1538 + int readingListId = BrowserContract.Bookmarks.FIXED_READING_LIST_ID; 1.1539 + ContentValues readingListItem = createBookmark(TITLE_3_BOOKMARK, URL_3, readingListId, 1.1540 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1541 + long readingListItemId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, readingListItem)); 1.1542 + 1.1543 + ContentValues readingListItem2 = createBookmark(TITLE_4, URL_4, readingListId, 1.1544 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1545 + long readingListItemId2 = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, readingListItem2)); 1.1546 + 1.1547 + Cursor c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, null); 1.1548 + mAsserter.is(c.getCount(), 4, "4 combined entries found"); 1.1549 + 1.1550 + while (c.moveToNext()) { 1.1551 + long id = c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID)); 1.1552 + 1.1553 + int display = c.getInt(c.getColumnIndex(BrowserContract.Combined.DISPLAY)); 1.1554 + int expectedDisplay = (id == readingListItemId || id == readingListItemId2 ? BrowserContract.Combined.DISPLAY_READER : BrowserContract.Combined.DISPLAY_NORMAL); 1.1555 + 1.1556 + mAsserter.is(new Integer(display), new Integer(expectedDisplay), 1.1557 + "Combined display column should always be DISPLAY_READER for the reading list item"); 1.1558 + } 1.1559 + c.close(); 1.1560 + } 1.1561 + } 1.1562 + 1.1563 + private class TestCombinedViewWithDeletedBookmark extends TestCase { 1.1564 + @Override 1.1565 + public void test() throws Exception { 1.1566 + final String TITLE = "Test Page 1"; 1.1567 + final String URL = "http://example.com"; 1.1568 + final int VISITS = 10; 1.1569 + final long LAST_VISITED = System.currentTimeMillis(); 1.1570 + 1.1571 + // Create a combined history entry 1.1572 + ContentValues combinedHistory = createHistoryEntry(TITLE, URL, VISITS, LAST_VISITED); 1.1573 + mProvider.insert(BrowserContract.History.CONTENT_URI, combinedHistory); 1.1574 + 1.1575 + // Create a combined bookmark entry 1.1576 + ContentValues combinedBookmark = createBookmark(TITLE, URL, mMobileFolderId, 1.1577 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1578 + long combinedBookmarkId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, combinedBookmark)); 1.1579 + 1.1580 + Cursor c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, null); 1.1581 + mAsserter.is(c.getCount(), 1, "1 combined entry found"); 1.1582 + 1.1583 + mAsserter.is(c.moveToFirst(), true, "Found combined entry with bookmark id"); 1.1584 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(combinedBookmarkId), 1.1585 + "Bookmark id should be set correctly on combined entry"); 1.1586 + 1.1587 + int deleted = mProvider.delete(BrowserContract.Bookmarks.CONTENT_URI, 1.1588 + BrowserContract.Bookmarks._ID + " = ?", 1.1589 + new String[] { String.valueOf(combinedBookmarkId) }); 1.1590 + 1.1591 + mAsserter.is((deleted == 1), true, "Inserted combined bookmark was deleted"); 1.1592 + c.close(); 1.1593 + 1.1594 + c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, null); 1.1595 + mAsserter.is(c.getCount(), 1, "1 combined entry found"); 1.1596 + 1.1597 + mAsserter.is(c.moveToFirst(), true, "Found combined entry without bookmark id"); 1.1598 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(0), 1.1599 + "Bookmark id should not be set to removed bookmark id"); 1.1600 + c.close(); 1.1601 + } 1.1602 + } 1.1603 + 1.1604 + private class TestCombinedViewWithDeletedReadingListItem extends TestCase { 1.1605 + @Override 1.1606 + public void test() throws Exception { 1.1607 + final String TITLE = "Test Page 1"; 1.1608 + final String URL = "http://example.com"; 1.1609 + final int VISITS = 10; 1.1610 + final long LAST_VISITED = System.currentTimeMillis(); 1.1611 + 1.1612 + // Create a combined history entry 1.1613 + ContentValues combinedHistory = createHistoryEntry(TITLE, URL, VISITS, LAST_VISITED); 1.1614 + mProvider.insert(BrowserContract.History.CONTENT_URI, combinedHistory); 1.1615 + 1.1616 + // Create a combined bookmark entry 1.1617 + int readingListId = BrowserContract.Bookmarks.FIXED_READING_LIST_ID; 1.1618 + ContentValues combinedReadingListItem = createBookmark(TITLE, URL, readingListId, 1.1619 + BrowserContract.Bookmarks.TYPE_BOOKMARK, 0, "tags", "description", "keyword"); 1.1620 + long combinedReadingListItemId = ContentUris.parseId(mProvider.insert(BrowserContract.Bookmarks.CONTENT_URI, combinedReadingListItem)); 1.1621 + 1.1622 + Cursor c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, null); 1.1623 + mAsserter.is(c.getCount(), 1, "1 combined entry found"); 1.1624 + 1.1625 + mAsserter.is(c.moveToFirst(), true, "Found combined entry with bookmark id"); 1.1626 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(combinedReadingListItemId), 1.1627 + "Bookmark id should be set correctly on combined entry"); 1.1628 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.DISPLAY))), new Long(BrowserContract.Combined.DISPLAY_READER), 1.1629 + "Combined entry should have reader display type"); 1.1630 + 1.1631 + int deleted = mProvider.delete(BrowserContract.Bookmarks.CONTENT_URI, 1.1632 + BrowserContract.Bookmarks._ID + " = ?", 1.1633 + new String[] { String.valueOf(combinedReadingListItemId) }); 1.1634 + 1.1635 + mAsserter.is((deleted == 1), true, "Inserted combined reading list item was deleted"); 1.1636 + c.close(); 1.1637 + 1.1638 + c = mProvider.query(BrowserContract.Combined.CONTENT_URI, null, "", null, null); 1.1639 + mAsserter.is(c.getCount(), 1, "1 combined entry found"); 1.1640 + 1.1641 + mAsserter.is(c.moveToFirst(), true, "Found combined entry without bookmark id"); 1.1642 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID))), new Long(0), 1.1643 + "Bookmark id should not be set to removed bookmark id"); 1.1644 + mAsserter.is(new Long(c.getLong(c.getColumnIndex(BrowserContract.Combined.DISPLAY))), new Long(BrowserContract.Combined.DISPLAY_NORMAL), 1.1645 + "Combined entry should have reader display type"); 1.1646 + c.close(); 1.1647 + } 1.1648 + } 1.1649 + 1.1650 + private class TestExpireHistory extends TestCase { 1.1651 + private void createFakeHistory(long timeShift, int count) { 1.1652 + // Insert a bunch of very new entries 1.1653 + ContentValues[] allVals = new ContentValues[count]; 1.1654 + long time = System.currentTimeMillis() - timeShift; 1.1655 + for (int i = 0; i < count; i++) { 1.1656 + allVals[i] = new ContentValues(); 1.1657 + allVals[i].put(BrowserContract.History.TITLE, "Test " + i); 1.1658 + allVals[i].put(BrowserContract.History.URL, "http://www.test.org/" + i); 1.1659 + allVals[i].put(BrowserContract.History.VISITS, i); 1.1660 + allVals[i].put(BrowserContract.History.DATE_LAST_VISITED, time); 1.1661 + } 1.1662 + 1.1663 + int inserts = mProvider.bulkInsert(BrowserContract.History.CONTENT_URI, allVals); 1.1664 + mAsserter.is(inserts, count, "Expected number of inserts matches"); 1.1665 + 1.1666 + // inserting a new entry sets the date created and modified automatically 1.1667 + // reset all of them 1.1668 + for (int i = 0; i < count; i++) { 1.1669 + ContentValues cv = new ContentValues(); 1.1670 + cv.put(BrowserContract.History.DATE_CREATED, time); 1.1671 + cv.put(BrowserContract.History.DATE_MODIFIED, time); 1.1672 + mProvider.update(BrowserContract.History.CONTENT_URI, cv, BrowserContract.History.URL + " = ?", 1.1673 + new String[] { "http://www.test.org/" + i }); 1.1674 + } 1.1675 + 1.1676 + Cursor c = mProvider.query(BrowserContract.History.CONTENT_URI, null, "", null, null); 1.1677 + 1.1678 + assertCountIsAndClose(c, count, count + " history entries found"); 1.1679 + 1.1680 + // add thumbnails for each entry 1.1681 + allVals = new ContentValues[count]; 1.1682 + for (int i = 0; i < count; i++) { 1.1683 + allVals[i] = new ContentValues(); 1.1684 + allVals[i].put(BrowserContract.Thumbnails.DATA, i); 1.1685 + allVals[i].put(BrowserContract.Thumbnails.URL, "http://www.test.org/" + i); 1.1686 + } 1.1687 + 1.1688 + inserts = mProvider.bulkInsert(BrowserContract.Thumbnails.CONTENT_URI, allVals); 1.1689 + mAsserter.is(inserts, count, "Expected number of inserts matches"); 1.1690 + 1.1691 + c = mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, null, null, null); 1.1692 + assertCountIsAndClose(c, count, count + " thumbnails entries found"); 1.1693 + } 1.1694 + 1.1695 + @Override 1.1696 + public void test() throws Exception { 1.1697 + final int count = 3000; 1.1698 + final int thumbCount = 15; 1.1699 + 1.1700 + // insert a bunch of new entries 1.1701 + createFakeHistory(0, count); 1.1702 + 1.1703 + // expiring with a normal priority should not delete new entries 1.1704 + Uri url = appendUriParam(BrowserContract.History.CONTENT_OLD_URI, BrowserContract.PARAM_EXPIRE_PRIORITY, "NORMAL"); 1.1705 + mProvider.delete(url, null, null); 1.1706 + Cursor c = mProvider.query(BrowserContract.History.CONTENT_URI, null, "", null, null); 1.1707 + assertCountIsAndClose(c, count, count + " history entries found"); 1.1708 + 1.1709 + // expiring with a normal priority should delete all but 10 thumbnails 1.1710 + c = mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, null, null, null); 1.1711 + assertCountIsAndClose(c, thumbCount, thumbCount + " thumbnails found"); 1.1712 + 1.1713 + ensureEmptyDatabase(); 1.1714 + 1.1715 + // Insert a bunch of new entries. 1.1716 + createFakeHistory(0, count); 1.1717 + 1.1718 + // Expiring with a aggressive priority should leave 500 entries. 1.1719 + url = appendUriParam(BrowserContract.History.CONTENT_OLD_URI, BrowserContract.PARAM_EXPIRE_PRIORITY, "AGGRESSIVE"); 1.1720 + mProvider.delete(url, null, null); 1.1721 + 1.1722 + c = mProvider.query(BrowserContract.History.CONTENT_URI, null, "", null, null); 1.1723 + assertCountIsAndClose(c, 500, "500 history entries found"); 1.1724 + 1.1725 + // Expiring with a aggressive priority should delete all but 10 thumbnails. 1.1726 + c = mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, null, null, null); 1.1727 + assertCountIsAndClose(c, thumbCount, thumbCount + " thumbnails found"); 1.1728 + 1.1729 + ensureEmptyDatabase(); 1.1730 + 1.1731 + // Insert a bunch of entries with an old time created/modified. 1.1732 + long time = 1000L * 60L * 60L * 24L * 30L * 3L; 1.1733 + createFakeHistory(time, count); 1.1734 + 1.1735 + // Expiring with an normal priority should remove at most 1000 entries, 1.1736 + // entries leaving at least 2000. 1.1737 + url = appendUriParam(BrowserContract.History.CONTENT_OLD_URI, BrowserContract.PARAM_EXPIRE_PRIORITY, "NORMAL"); 1.1738 + mProvider.delete(url, null, null); 1.1739 + 1.1740 + c = mProvider.query(BrowserContract.History.CONTENT_URI, null, "", null, null); 1.1741 + assertCountIsAndClose(c, 2000, "2000 history entries found"); 1.1742 + 1.1743 + // Expiring with a normal priority should delete all but 10 thumbnails. 1.1744 + c = mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, null, null, null); 1.1745 + assertCountIsAndClose(c, thumbCount, thumbCount + " thumbnails found"); 1.1746 + 1.1747 + ensureEmptyDatabase(); 1.1748 + // insert a bunch of entries with an old time created/modified 1.1749 + time = 1000L * 60L * 60L * 24L * 30L * 3L; 1.1750 + createFakeHistory(time, count); 1.1751 + 1.1752 + // Expiring with an aggressive priority should remove old 1.1753 + // entries, leaving at least 500. 1.1754 + url = appendUriParam(BrowserContract.History.CONTENT_OLD_URI, BrowserContract.PARAM_EXPIRE_PRIORITY, "AGGRESSIVE"); 1.1755 + mProvider.delete(url, null, null); 1.1756 + c = mProvider.query(BrowserContract.History.CONTENT_URI, null, "", null, null); 1.1757 + assertCountIsAndClose(c, 500, "500 history entries found"); 1.1758 + 1.1759 + // expiring with an aggressive priority should delete all but 10 thumbnails 1.1760 + c = mProvider.query(BrowserContract.Thumbnails.CONTENT_URI, null, null, null, null); 1.1761 + assertCountIsAndClose(c, thumbCount, thumbCount + " thumbnails found"); 1.1762 + } 1.1763 + } 1.1764 + 1.1765 + /* 1.1766 + * Verify that insert, update, delete, and bulkInsert operations 1.1767 + * notify the ambient content resolver. Each operation calls the 1.1768 + * content resolver notifyChange method synchronously, so it is 1.1769 + * okay to test sequentially. 1.1770 + */ 1.1771 + private class TestBrowserProviderNotifications extends TestCase { 1.1772 + public static final String LOGTAG = "TestBPNotifications"; 1.1773 + 1.1774 + protected void ensureOnlyChangeNotifiedStartsWith(Uri expectedUri, String operation) { 1.1775 + if (expectedUri == null) { 1.1776 + throw new IllegalArgumentException("expectedUri must not be null"); 1.1777 + } 1.1778 + 1.1779 + if (mResolver.notifyChangeList.size() != 1) { 1.1780 + // Log to help post-mortem debugging 1.1781 + Log.w(LOGTAG, "after operation, notifyChangeList = " + mResolver.notifyChangeList); 1.1782 + } 1.1783 + 1.1784 + mAsserter.is(Long.valueOf(mResolver.notifyChangeList.size()), 1.1785 + Long.valueOf(1), 1.1786 + "Content observer was notified exactly once by " + operation); 1.1787 + 1.1788 + Uri uri = mResolver.notifyChangeList.poll(); 1.1789 + 1.1790 + mAsserter.isnot(uri, 1.1791 + null, 1.1792 + "Notification from " + operation + " was valid"); 1.1793 + 1.1794 + mAsserter.ok(uri.toString().startsWith(expectedUri.toString()), 1.1795 + "Content observer was notified exactly once by " + operation, 1.1796 + uri.toString() + " starts with expected prefix " + expectedUri); 1.1797 + } 1.1798 + 1.1799 + @Override 1.1800 + public void test() throws Exception { 1.1801 + // Insert 1.1802 + final ContentValues h = createOneHistoryEntry(); 1.1803 + 1.1804 + mResolver.notifyChangeList.clear(); 1.1805 + long id = ContentUris.parseId(mProvider.insert(BrowserContract.History.CONTENT_URI, h)); 1.1806 + 1.1807 + mAsserter.isnot(Long.valueOf(id), 1.1808 + Long.valueOf(-1), 1.1809 + "Inserted item has valid id"); 1.1810 + 1.1811 + ensureOnlyChangeNotifiedStartsWith(BrowserContract.History.CONTENT_URI, "insert"); 1.1812 + 1.1813 + // Update 1.1814 + mResolver.notifyChangeList.clear(); 1.1815 + h.put(BrowserContract.History.TITLE, "http://newexample.com"); 1.1816 + 1.1817 + long numUpdated = mProvider.update(BrowserContract.History.CONTENT_URI, h, 1.1818 + BrowserContract.History._ID + " = ?", 1.1819 + new String[] { String.valueOf(id) }); 1.1820 + 1.1821 + mAsserter.is(Long.valueOf(numUpdated), 1.1822 + Long.valueOf(1), 1.1823 + "Correct number of items are updated"); 1.1824 + 1.1825 + ensureOnlyChangeNotifiedStartsWith(BrowserContract.History.CONTENT_URI, "update"); 1.1826 + 1.1827 + // Delete 1.1828 + mResolver.notifyChangeList.clear(); 1.1829 + long numDeleted = mProvider.delete(BrowserContract.History.CONTENT_URI, null, null); 1.1830 + 1.1831 + mAsserter.is(Long.valueOf(numDeleted), 1.1832 + Long.valueOf(1), 1.1833 + "Correct number of items are deleted"); 1.1834 + 1.1835 + ensureOnlyChangeNotifiedStartsWith(BrowserContract.History.CONTENT_URI, "delete"); 1.1836 + 1.1837 + // Bulk insert 1.1838 + final ContentValues[] hs = new ContentValues[] { createOneHistoryEntry() }; 1.1839 + 1.1840 + mResolver.notifyChangeList.clear(); 1.1841 + long numBulkInserted = mProvider.bulkInsert(BrowserContract.History.CONTENT_URI, hs); 1.1842 + 1.1843 + mAsserter.is(Long.valueOf(numBulkInserted), 1.1844 + Long.valueOf(1), 1.1845 + "Correct number of items are bulkInserted"); 1.1846 + 1.1847 + ensureOnlyChangeNotifiedStartsWith(BrowserContract.History.CONTENT_URI, "bulkInsert"); 1.1848 + } 1.1849 + } 1.1850 + 1.1851 + /** 1.1852 + * Assert that the provided cursor has the expected number of rows, 1.1853 + * closing the cursor afterwards. 1.1854 + */ 1.1855 + private void assertCountIsAndClose(Cursor c, int expectedCount, String message) { 1.1856 + try { 1.1857 + mAsserter.is(c.getCount(), expectedCount, message); 1.1858 + } finally { 1.1859 + c.close(); 1.1860 + } 1.1861 + } 1.1862 +}