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.

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

mercurial