|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 package org.mozilla.gecko.background.db; |
|
5 |
|
6 import java.io.IOException; |
|
7 import java.util.ArrayList; |
|
8 |
|
9 import org.json.simple.JSONArray; |
|
10 import org.json.simple.JSONObject; |
|
11 import org.json.simple.parser.ParseException; |
|
12 import org.mozilla.gecko.background.helpers.AndroidSyncTestCase; |
|
13 import org.mozilla.gecko.background.sync.helpers.HistoryHelpers; |
|
14 import org.mozilla.gecko.sync.ExtendedJSONObject; |
|
15 import org.mozilla.gecko.sync.NonArrayJSONException; |
|
16 import org.mozilla.gecko.sync.NonObjectJSONException; |
|
17 import org.mozilla.gecko.sync.Utils; |
|
18 import org.mozilla.gecko.sync.repositories.NullCursorException; |
|
19 import org.mozilla.gecko.sync.repositories.android.AndroidBrowserHistoryDataExtender; |
|
20 import org.mozilla.gecko.sync.repositories.android.RepoUtils; |
|
21 import org.mozilla.gecko.sync.repositories.domain.HistoryRecord; |
|
22 |
|
23 import android.database.Cursor; |
|
24 |
|
25 public class TestAndroidBrowserHistoryDataExtender extends AndroidSyncTestCase { |
|
26 |
|
27 protected AndroidBrowserHistoryDataExtender extender; |
|
28 protected static final String LOG_TAG = "SyncHistoryVisitsTest"; |
|
29 |
|
30 public void setUp() { |
|
31 extender = new AndroidBrowserHistoryDataExtender(getApplicationContext()); |
|
32 extender.wipe(); |
|
33 } |
|
34 |
|
35 public void tearDown() { |
|
36 extender.close(); |
|
37 } |
|
38 |
|
39 public void testStoreFetch() throws NullCursorException, NonObjectJSONException, IOException, ParseException { |
|
40 String guid = Utils.generateGuid(); |
|
41 extender.store(Utils.generateGuid(), null); |
|
42 extender.store(guid, null); |
|
43 extender.store(Utils.generateGuid(), null); |
|
44 |
|
45 Cursor cur = null; |
|
46 try { |
|
47 cur = extender.fetch(guid); |
|
48 assertEquals(1, cur.getCount()); |
|
49 assertTrue(cur.moveToFirst()); |
|
50 assertEquals(guid, cur.getString(0)); |
|
51 } finally { |
|
52 if (cur != null) { |
|
53 cur.close(); |
|
54 } |
|
55 } |
|
56 } |
|
57 |
|
58 public void testVisitsForGUID() throws NonArrayJSONException, NonObjectJSONException, IOException, ParseException, NullCursorException { |
|
59 String guid = Utils.generateGuid(); |
|
60 JSONArray visits = new ExtendedJSONObject("{ \"visits\": [ { \"key\" : \"value\" } ] }").getArray("visits"); |
|
61 |
|
62 extender.store(Utils.generateGuid(), null); |
|
63 extender.store(guid, visits); |
|
64 extender.store(Utils.generateGuid(), null); |
|
65 |
|
66 JSONArray fetchedVisits = extender.visitsForGUID(guid); |
|
67 assertEquals(1, fetchedVisits.size()); |
|
68 assertEquals("value", ((JSONObject)fetchedVisits.get(0)).get("key")); |
|
69 } |
|
70 |
|
71 public void testDeleteHandlesBadGUIDs() { |
|
72 String evilGUID = "' or '1'='1"; |
|
73 extender.store(Utils.generateGuid(), null); |
|
74 extender.store(Utils.generateGuid(), null); |
|
75 extender.store(evilGUID, null); |
|
76 extender.delete(evilGUID); |
|
77 |
|
78 Cursor cur = null; |
|
79 try { |
|
80 cur = extender.fetchAll(); |
|
81 assertEquals(cur.getCount(), 2); |
|
82 assertTrue(cur.moveToFirst()); |
|
83 while (!cur.isAfterLast()) { |
|
84 String guid = RepoUtils.getStringFromCursor(cur, AndroidBrowserHistoryDataExtender.COL_GUID); |
|
85 assertFalse(evilGUID.equals(guid)); |
|
86 cur.moveToNext(); |
|
87 } |
|
88 } catch (NullCursorException e) { |
|
89 e.printStackTrace(); |
|
90 fail("Should not have null cursor."); |
|
91 } finally { |
|
92 if (cur != null) { |
|
93 cur.close(); |
|
94 } |
|
95 } |
|
96 } |
|
97 |
|
98 public void testStoreFetchHandlesBadGUIDs() { |
|
99 String evilGUID = "' or '1'='1"; |
|
100 extender.store(Utils.generateGuid(), null); |
|
101 extender.store(Utils.generateGuid(), null); |
|
102 extender.store(evilGUID, null); |
|
103 |
|
104 Cursor cur = null; |
|
105 try { |
|
106 cur = extender.fetch(evilGUID); |
|
107 assertEquals(1, cur.getCount()); |
|
108 assertTrue(cur.moveToFirst()); |
|
109 while (!cur.isAfterLast()) { |
|
110 String guid = RepoUtils.getStringFromCursor(cur, AndroidBrowserHistoryDataExtender.COL_GUID); |
|
111 assertEquals(evilGUID, guid); |
|
112 cur.moveToNext(); |
|
113 } |
|
114 } catch (NullCursorException e) { |
|
115 e.printStackTrace(); |
|
116 fail("Should not have null cursor."); |
|
117 } finally { |
|
118 if (cur != null) { |
|
119 cur.close(); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 public void testBulkInsert() throws NullCursorException { |
|
125 ArrayList<HistoryRecord> records = new ArrayList<HistoryRecord>(); |
|
126 records.add(HistoryHelpers.createHistory1()); |
|
127 records.add(HistoryHelpers.createHistory2()); |
|
128 extender.bulkInsert(records); |
|
129 |
|
130 for (HistoryRecord record : records) { |
|
131 HistoryRecord toCompare = (HistoryRecord) record.copyWithIDs(record.guid, record.androidID); |
|
132 toCompare.visits = extender.visitsForGUID(record.guid); |
|
133 assertEquals(record.visits.size(), toCompare.visits.size()); |
|
134 assertTrue(record.equals(toCompare)); |
|
135 } |
|
136 |
|
137 // Now insert existing records, changing one, and add another record. |
|
138 records.get(0).title = "test"; |
|
139 records.add(HistoryHelpers.createHistory3()); |
|
140 extender.bulkInsert(records); |
|
141 |
|
142 for (HistoryRecord record : records) { |
|
143 HistoryRecord toCompare = (HistoryRecord) record.copyWithIDs(record.guid, record.androidID); |
|
144 toCompare.visits = extender.visitsForGUID(record.guid); |
|
145 assertEquals(record.visits.size(), toCompare.visits.size()); |
|
146 assertTrue(record.equals(toCompare)); |
|
147 } |
|
148 } |
|
149 } |