mobile/android/tests/background/junit3/src/db/TestAndroidBrowserBookmarksRepository.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 package org.mozilla.gecko.background.db;
michael@0 5
michael@0 6 import java.util.ArrayList;
michael@0 7
michael@0 8 import org.json.simple.JSONArray;
michael@0 9 import org.mozilla.gecko.background.sync.helpers.BookmarkHelpers;
michael@0 10 import org.mozilla.gecko.background.sync.helpers.ExpectFetchDelegate;
michael@0 11 import org.mozilla.gecko.background.sync.helpers.ExpectFetchSinceDelegate;
michael@0 12 import org.mozilla.gecko.background.sync.helpers.ExpectFinishDelegate;
michael@0 13 import org.mozilla.gecko.background.sync.helpers.ExpectGuidsSinceDelegate;
michael@0 14 import org.mozilla.gecko.background.sync.helpers.ExpectInvalidTypeStoreDelegate;
michael@0 15 import org.mozilla.gecko.db.BrowserContract;
michael@0 16 import org.mozilla.gecko.sync.Utils;
michael@0 17 import org.mozilla.gecko.sync.repositories.InactiveSessionException;
michael@0 18 import org.mozilla.gecko.sync.repositories.NullCursorException;
michael@0 19 import org.mozilla.gecko.sync.repositories.RepositorySession;
michael@0 20 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserBookmarksDataAccessor;
michael@0 21 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserBookmarksRepository;
michael@0 22 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserBookmarksRepositorySession;
michael@0 23 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserRepository;
michael@0 24 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserRepositoryDataAccessor;
michael@0 25 import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
michael@0 26 import org.mozilla.gecko.sync.repositories.android.RepoUtils;
michael@0 27 import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
michael@0 28 import org.mozilla.gecko.sync.repositories.domain.BookmarkRecord;
michael@0 29 import org.mozilla.gecko.sync.repositories.domain.Record;
michael@0 30
michael@0 31 import android.content.ContentValues;
michael@0 32 import android.content.Context;
michael@0 33 import android.database.Cursor;
michael@0 34
michael@0 35 public class TestAndroidBrowserBookmarksRepository extends AndroidBrowserRepositoryTestCase {
michael@0 36
michael@0 37 @Override
michael@0 38 protected AndroidBrowserRepository getRepository() {
michael@0 39
michael@0 40 /**
michael@0 41 * Override this chain in order to avoid our test code having to create two
michael@0 42 * sessions all the time.
michael@0 43 */
michael@0 44 return new AndroidBrowserBookmarksRepository() {
michael@0 45 @Override
michael@0 46 protected void sessionCreator(RepositorySessionCreationDelegate delegate, Context context) {
michael@0 47 AndroidBrowserBookmarksRepositorySession session;
michael@0 48 session = new AndroidBrowserBookmarksRepositorySession(this, context) {
michael@0 49 @Override
michael@0 50 protected synchronized void trackGUID(String guid) {
michael@0 51 System.out.println("Ignoring trackGUID call: this is a test!");
michael@0 52 }
michael@0 53 };
michael@0 54 delegate.deferredCreationDelegate().onSessionCreated(session);
michael@0 55 }
michael@0 56 };
michael@0 57 }
michael@0 58
michael@0 59 @Override
michael@0 60 protected AndroidBrowserRepositoryDataAccessor getDataAccessor() {
michael@0 61 return new AndroidBrowserBookmarksDataAccessor(getApplicationContext());
michael@0 62 }
michael@0 63
michael@0 64 /**
michael@0 65 * Hook to return an ExpectFetchDelegate, possibly with special GUIDs ignored.
michael@0 66 */
michael@0 67 @Override
michael@0 68 public ExpectFetchDelegate preparedExpectFetchDelegate(Record[] expected) {
michael@0 69 ExpectFetchDelegate delegate = new ExpectFetchDelegate(expected);
michael@0 70 delegate.ignore.addAll(AndroidBrowserBookmarksRepositorySession.SPECIAL_GUIDS_MAP.keySet());
michael@0 71 return delegate;
michael@0 72 }
michael@0 73
michael@0 74 /**
michael@0 75 * Hook to return an ExpectGuidsSinceDelegate expecting only special GUIDs (if there are any).
michael@0 76 */
michael@0 77 public ExpectGuidsSinceDelegate preparedExpectOnlySpecialGuidsSinceDelegate() {
michael@0 78 ExpectGuidsSinceDelegate delegate = new ExpectGuidsSinceDelegate(AndroidBrowserBookmarksRepositorySession.SPECIAL_GUIDS_MAP.keySet().toArray(new String[] {}));
michael@0 79 return delegate;
michael@0 80 }
michael@0 81
michael@0 82 /**
michael@0 83 * Hook to return an ExpectGuidsSinceDelegate, possibly with special GUIDs ignored.
michael@0 84 */
michael@0 85 @Override
michael@0 86 public ExpectGuidsSinceDelegate preparedExpectGuidsSinceDelegate(String[] expected) {
michael@0 87 ExpectGuidsSinceDelegate delegate = new ExpectGuidsSinceDelegate(expected);
michael@0 88 delegate.ignore.addAll(AndroidBrowserBookmarksRepositorySession.SPECIAL_GUIDS_MAP.keySet());
michael@0 89 return delegate;
michael@0 90 }
michael@0 91
michael@0 92 /**
michael@0 93 * Hook to return an ExpectFetchSinceDelegate, possibly with special GUIDs ignored.
michael@0 94 */
michael@0 95 public ExpectFetchSinceDelegate preparedExpectFetchSinceDelegate(long timestamp, String[] expected) {
michael@0 96 ExpectFetchSinceDelegate delegate = new ExpectFetchSinceDelegate(timestamp, expected);
michael@0 97 delegate.ignore.addAll(AndroidBrowserBookmarksRepositorySession.SPECIAL_GUIDS_MAP.keySet());
michael@0 98 return delegate;
michael@0 99 }
michael@0 100
michael@0 101 // NOTE NOTE NOTE
michael@0 102 // Must store folder before records if we we are checking that the
michael@0 103 // records returned are the same as those sent in. If the folder isn't stored
michael@0 104 // first, the returned records won't be identical to those stored because we
michael@0 105 // aren't able to find the parent name/guid when we do a fetch. If you don't want
michael@0 106 // to store a folder first, store your record in "mobile" or one of the folders
michael@0 107 // that always exists.
michael@0 108
michael@0 109 public void testFetchOneWithChildren() {
michael@0 110 BookmarkRecord folder = BookmarkHelpers.createFolder1();
michael@0 111 BookmarkRecord bookmark1 = BookmarkHelpers.createBookmark1();
michael@0 112 BookmarkRecord bookmark2 = BookmarkHelpers.createBookmark2();
michael@0 113
michael@0 114 RepositorySession session = createAndBeginSession();
michael@0 115
michael@0 116 Record[] records = new Record[] { folder, bookmark1, bookmark2 };
michael@0 117 performWait(storeManyRunnable(session, records));
michael@0 118
michael@0 119 AndroidBrowserRepositoryDataAccessor helper = getDataAccessor();
michael@0 120 helper.dumpDB();
michael@0 121 closeDataAccessor(helper);
michael@0 122
michael@0 123 String[] guids = new String[] { folder.guid };
michael@0 124 Record[] expected = new Record[] { folder };
michael@0 125 performWait(fetchRunnable(session, guids, expected));
michael@0 126 dispose(session);
michael@0 127 }
michael@0 128
michael@0 129 @Override
michael@0 130 public void testFetchAll() {
michael@0 131 Record[] expected = new Record[3];
michael@0 132 expected[0] = BookmarkHelpers.createFolder1();
michael@0 133 expected[1] = BookmarkHelpers.createBookmark1();
michael@0 134 expected[2] = BookmarkHelpers.createBookmark2();
michael@0 135 basicFetchAllTest(expected);
michael@0 136 }
michael@0 137
michael@0 138 @Override
michael@0 139 public void testGuidsSinceReturnMultipleRecords() {
michael@0 140 BookmarkRecord record0 = BookmarkHelpers.createBookmark1();
michael@0 141 BookmarkRecord record1 = BookmarkHelpers.createBookmark2();
michael@0 142 guidsSinceReturnMultipleRecords(record0, record1);
michael@0 143 }
michael@0 144
michael@0 145 @Override
michael@0 146 public void testGuidsSinceReturnNoRecords() {
michael@0 147 guidsSinceReturnNoRecords(BookmarkHelpers.createBookmarkInMobileFolder1());
michael@0 148 }
michael@0 149
michael@0 150 @Override
michael@0 151 public void testFetchSinceOneRecord() {
michael@0 152 fetchSinceOneRecord(BookmarkHelpers.createBookmarkInMobileFolder1(),
michael@0 153 BookmarkHelpers.createBookmarkInMobileFolder2());
michael@0 154 }
michael@0 155
michael@0 156 @Override
michael@0 157 public void testFetchSinceReturnNoRecords() {
michael@0 158 fetchSinceReturnNoRecords(BookmarkHelpers.createBookmark1());
michael@0 159 }
michael@0 160
michael@0 161 @Override
michael@0 162 public void testFetchOneRecordByGuid() {
michael@0 163 fetchOneRecordByGuid(BookmarkHelpers.createBookmarkInMobileFolder1(),
michael@0 164 BookmarkHelpers.createBookmarkInMobileFolder2());
michael@0 165 }
michael@0 166
michael@0 167 @Override
michael@0 168 public void testFetchMultipleRecordsByGuids() {
michael@0 169 BookmarkRecord record0 = BookmarkHelpers.createFolder1();
michael@0 170 BookmarkRecord record1 = BookmarkHelpers.createBookmark1();
michael@0 171 BookmarkRecord record2 = BookmarkHelpers.createBookmark2();
michael@0 172 fetchMultipleRecordsByGuids(record0, record1, record2);
michael@0 173 }
michael@0 174
michael@0 175 @Override
michael@0 176 public void testFetchNoRecordByGuid() {
michael@0 177 fetchNoRecordByGuid(BookmarkHelpers.createBookmark1());
michael@0 178 }
michael@0 179
michael@0 180
michael@0 181 @Override
michael@0 182 public void testWipe() {
michael@0 183 doWipe(BookmarkHelpers.createBookmarkInMobileFolder1(),
michael@0 184 BookmarkHelpers.createBookmarkInMobileFolder2());
michael@0 185 }
michael@0 186
michael@0 187 @Override
michael@0 188 public void testStore() {
michael@0 189 basicStoreTest(BookmarkHelpers.createBookmark1());
michael@0 190 }
michael@0 191
michael@0 192
michael@0 193 public void testStoreFolder() {
michael@0 194 basicStoreTest(BookmarkHelpers.createFolder1());
michael@0 195 }
michael@0 196
michael@0 197 /**
michael@0 198 * TODO: 2011-12-24, tests disabled because we no longer fail
michael@0 199 * a store call if we get an unknown record type.
michael@0 200 */
michael@0 201 /*
michael@0 202 * Test storing each different type of Bookmark record.
michael@0 203 * We expect any records with type other than "bookmark"
michael@0 204 * or "folder" to fail. For now we throw these away.
michael@0 205 */
michael@0 206 /*
michael@0 207 public void testStoreMicrosummary() {
michael@0 208 basicStoreFailTest(BookmarkHelpers.createMicrosummary());
michael@0 209 }
michael@0 210
michael@0 211 public void testStoreQuery() {
michael@0 212 basicStoreFailTest(BookmarkHelpers.createQuery());
michael@0 213 }
michael@0 214
michael@0 215 public void testStoreLivemark() {
michael@0 216 basicStoreFailTest(BookmarkHelpers.createLivemark());
michael@0 217 }
michael@0 218
michael@0 219 public void testStoreSeparator() {
michael@0 220 basicStoreFailTest(BookmarkHelpers.createSeparator());
michael@0 221 }
michael@0 222 */
michael@0 223
michael@0 224 protected void basicStoreFailTest(Record record) {
michael@0 225 final RepositorySession session = createAndBeginSession();
michael@0 226 performWait(storeRunnable(session, record, new ExpectInvalidTypeStoreDelegate()));
michael@0 227 dispose(session);
michael@0 228 }
michael@0 229
michael@0 230 /*
michael@0 231 * Re-parenting tests
michael@0 232 */
michael@0 233 // Insert two records missing parent, then insert their parent.
michael@0 234 // Make sure they end up with the correct parent on fetch.
michael@0 235 public void testBasicReparenting() throws InactiveSessionException {
michael@0 236 Record[] expected = new Record[] {
michael@0 237 BookmarkHelpers.createBookmark1(),
michael@0 238 BookmarkHelpers.createBookmark2(),
michael@0 239 BookmarkHelpers.createFolder1()
michael@0 240 };
michael@0 241 doMultipleFolderReparentingTest(expected);
michael@0 242 }
michael@0 243
michael@0 244 // Insert 3 folders and 4 bookmarks in different orders
michael@0 245 // and make sure they come out parented correctly
michael@0 246 public void testMultipleFolderReparenting1() throws InactiveSessionException {
michael@0 247 Record[] expected = new Record[] {
michael@0 248 BookmarkHelpers.createBookmark1(),
michael@0 249 BookmarkHelpers.createBookmark2(),
michael@0 250 BookmarkHelpers.createBookmark3(),
michael@0 251 BookmarkHelpers.createFolder1(),
michael@0 252 BookmarkHelpers.createBookmark4(),
michael@0 253 BookmarkHelpers.createFolder3(),
michael@0 254 BookmarkHelpers.createFolder2(),
michael@0 255 };
michael@0 256 doMultipleFolderReparentingTest(expected);
michael@0 257 }
michael@0 258
michael@0 259 public void testMultipleFolderReparenting2() throws InactiveSessionException {
michael@0 260 Record[] expected = new Record[] {
michael@0 261 BookmarkHelpers.createBookmark1(),
michael@0 262 BookmarkHelpers.createBookmark2(),
michael@0 263 BookmarkHelpers.createBookmark3(),
michael@0 264 BookmarkHelpers.createFolder1(),
michael@0 265 BookmarkHelpers.createBookmark4(),
michael@0 266 BookmarkHelpers.createFolder3(),
michael@0 267 BookmarkHelpers.createFolder2(),
michael@0 268 };
michael@0 269 doMultipleFolderReparentingTest(expected);
michael@0 270 }
michael@0 271
michael@0 272 public void testMultipleFolderReparenting3() throws InactiveSessionException {
michael@0 273 Record[] expected = new Record[] {
michael@0 274 BookmarkHelpers.createBookmark1(),
michael@0 275 BookmarkHelpers.createBookmark2(),
michael@0 276 BookmarkHelpers.createBookmark3(),
michael@0 277 BookmarkHelpers.createFolder1(),
michael@0 278 BookmarkHelpers.createBookmark4(),
michael@0 279 BookmarkHelpers.createFolder3(),
michael@0 280 BookmarkHelpers.createFolder2(),
michael@0 281 };
michael@0 282 doMultipleFolderReparentingTest(expected);
michael@0 283 }
michael@0 284
michael@0 285 private void doMultipleFolderReparentingTest(Record[] expected) throws InactiveSessionException {
michael@0 286 final RepositorySession session = createAndBeginSession();
michael@0 287 doStore(session, expected);
michael@0 288 ExpectFetchDelegate delegate = preparedExpectFetchDelegate(expected);
michael@0 289 performWait(fetchAllRunnable(session, delegate));
michael@0 290 performWait(finishRunnable(session, new ExpectFinishDelegate()));
michael@0 291 }
michael@0 292
michael@0 293 /*
michael@0 294 * Test storing identical records with different guids.
michael@0 295 * For bookmarks identical is defined by the following fields
michael@0 296 * being the same: title, uri, type, parentName
michael@0 297 */
michael@0 298 @Override
michael@0 299 public void testStoreIdenticalExceptGuid() {
michael@0 300 storeIdenticalExceptGuid(BookmarkHelpers.createBookmarkInMobileFolder1());
michael@0 301 }
michael@0 302
michael@0 303 /*
michael@0 304 * More complicated situation in which we insert a folder
michael@0 305 * followed by a couple of its children. We then insert
michael@0 306 * the folder again but with a different guid. Children
michael@0 307 * must still get correct parent when they are fetched.
michael@0 308 * Store a record after with the new guid as the parent
michael@0 309 * and make sure it works as well.
michael@0 310 */
michael@0 311 public void testStoreIdenticalFoldersWithChildren() {
michael@0 312 final RepositorySession session = createAndBeginSession();
michael@0 313 Record record0 = BookmarkHelpers.createFolder1();
michael@0 314
michael@0 315 // Get timestamp so that the conflicting folder that we store below is newer.
michael@0 316 // Children won't come back on this fetch since they haven't been stored, so remove them
michael@0 317 // before our delegate throws a failure.
michael@0 318 BookmarkRecord rec0 = (BookmarkRecord) record0;
michael@0 319 rec0.children = new JSONArray();
michael@0 320 performWait(storeRunnable(session, record0));
michael@0 321
michael@0 322 ExpectFetchDelegate timestampDelegate = preparedExpectFetchDelegate(new Record[] { rec0 });
michael@0 323 performWait(fetchRunnable(session, new String[] { record0.guid }, timestampDelegate));
michael@0 324
michael@0 325 AndroidBrowserRepositoryDataAccessor helper = getDataAccessor();
michael@0 326 helper.dumpDB();
michael@0 327 closeDataAccessor(helper);
michael@0 328
michael@0 329 Record record1 = BookmarkHelpers.createBookmark1();
michael@0 330 Record record2 = BookmarkHelpers.createBookmark2();
michael@0 331 Record record3 = BookmarkHelpers.createFolder1();
michael@0 332 BookmarkRecord bmk3 = (BookmarkRecord) record3;
michael@0 333 record3.guid = Utils.generateGuid();
michael@0 334 record3.lastModified = timestampDelegate.records.get(0).lastModified + 3000;
michael@0 335 assert(!record0.guid.equals(record3.guid));
michael@0 336
michael@0 337 // Store an additional record after inserting the duplicate folder
michael@0 338 // with new GUID. Make sure it comes back as well.
michael@0 339 Record record4 = BookmarkHelpers.createBookmark3();
michael@0 340 BookmarkRecord bmk4 = (BookmarkRecord) record4;
michael@0 341 bmk4.parentID = bmk3.guid;
michael@0 342 bmk4.parentName = bmk3.parentName;
michael@0 343
michael@0 344 doStore(session, new Record[] {
michael@0 345 record1, record2, record3, bmk4
michael@0 346 });
michael@0 347 BookmarkRecord bmk1 = (BookmarkRecord) record1;
michael@0 348 bmk1.parentID = record3.guid;
michael@0 349 BookmarkRecord bmk2 = (BookmarkRecord) record2;
michael@0 350 bmk2.parentID = record3.guid;
michael@0 351 Record[] expect = new Record[] {
michael@0 352 bmk1, bmk2, record3
michael@0 353 };
michael@0 354 fetchAllRunnable(session, preparedExpectFetchDelegate(expect));
michael@0 355 dispose(session);
michael@0 356 }
michael@0 357
michael@0 358 @Override
michael@0 359 public void testRemoteNewerTimeStamp() {
michael@0 360 BookmarkRecord local = BookmarkHelpers.createBookmarkInMobileFolder1();
michael@0 361 BookmarkRecord remote = BookmarkHelpers.createBookmarkInMobileFolder2();
michael@0 362 remoteNewerTimeStamp(local, remote);
michael@0 363 }
michael@0 364
michael@0 365 @Override
michael@0 366 public void testLocalNewerTimeStamp() {
michael@0 367 BookmarkRecord local = BookmarkHelpers.createBookmarkInMobileFolder1();
michael@0 368 BookmarkRecord remote = BookmarkHelpers.createBookmarkInMobileFolder2();
michael@0 369 localNewerTimeStamp(local, remote);
michael@0 370 }
michael@0 371
michael@0 372 @Override
michael@0 373 public void testDeleteRemoteNewer() {
michael@0 374 BookmarkRecord local = BookmarkHelpers.createBookmarkInMobileFolder1();
michael@0 375 BookmarkRecord remote = BookmarkHelpers.createBookmarkInMobileFolder2();
michael@0 376 deleteRemoteNewer(local, remote);
michael@0 377 }
michael@0 378
michael@0 379 @Override
michael@0 380 public void testDeleteLocalNewer() {
michael@0 381 BookmarkRecord local = BookmarkHelpers.createBookmarkInMobileFolder1();
michael@0 382 BookmarkRecord remote = BookmarkHelpers.createBookmarkInMobileFolder2();
michael@0 383 deleteLocalNewer(local, remote);
michael@0 384 }
michael@0 385
michael@0 386 @Override
michael@0 387 public void testDeleteRemoteLocalNonexistent() {
michael@0 388 BookmarkRecord remote = BookmarkHelpers.createBookmark2();
michael@0 389 deleteRemoteLocalNonexistent(remote);
michael@0 390 }
michael@0 391
michael@0 392 @Override
michael@0 393 public void testCleanMultipleRecords() {
michael@0 394 cleanMultipleRecords(
michael@0 395 BookmarkHelpers.createBookmarkInMobileFolder1(),
michael@0 396 BookmarkHelpers.createBookmarkInMobileFolder2(),
michael@0 397 BookmarkHelpers.createBookmark1(),
michael@0 398 BookmarkHelpers.createBookmark2(),
michael@0 399 BookmarkHelpers.createFolder1());
michael@0 400 }
michael@0 401
michael@0 402 public void testBasicPositioning() {
michael@0 403 final RepositorySession session = createAndBeginSession();
michael@0 404 Record[] expected = new Record[] {
michael@0 405 BookmarkHelpers.createBookmark1(),
michael@0 406 BookmarkHelpers.createFolder1(),
michael@0 407 BookmarkHelpers.createBookmark2()
michael@0 408 };
michael@0 409 System.out.println("TEST: Inserting " + expected[0].guid + ", "
michael@0 410 + expected[1].guid + ", "
michael@0 411 + expected[2].guid);
michael@0 412 doStore(session, expected);
michael@0 413
michael@0 414 ExpectFetchDelegate delegate = preparedExpectFetchDelegate(expected);
michael@0 415 performWait(fetchAllRunnable(session, delegate));
michael@0 416
michael@0 417 int found = 0;
michael@0 418 boolean foundFolder = false;
michael@0 419 for (int i = 0; i < delegate.records.size(); i++) {
michael@0 420 BookmarkRecord rec = (BookmarkRecord) delegate.records.get(i);
michael@0 421 if (rec.guid.equals(expected[0].guid)) {
michael@0 422 assertEquals(0, ((BookmarkRecord) delegate.records.get(i)).androidPosition);
michael@0 423 found++;
michael@0 424 } else if (rec.guid.equals(expected[2].guid)) {
michael@0 425 assertEquals(1, ((BookmarkRecord) delegate.records.get(i)).androidPosition);
michael@0 426 found++;
michael@0 427 } else if (rec.guid.equals(expected[1].guid)) {
michael@0 428 foundFolder = true;
michael@0 429 } else {
michael@0 430 System.out.println("TEST: found " + rec.guid);
michael@0 431 }
michael@0 432 }
michael@0 433 assertTrue(foundFolder);
michael@0 434 assertEquals(2, found);
michael@0 435 dispose(session);
michael@0 436 }
michael@0 437
michael@0 438 public void testSqlInjectPurgeDeleteAndUpdateByGuid() {
michael@0 439 // Some setup.
michael@0 440 RepositorySession session = createAndBeginSession();
michael@0 441 AndroidBrowserRepositoryDataAccessor db = getDataAccessor();
michael@0 442
michael@0 443 ContentValues cv = new ContentValues();
michael@0 444 cv.put(BrowserContract.SyncColumns.IS_DELETED, 1);
michael@0 445
michael@0 446 // Create and insert 2 bookmarks, 2nd one is evil (attempts injection).
michael@0 447 BookmarkRecord bmk1 = BookmarkHelpers.createBookmark1();
michael@0 448 BookmarkRecord bmk2 = BookmarkHelpers.createBookmark2();
michael@0 449 bmk2.guid = "' or '1'='1";
michael@0 450
michael@0 451 db.insert(bmk1);
michael@0 452 db.insert(bmk2);
michael@0 453
michael@0 454 // Test 1 - updateByGuid() handles evil bookmarks correctly.
michael@0 455 db.updateByGuid(bmk2.guid, cv);
michael@0 456
michael@0 457 // Query bookmarks table.
michael@0 458 Cursor cur = getAllBookmarks();
michael@0 459 int numBookmarks = cur.getCount();
michael@0 460
michael@0 461 // Ensure only the evil bookmark is marked for deletion.
michael@0 462 try {
michael@0 463 cur.moveToFirst();
michael@0 464 while (!cur.isAfterLast()) {
michael@0 465 String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID);
michael@0 466 boolean deleted = RepoUtils.getLongFromCursor(cur, BrowserContract.SyncColumns.IS_DELETED) == 1;
michael@0 467
michael@0 468 if (guid.equals(bmk2.guid)) {
michael@0 469 assertTrue(deleted);
michael@0 470 } else {
michael@0 471 assertFalse(deleted);
michael@0 472 }
michael@0 473 cur.moveToNext();
michael@0 474 }
michael@0 475 } finally {
michael@0 476 cur.close();
michael@0 477 }
michael@0 478
michael@0 479 // Test 2 - Ensure purgeDelete()'s call to delete() deletes only 1 record.
michael@0 480 try {
michael@0 481 db.purgeDeleted();
michael@0 482 } catch (NullCursorException e) {
michael@0 483 e.printStackTrace();
michael@0 484 }
michael@0 485
michael@0 486 cur = getAllBookmarks();
michael@0 487 int numBookmarksAfterDeletion = cur.getCount();
michael@0 488
michael@0 489 // Ensure we have only 1 deleted row.
michael@0 490 assertEquals(numBookmarksAfterDeletion, numBookmarks - 1);
michael@0 491
michael@0 492 // Ensure only the evil bookmark is deleted.
michael@0 493 try {
michael@0 494 cur.moveToFirst();
michael@0 495 while (!cur.isAfterLast()) {
michael@0 496 String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID);
michael@0 497 boolean deleted = RepoUtils.getLongFromCursor(cur, BrowserContract.SyncColumns.IS_DELETED) == 1;
michael@0 498
michael@0 499 if (guid.equals(bmk2.guid)) {
michael@0 500 fail("Evil guid was not deleted!");
michael@0 501 } else {
michael@0 502 assertFalse(deleted);
michael@0 503 }
michael@0 504 cur.moveToNext();
michael@0 505 }
michael@0 506 } finally {
michael@0 507 cur.close();
michael@0 508 }
michael@0 509 dispose(session);
michael@0 510 }
michael@0 511
michael@0 512 protected Cursor getAllBookmarks() {
michael@0 513 Context context = getApplicationContext();
michael@0 514 Cursor cur = context.getContentResolver().query(BrowserContractHelpers.BOOKMARKS_CONTENT_URI,
michael@0 515 BrowserContractHelpers.BookmarkColumns, null, null, null);
michael@0 516 return cur;
michael@0 517 }
michael@0 518
michael@0 519 public void testSqlInjectFetch() {
michael@0 520 // Some setup.
michael@0 521 RepositorySession session = createAndBeginSession();
michael@0 522 AndroidBrowserRepositoryDataAccessor db = getDataAccessor();
michael@0 523
michael@0 524 // Create and insert 4 bookmarks, last one is evil (attempts injection).
michael@0 525 BookmarkRecord bmk1 = BookmarkHelpers.createBookmark1();
michael@0 526 BookmarkRecord bmk2 = BookmarkHelpers.createBookmark2();
michael@0 527 BookmarkRecord bmk3 = BookmarkHelpers.createBookmark3();
michael@0 528 BookmarkRecord bmk4 = BookmarkHelpers.createBookmark4();
michael@0 529 bmk4.guid = "' or '1'='1";
michael@0 530
michael@0 531 db.insert(bmk1);
michael@0 532 db.insert(bmk2);
michael@0 533 db.insert(bmk3);
michael@0 534 db.insert(bmk4);
michael@0 535
michael@0 536 // Perform a fetch.
michael@0 537 Cursor cur = null;
michael@0 538 try {
michael@0 539 cur = db.fetch(new String[] { bmk3.guid, bmk4.guid });
michael@0 540 } catch (NullCursorException e1) {
michael@0 541 e1.printStackTrace();
michael@0 542 }
michael@0 543
michael@0 544 // Ensure the correct number (2) of records were fetched and with the correct guids.
michael@0 545 if (cur == null) {
michael@0 546 fail("No records were fetched.");
michael@0 547 }
michael@0 548
michael@0 549 try {
michael@0 550 if (cur.getCount() != 2) {
michael@0 551 fail("Wrong number of guids fetched!");
michael@0 552 }
michael@0 553 cur.moveToFirst();
michael@0 554 while (!cur.isAfterLast()) {
michael@0 555 String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID);
michael@0 556 if (!guid.equals(bmk3.guid) && !guid.equals(bmk4.guid)) {
michael@0 557 fail("Wrong guids were fetched!");
michael@0 558 }
michael@0 559 cur.moveToNext();
michael@0 560 }
michael@0 561 } finally {
michael@0 562 cur.close();
michael@0 563 }
michael@0 564 dispose(session);
michael@0 565 }
michael@0 566
michael@0 567 public void testSqlInjectDelete() {
michael@0 568 // Some setup.
michael@0 569 RepositorySession session = createAndBeginSession();
michael@0 570 AndroidBrowserRepositoryDataAccessor db = getDataAccessor();
michael@0 571
michael@0 572 // Create and insert 2 bookmarks, 2nd one is evil (attempts injection).
michael@0 573 BookmarkRecord bmk1 = BookmarkHelpers.createBookmark1();
michael@0 574 BookmarkRecord bmk2 = BookmarkHelpers.createBookmark2();
michael@0 575 bmk2.guid = "' or '1'='1";
michael@0 576
michael@0 577 db.insert(bmk1);
michael@0 578 db.insert(bmk2);
michael@0 579
michael@0 580 // Note size of table before delete.
michael@0 581 Cursor cur = getAllBookmarks();
michael@0 582 int numBookmarks = cur.getCount();
michael@0 583
michael@0 584 db.purgeGuid(bmk2.guid);
michael@0 585
michael@0 586 // Note size of table after delete.
michael@0 587 cur = getAllBookmarks();
michael@0 588 int numBookmarksAfterDelete = cur.getCount();
michael@0 589
michael@0 590 // Ensure size of table after delete is *only* 1 less.
michael@0 591 assertEquals(numBookmarksAfterDelete, numBookmarks - 1);
michael@0 592
michael@0 593 try {
michael@0 594 cur.moveToFirst();
michael@0 595 while (!cur.isAfterLast()) {
michael@0 596 String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID);
michael@0 597 if (guid.equals(bmk2.guid)) {
michael@0 598 fail("Guid was not deleted!");
michael@0 599 }
michael@0 600 cur.moveToNext();
michael@0 601 }
michael@0 602 } finally {
michael@0 603 cur.close();
michael@0 604 }
michael@0 605 dispose(session);
michael@0 606 }
michael@0 607
michael@0 608 /**
michael@0 609 * Verify that data accessor's bulkInsert actually inserts.
michael@0 610 * @throws NullCursorException
michael@0 611 */
michael@0 612 public void testBulkInsert() throws NullCursorException {
michael@0 613 RepositorySession session = createAndBeginSession();
michael@0 614 AndroidBrowserRepositoryDataAccessor db = getDataAccessor();
michael@0 615
michael@0 616 // Have to set androidID of parent manually.
michael@0 617 Cursor cur = db.fetch(new String[] { "mobile" } );
michael@0 618 assertEquals(1, cur.getCount());
michael@0 619 cur.moveToFirst();
michael@0 620 int mobileAndroidID = RepoUtils.getIntFromCursor(cur, BrowserContract.Bookmarks._ID);
michael@0 621
michael@0 622 BookmarkRecord bookmark1 = BookmarkHelpers.createBookmarkInMobileFolder1();
michael@0 623 BookmarkRecord bookmark2 = BookmarkHelpers.createBookmarkInMobileFolder2();
michael@0 624 bookmark1.androidParentID = mobileAndroidID;
michael@0 625 bookmark2.androidParentID = mobileAndroidID;
michael@0 626 ArrayList<Record> recordList = new ArrayList<Record>();
michael@0 627 recordList.add(bookmark1);
michael@0 628 recordList.add(bookmark2);
michael@0 629 db.bulkInsert(recordList);
michael@0 630
michael@0 631 String[] guids = new String[] { bookmark1.guid, bookmark2.guid };
michael@0 632 Record[] expected = new Record[] { bookmark1, bookmark2 };
michael@0 633 performWait(fetchRunnable(session, guids, expected));
michael@0 634 dispose(session);
michael@0 635 }
michael@0 636 }

mercurial