michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: package org.mozilla.gecko.background.db; michael@0: michael@0: import java.io.IOException; michael@0: import java.util.ArrayList; michael@0: michael@0: import org.json.simple.JSONArray; michael@0: import org.json.simple.JSONObject; michael@0: import org.json.simple.parser.ParseException; michael@0: import org.mozilla.gecko.background.helpers.AndroidSyncTestCase; michael@0: import org.mozilla.gecko.background.sync.helpers.HistoryHelpers; michael@0: import org.mozilla.gecko.sync.ExtendedJSONObject; michael@0: import org.mozilla.gecko.sync.NonArrayJSONException; michael@0: import org.mozilla.gecko.sync.NonObjectJSONException; michael@0: import org.mozilla.gecko.sync.Utils; michael@0: import org.mozilla.gecko.sync.repositories.NullCursorException; michael@0: import org.mozilla.gecko.sync.repositories.android.AndroidBrowserHistoryDataExtender; michael@0: import org.mozilla.gecko.sync.repositories.android.RepoUtils; michael@0: import org.mozilla.gecko.sync.repositories.domain.HistoryRecord; michael@0: michael@0: import android.database.Cursor; michael@0: michael@0: public class TestAndroidBrowserHistoryDataExtender extends AndroidSyncTestCase { michael@0: michael@0: protected AndroidBrowserHistoryDataExtender extender; michael@0: protected static final String LOG_TAG = "SyncHistoryVisitsTest"; michael@0: michael@0: public void setUp() { michael@0: extender = new AndroidBrowserHistoryDataExtender(getApplicationContext()); michael@0: extender.wipe(); michael@0: } michael@0: michael@0: public void tearDown() { michael@0: extender.close(); michael@0: } michael@0: michael@0: public void testStoreFetch() throws NullCursorException, NonObjectJSONException, IOException, ParseException { michael@0: String guid = Utils.generateGuid(); michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(guid, null); michael@0: extender.store(Utils.generateGuid(), null); michael@0: michael@0: Cursor cur = null; michael@0: try { michael@0: cur = extender.fetch(guid); michael@0: assertEquals(1, cur.getCount()); michael@0: assertTrue(cur.moveToFirst()); michael@0: assertEquals(guid, cur.getString(0)); michael@0: } finally { michael@0: if (cur != null) { michael@0: cur.close(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: public void testVisitsForGUID() throws NonArrayJSONException, NonObjectJSONException, IOException, ParseException, NullCursorException { michael@0: String guid = Utils.generateGuid(); michael@0: JSONArray visits = new ExtendedJSONObject("{ \"visits\": [ { \"key\" : \"value\" } ] }").getArray("visits"); michael@0: michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(guid, visits); michael@0: extender.store(Utils.generateGuid(), null); michael@0: michael@0: JSONArray fetchedVisits = extender.visitsForGUID(guid); michael@0: assertEquals(1, fetchedVisits.size()); michael@0: assertEquals("value", ((JSONObject)fetchedVisits.get(0)).get("key")); michael@0: } michael@0: michael@0: public void testDeleteHandlesBadGUIDs() { michael@0: String evilGUID = "' or '1'='1"; michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(evilGUID, null); michael@0: extender.delete(evilGUID); michael@0: michael@0: Cursor cur = null; michael@0: try { michael@0: cur = extender.fetchAll(); michael@0: assertEquals(cur.getCount(), 2); michael@0: assertTrue(cur.moveToFirst()); michael@0: while (!cur.isAfterLast()) { michael@0: String guid = RepoUtils.getStringFromCursor(cur, AndroidBrowserHistoryDataExtender.COL_GUID); michael@0: assertFalse(evilGUID.equals(guid)); michael@0: cur.moveToNext(); michael@0: } michael@0: } catch (NullCursorException e) { michael@0: e.printStackTrace(); michael@0: fail("Should not have null cursor."); michael@0: } finally { michael@0: if (cur != null) { michael@0: cur.close(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: public void testStoreFetchHandlesBadGUIDs() { michael@0: String evilGUID = "' or '1'='1"; michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(Utils.generateGuid(), null); michael@0: extender.store(evilGUID, null); michael@0: michael@0: Cursor cur = null; michael@0: try { michael@0: cur = extender.fetch(evilGUID); michael@0: assertEquals(1, cur.getCount()); michael@0: assertTrue(cur.moveToFirst()); michael@0: while (!cur.isAfterLast()) { michael@0: String guid = RepoUtils.getStringFromCursor(cur, AndroidBrowserHistoryDataExtender.COL_GUID); michael@0: assertEquals(evilGUID, guid); michael@0: cur.moveToNext(); michael@0: } michael@0: } catch (NullCursorException e) { michael@0: e.printStackTrace(); michael@0: fail("Should not have null cursor."); michael@0: } finally { michael@0: if (cur != null) { michael@0: cur.close(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: public void testBulkInsert() throws NullCursorException { michael@0: ArrayList records = new ArrayList(); michael@0: records.add(HistoryHelpers.createHistory1()); michael@0: records.add(HistoryHelpers.createHistory2()); michael@0: extender.bulkInsert(records); michael@0: michael@0: for (HistoryRecord record : records) { michael@0: HistoryRecord toCompare = (HistoryRecord) record.copyWithIDs(record.guid, record.androidID); michael@0: toCompare.visits = extender.visitsForGUID(record.guid); michael@0: assertEquals(record.visits.size(), toCompare.visits.size()); michael@0: assertTrue(record.equals(toCompare)); michael@0: } michael@0: michael@0: // Now insert existing records, changing one, and add another record. michael@0: records.get(0).title = "test"; michael@0: records.add(HistoryHelpers.createHistory3()); michael@0: extender.bulkInsert(records); michael@0: michael@0: for (HistoryRecord record : records) { michael@0: HistoryRecord toCompare = (HistoryRecord) record.copyWithIDs(record.guid, record.androidID); michael@0: toCompare.visits = extender.visitsForGUID(record.guid); michael@0: assertEquals(record.visits.size(), toCompare.visits.size()); michael@0: assertTrue(record.equals(toCompare)); michael@0: } michael@0: } michael@0: }