Wed, 31 Dec 2014 07:22:50 +0100
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 org.json.simple.JSONArray; |
michael@0 | 7 | import org.mozilla.gecko.background.helpers.AndroidSyncTestCase; |
michael@0 | 8 | import org.mozilla.gecko.background.sync.helpers.ExpectFetchDelegate; |
michael@0 | 9 | import org.mozilla.gecko.background.sync.helpers.SessionTestHelper; |
michael@0 | 10 | import org.mozilla.gecko.db.BrowserContract; |
michael@0 | 11 | import org.mozilla.gecko.sync.repositories.NoContentProviderException; |
michael@0 | 12 | import org.mozilla.gecko.sync.repositories.RepositorySession; |
michael@0 | 13 | import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers; |
michael@0 | 14 | import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository; |
michael@0 | 15 | import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository.FennecTabsRepositorySession; |
michael@0 | 16 | import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate; |
michael@0 | 17 | import org.mozilla.gecko.sync.repositories.domain.Record; |
michael@0 | 18 | import org.mozilla.gecko.sync.repositories.domain.TabsRecord; |
michael@0 | 19 | |
michael@0 | 20 | import android.content.ContentProviderClient; |
michael@0 | 21 | import android.content.ContentResolver; |
michael@0 | 22 | import android.content.Context; |
michael@0 | 23 | import android.database.Cursor; |
michael@0 | 24 | import android.os.RemoteException; |
michael@0 | 25 | |
michael@0 | 26 | public class TestFennecTabsRepositorySession extends AndroidSyncTestCase { |
michael@0 | 27 | public static final String TEST_CLIENT_GUID = "test guid"; // Real GUIDs never contain spaces. |
michael@0 | 28 | public static final String TEST_CLIENT_NAME = "test client name"; |
michael@0 | 29 | |
michael@0 | 30 | // Override these to test against data that is not live. |
michael@0 | 31 | public static final String TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION = BrowserContract.Tabs.CLIENT_GUID + " IS ?"; |
michael@0 | 32 | public static final String[] TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION_ARGS = new String[] { TEST_CLIENT_GUID }; |
michael@0 | 33 | |
michael@0 | 34 | protected ContentProviderClient tabsClient = null; |
michael@0 | 35 | |
michael@0 | 36 | protected ContentProviderClient getTabsClient() { |
michael@0 | 37 | final ContentResolver cr = getApplicationContext().getContentResolver(); |
michael@0 | 38 | return cr.acquireContentProviderClient(BrowserContractHelpers.TABS_CONTENT_URI); |
michael@0 | 39 | } |
michael@0 | 40 | |
michael@0 | 41 | public TestFennecTabsRepositorySession() throws NoContentProviderException { |
michael@0 | 42 | super(); |
michael@0 | 43 | } |
michael@0 | 44 | |
michael@0 | 45 | @Override |
michael@0 | 46 | public void setUp() { |
michael@0 | 47 | if (tabsClient == null) { |
michael@0 | 48 | tabsClient = getTabsClient(); |
michael@0 | 49 | } |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | protected int deleteAllTestTabs(final ContentProviderClient tabsClient) throws RemoteException { |
michael@0 | 53 | if (tabsClient == null) { |
michael@0 | 54 | return -1; |
michael@0 | 55 | } |
michael@0 | 56 | return tabsClient.delete(BrowserContractHelpers.TABS_CONTENT_URI, |
michael@0 | 57 | TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION, TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION_ARGS); |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | @Override |
michael@0 | 61 | protected void tearDown() throws Exception { |
michael@0 | 62 | if (tabsClient != null) { |
michael@0 | 63 | deleteAllTestTabs(tabsClient); |
michael@0 | 64 | |
michael@0 | 65 | tabsClient.release(); |
michael@0 | 66 | tabsClient = null; |
michael@0 | 67 | } |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | protected FennecTabsRepository getRepository() { |
michael@0 | 71 | /** |
michael@0 | 72 | * Override this chain in order to avoid our test code having to create two |
michael@0 | 73 | * sessions all the time. |
michael@0 | 74 | */ |
michael@0 | 75 | return new FennecTabsRepository(TEST_CLIENT_NAME, TEST_CLIENT_GUID) { |
michael@0 | 76 | @Override |
michael@0 | 77 | public void createSession(RepositorySessionCreationDelegate delegate, |
michael@0 | 78 | Context context) { |
michael@0 | 79 | try { |
michael@0 | 80 | final FennecTabsRepositorySession session = new FennecTabsRepositorySession(this, context) { |
michael@0 | 81 | @Override |
michael@0 | 82 | protected synchronized void trackGUID(String guid) { |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | @Override |
michael@0 | 86 | protected String localClientSelection() { |
michael@0 | 87 | return TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION; |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | @Override |
michael@0 | 91 | protected String[] localClientSelectionArgs() { |
michael@0 | 92 | return TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION_ARGS; |
michael@0 | 93 | } |
michael@0 | 94 | }; |
michael@0 | 95 | delegate.onSessionCreated(session); |
michael@0 | 96 | } catch (Exception e) { |
michael@0 | 97 | delegate.onSessionCreateFailed(e); |
michael@0 | 98 | } |
michael@0 | 99 | } |
michael@0 | 100 | }; |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | protected FennecTabsRepositorySession createSession() { |
michael@0 | 104 | return (FennecTabsRepositorySession) SessionTestHelper.createSession( |
michael@0 | 105 | getApplicationContext(), |
michael@0 | 106 | getRepository()); |
michael@0 | 107 | } |
michael@0 | 108 | |
michael@0 | 109 | protected FennecTabsRepositorySession createAndBeginSession() { |
michael@0 | 110 | return (FennecTabsRepositorySession) SessionTestHelper.createAndBeginSession( |
michael@0 | 111 | getApplicationContext(), |
michael@0 | 112 | getRepository()); |
michael@0 | 113 | } |
michael@0 | 114 | |
michael@0 | 115 | protected Runnable fetchSinceRunnable(final RepositorySession session, final long timestamp, final Record[] expectedRecords) { |
michael@0 | 116 | return new Runnable() { |
michael@0 | 117 | @Override |
michael@0 | 118 | public void run() { |
michael@0 | 119 | session.fetchSince(timestamp, new ExpectFetchDelegate(expectedRecords)); |
michael@0 | 120 | } |
michael@0 | 121 | }; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | protected Runnable fetchAllRunnable(final RepositorySession session, final Record[] expectedRecords) { |
michael@0 | 125 | return new Runnable() { |
michael@0 | 126 | @Override |
michael@0 | 127 | public void run() { |
michael@0 | 128 | session.fetchAll(new ExpectFetchDelegate(expectedRecords)); |
michael@0 | 129 | } |
michael@0 | 130 | }; |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | protected Tab testTab1; |
michael@0 | 134 | protected Tab testTab2; |
michael@0 | 135 | protected Tab testTab3; |
michael@0 | 136 | |
michael@0 | 137 | @SuppressWarnings("unchecked") |
michael@0 | 138 | private void insertSomeTestTabs(ContentProviderClient tabsClient) throws RemoteException { |
michael@0 | 139 | final JSONArray history1 = new JSONArray(); |
michael@0 | 140 | history1.add("http://test.com/test1.html"); |
michael@0 | 141 | testTab1 = new Tab("test title 1", "http://test.com/test1.png", history1, 1000); |
michael@0 | 142 | |
michael@0 | 143 | final JSONArray history2 = new JSONArray(); |
michael@0 | 144 | history2.add("http://test.com/test2.html#1"); |
michael@0 | 145 | history2.add("http://test.com/test2.html#2"); |
michael@0 | 146 | history2.add("http://test.com/test2.html#3"); |
michael@0 | 147 | testTab2 = new Tab("test title 2", "http://test.com/test2.png", history2, 2000); |
michael@0 | 148 | |
michael@0 | 149 | final JSONArray history3 = new JSONArray(); |
michael@0 | 150 | history3.add("http://test.com/test3.html#1"); |
michael@0 | 151 | history3.add("http://test.com/test3.html#2"); |
michael@0 | 152 | testTab3 = new Tab("test title 3", "http://test.com/test3.png", history3, 3000); |
michael@0 | 153 | |
michael@0 | 154 | tabsClient.insert(BrowserContractHelpers.TABS_CONTENT_URI, testTab1.toContentValues(TEST_CLIENT_GUID, 0)); |
michael@0 | 155 | tabsClient.insert(BrowserContractHelpers.TABS_CONTENT_URI, testTab2.toContentValues(TEST_CLIENT_GUID, 1)); |
michael@0 | 156 | tabsClient.insert(BrowserContractHelpers.TABS_CONTENT_URI, testTab3.toContentValues(TEST_CLIENT_GUID, 2)); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | protected TabsRecord insertTestTabsAndExtractTabsRecord() throws RemoteException { |
michael@0 | 160 | insertSomeTestTabs(tabsClient); |
michael@0 | 161 | |
michael@0 | 162 | final String positionAscending = BrowserContract.Tabs.POSITION + " ASC"; |
michael@0 | 163 | Cursor cursor = null; |
michael@0 | 164 | try { |
michael@0 | 165 | cursor = tabsClient.query(BrowserContractHelpers.TABS_CONTENT_URI, null, |
michael@0 | 166 | TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION, TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION_ARGS, positionAscending); |
michael@0 | 167 | CursorDumper.dumpCursor(cursor); |
michael@0 | 168 | |
michael@0 | 169 | final TabsRecord tabsRecord = FennecTabsRepository.tabsRecordFromCursor(cursor, TEST_CLIENT_GUID, TEST_CLIENT_NAME); |
michael@0 | 170 | |
michael@0 | 171 | assertEquals(TEST_CLIENT_GUID, tabsRecord.guid); |
michael@0 | 172 | assertEquals(TEST_CLIENT_NAME, tabsRecord.clientName); |
michael@0 | 173 | |
michael@0 | 174 | assertNotNull(tabsRecord.tabs); |
michael@0 | 175 | assertEquals(cursor.getCount(), tabsRecord.tabs.size()); |
michael@0 | 176 | |
michael@0 | 177 | return tabsRecord; |
michael@0 | 178 | } finally { |
michael@0 | 179 | cursor.close(); |
michael@0 | 180 | } |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | public void testFetchAll() throws NoContentProviderException, RemoteException { |
michael@0 | 184 | final TabsRecord tabsRecord = insertTestTabsAndExtractTabsRecord(); |
michael@0 | 185 | |
michael@0 | 186 | final FennecTabsRepositorySession session = createAndBeginSession(); |
michael@0 | 187 | performWait(fetchAllRunnable(session, new Record[] { tabsRecord })); |
michael@0 | 188 | |
michael@0 | 189 | session.abort(); |
michael@0 | 190 | } |
michael@0 | 191 | |
michael@0 | 192 | public void testFetchSince() throws NoContentProviderException, RemoteException { |
michael@0 | 193 | final TabsRecord tabsRecord = insertTestTabsAndExtractTabsRecord(); |
michael@0 | 194 | |
michael@0 | 195 | final FennecTabsRepositorySession session = createAndBeginSession(); |
michael@0 | 196 | |
michael@0 | 197 | // Not all tabs are modified after this, but the record should contain them all. |
michael@0 | 198 | performWait(fetchSinceRunnable(session, 1000, new Record[] { tabsRecord })); |
michael@0 | 199 | |
michael@0 | 200 | // No tabs are modified after this, so we shouldn't get a record at all. |
michael@0 | 201 | performWait(fetchSinceRunnable(session, 4000, new Record[] { })); |
michael@0 | 202 | |
michael@0 | 203 | session.abort(); |
michael@0 | 204 | } |
michael@0 | 205 | } |