Bug 1293710 - Add unit tests for highlights query. r?ahunt draft
authorSebastian Kaspari <s.kaspari@gmail.com>
Fri, 02 Sep 2016 19:31:49 +0200
changeset 409818 c459babfb73fcfd0436034a5afcced7cea0b140e
parent 409817 d150ae9341171be9b39a67e314e794f368bcb132
child 530421 a5e8283517c7676a364e41a42acc49ee1158352c
push id28557
push users.kaspari@gmail.com
push dateMon, 05 Sep 2016 07:55:10 +0000
reviewersahunt
bugs1293710
milestone51.0a1
Bug 1293710 - Add unit tests for highlights query. r?ahunt MozReview-Commit-ID: DX1AM9wsCMn
mobile/android/tests/background/junit4/src/org/mozilla/gecko/db/BrowserProviderHighlightsTest.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/db/BrowserProviderHistoryVisitsTestBase.java
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/db/BrowserProviderHighlightsTest.java
@@ -0,0 +1,346 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.db;
+
+import android.content.ContentProviderClient;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
+import org.mozilla.gecko.sync.setup.Constants;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import static org.mozilla.gecko.db.BrowserContract.PARAM_PROFILE;
+
+/**
+ * Unit tests for the highlights query (Activity Stream).
+ */
+@RunWith(TestRunner.class)
+public class BrowserProviderHighlightsTest extends BrowserProviderHistoryVisitsTestBase {
+    private ContentProviderClient highlightsClient;
+    private ContentProviderClient bookmarksClient;
+
+    private Uri highlightsTestUri;
+    private Uri bookmarksTestUri;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final Uri highlightsClientUri = BrowserContract.Highlights.CONTENT_URI.buildUpon()
+                .appendQueryParameter(PARAM_PROFILE, Constants.DEFAULT_PROFILE)
+                .build();
+
+        highlightsClient = contentResolver.acquireContentProviderClient(highlightsClientUri);
+        bookmarksClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.BOOKMARKS_CONTENT_URI);
+
+        highlightsTestUri = testUri(BrowserContract.Highlights.CONTENT_URI);
+        bookmarksTestUri = testUri(BrowserContract.Bookmarks.CONTENT_URI);
+    }
+
+    @After
+    public void tearDown() {
+        highlightsClient.release();
+        bookmarksClient.release();
+
+        super.tearDown();
+    }
+
+    /**
+     * Scenario: Empty database, no history, no bookmarks.
+     *
+     * Assert that:
+     *  - Empty cursor (not null) is returned.
+     */
+    @Test
+    public void testEmptyDatabase() throws Exception {
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(0, cursor.getCount());
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: The database only contains very recent history (now, 5 minutes ago, 20 minutes).
+     *
+     * Assert that:
+     *  - No highlight is returned from recent history.
+     */
+    @Test
+    public void testOnlyRecentHistory() throws Exception {
+        final long now = System.currentTimeMillis();
+        final long fiveMinutesAgo = now - 1000 * 60 * 5;
+        final long twentyMinutes = now - 1000 * 60 * 20;
+
+        insertHistoryItem(createUniqueUrl(), createGUID(), now, 1, createUniqueTitle());
+        insertHistoryItem(createUniqueUrl(), createGUID(), fiveMinutesAgo, 1, createUniqueTitle());
+        insertHistoryItem(createUniqueUrl(), createGUID(), twentyMinutes, 1, createUniqueTitle());
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(0, cursor.getCount());
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: The database contains recent (but not too fresh) history (1 hour, 5 days).
+     *
+     * Assert that:
+     *  - Highlights are returned from history.
+     */
+    @Test
+    public void testHighlightsArePickedFromHistory() throws Exception {
+        final String url1 = createUniqueUrl();
+        final String url2 = createUniqueUrl();
+        final String title1 = createUniqueTitle();
+        final String title2 = createUniqueTitle();
+
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+        final long fiveDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 5;
+
+        insertHistoryItem(url1, createGUID(), oneHourAgo, 1, title1);
+        insertHistoryItem(url2, createGUID(), fiveDaysAgo, 1, title2);
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(2, cursor.getCount());
+
+        assertCursorContainsEntry(cursor, url1, title1);
+        assertCursorContainsEntry(cursor, url2, title2);
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: The database contains history that is visited frequently and rarely.
+     *
+     * Assert that:
+     *  - Highlights are picked from rarely visited websites.
+     *  - Highlights are not picked from frequently visited websites.
+     */
+    @Test
+    public void testOftenVisitedPagesAreNotPicked() throws Exception {
+        final String url1 = createUniqueUrl();
+        final String title1 = createUniqueTitle();
+
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+        final long fiveDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 5;
+
+        insertHistoryItem(url1, createGUID(), oneHourAgo, 2, title1);
+        insertHistoryItem(createUniqueUrl(), createGUID(), fiveDaysAgo, 25, createUniqueTitle());
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        // Verify that only the first URL (with one visit) is picked and the second URL with 25 visits is ignored.
+
+        Assert.assertEquals(1, cursor.getCount());
+
+        cursor.moveToNext();
+        assertCursor(cursor, url1, title1);
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: The database contains history with and without titles.
+     *
+     * Assert that:
+     * - History without titles is not picked for highlights.
+     */
+    @Test
+    public void testHistoryWithoutTitlesIsNotPicked() throws Exception {
+        final String url1 = createUniqueUrl();
+        final String url2 = createUniqueUrl();
+        final String title1 = "";
+        final String title2 = createUniqueTitle();
+
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+        final long fiveDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 5;
+
+        insertHistoryItem(url1, createGUID(), oneHourAgo, 1, title1);
+        insertHistoryItem(url2, createGUID(), fiveDaysAgo, 1, title2);
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        // Only one bookmark will be picked for highlights
+        Assert.assertEquals(1, cursor.getCount());
+
+        cursor.moveToNext();
+        assertCursor(cursor, url2, title2);
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: Database contains two bookmarks (unvisited).
+     *
+     * Assert that:
+     *  - One bookmark is picked for highlights.
+     */
+    @Test
+    public void testPickingBookmarkForHighlights() throws Exception {
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+        final long fiveDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 5;
+
+        final String url1 = createUniqueUrl();
+        final String url2 = createUniqueUrl();
+        final String title1 = createUniqueTitle();
+        final String title2 = createUniqueTitle();
+
+        insertBookmarkItem(url1, title1, oneHourAgo);
+        insertBookmarkItem(url2, title2, fiveDaysAgo);
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(1, cursor.getCount());
+
+        cursor.moveToNext();
+        assertCursor(cursor, url1, title1);
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: Database contains an often visited bookmark.
+     *
+     * Assert that:
+     *  - Bookmark is not selected for highlights.
+     */
+    @Test
+    public void testOftenVisitedBookmarksWillNotBePicked() throws Exception {
+        final String url = createUniqueUrl();
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+
+        insertBookmarkItem(url, createUniqueTitle(), oneHourAgo);
+        insertHistoryItem(url, createGUID(), oneHourAgo, 25, createUniqueTitle());
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(0, cursor.getCount());
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: Database contains URL as bookmark and in history (not visited often).
+     *
+     * Assert that:
+     * - URL is not picked twice (as bookmark and from history)
+     */
+    @Test
+    public void testSameUrlIsNotPickedFromHistoryAndBookmarks() throws Exception {
+        final String url = createUniqueUrl();
+
+        final long oneHourAgo = System.currentTimeMillis() - 1000 * 60 * 60;
+
+        // Insert bookmark that is picked for highlights
+        insertBookmarkItem(url, createUniqueTitle(), oneHourAgo);
+        // Insert history for same URL that would be picked for highlights too
+        insertHistoryItem(url, createGUID(), oneHourAgo, 2, createUniqueTitle());
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(1, cursor.getCount());
+
+        cursor.close();
+    }
+
+    /**
+     * Scenario: Database contains only old bookmarks.
+     *
+     * Assert that:
+     * - Old bookmarks are not selected as highlight.
+     */
+    @Test
+    public void testVeryOldBookmarksAreNotSelected() throws Exception {
+        final long oneWeekAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
+        final long oneMonthAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31);
+        final long oneYearAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(365);
+
+        insertBookmarkItem(createUniqueUrl(), createUniqueTitle(), oneWeekAgo);
+        insertBookmarkItem(createUniqueUrl(), createUniqueTitle(), oneMonthAgo);
+        insertBookmarkItem(createUniqueUrl(), createUniqueTitle(), oneYearAgo);
+
+        final Cursor cursor = highlightsClient.query(highlightsTestUri, null, null, null, null);
+        Assert.assertNotNull(cursor);
+
+        Assert.assertEquals(0, cursor.getCount());
+
+        cursor.close();
+    }
+
+    private void insertBookmarkItem(String url, String title, long createdAt) throws RemoteException {
+        ContentValues values = new ContentValues();
+
+        values.put(BrowserContract.Bookmarks.URL, url);
+        values.put(BrowserContract.Bookmarks.TITLE, title);
+        values.put(BrowserContract.Bookmarks.PARENT, 0);
+        values.put(BrowserContract.Bookmarks.TYPE, BrowserContract.Bookmarks.TYPE_BOOKMARK);
+        values.put(BrowserContract.Bookmarks.DATE_CREATED, createdAt);
+
+        bookmarksClient.insert(bookmarksTestUri, values);
+    }
+
+    private void assertCursor(Cursor cursor, String url, String title) {
+        final String actualTitle = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE));
+        Assert.assertEquals(title, actualTitle);
+
+        final String actualUrl = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
+        Assert.assertEquals(url, actualUrl);
+    }
+
+    private void assertCursorContainsEntry(Cursor cursor, String url, String title) {
+        cursor.moveToFirst();
+
+        do {
+            final String actualTitle = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE));
+            final String actualUrl = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
+
+            if (actualTitle.equals(title) && actualUrl.equals(url)) {
+                return;
+            }
+        } while (cursor.moveToNext());
+
+        Assert.fail("Could not find entry title=" + title + ", url=" + url);
+    }
+
+    private String createUniqueUrl() {
+        return new Uri.Builder()
+                .scheme("https")
+                .authority(UUID.randomUUID().toString() + ".example.org")
+                .appendPath(UUID.randomUUID().toString())
+                .appendPath(UUID.randomUUID().toString())
+                .build()
+                .toString();
+    }
+
+    private String createUniqueTitle() {
+        return "Title " + UUID.randomUUID().toString();
+    }
+
+    private String createGUID() {
+        return UUID.randomUUID().toString();
+    }
+}
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/db/BrowserProviderHistoryVisitsTestBase.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/db/BrowserProviderHistoryVisitsTestBase.java
@@ -8,58 +8,69 @@ import android.content.ContentValues;
 import android.net.Uri;
 import android.os.RemoteException;
 
 import org.junit.After;
 import org.junit.Before;
 import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
 import org.robolectric.shadows.ShadowContentResolver;
 
+import java.util.UUID;
+
 public class BrowserProviderHistoryVisitsTestBase {
-    protected BrowserProvider provider;
-    protected ContentProviderClient historyClient;
-    protected ContentProviderClient visitsClient;
-    protected Uri historyTestUri;
-    protected Uri visitsTestUri;
+    /* package-private */ ShadowContentResolver contentResolver;
+    /* package-private */ ContentProviderClient historyClient;
+    /* package-private */ ContentProviderClient visitsClient;
+    /* package-private */ Uri historyTestUri;
+    /* package-private */ Uri visitsTestUri;
+
+    private BrowserProvider provider;
 
     @Before
     public void setUp() throws Exception {
         provider = new BrowserProvider();
         provider.onCreate();
         ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY_URI.toString(), provider);
 
-        final ShadowContentResolver cr = new ShadowContentResolver();
-        historyClient = cr.acquireContentProviderClient(BrowserContractHelpers.HISTORY_CONTENT_URI);
-        visitsClient = cr.acquireContentProviderClient(BrowserContractHelpers.VISITS_CONTENT_URI);
+        contentResolver = new ShadowContentResolver();
+        historyClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.HISTORY_CONTENT_URI);
+        visitsClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.VISITS_CONTENT_URI);
 
         historyTestUri = testUri(BrowserContract.History.CONTENT_URI);
         visitsTestUri = testUri(BrowserContract.Visits.CONTENT_URI);
     }
 
     @After
     public void tearDown() {
         historyClient.release();
         visitsClient.release();
         provider.shutdown();
     }
 
-    protected Uri testUri(Uri baseUri) {
+    /* package-private */  Uri testUri(Uri baseUri) {
         return baseUri.buildUpon().appendQueryParameter(BrowserContract.PARAM_IS_TEST, "1").build();
     }
 
-    protected Uri insertHistoryItem(String url, String guid) throws RemoteException {
-        return insertHistoryItem(url, guid, System.currentTimeMillis(), null);
+    /* package-private */  Uri insertHistoryItem(String url, String guid) throws RemoteException {
+        return insertHistoryItem(url, guid, System.currentTimeMillis(), null, null);
     }
 
-    protected Uri insertHistoryItem(String url, String guid, Long lastVisited, Integer visitCount) throws RemoteException {
+    /* package-private */  Uri insertHistoryItem(String url, String guid, Long lastVisited, Integer visitCount) throws RemoteException {
+        return insertHistoryItem(url, guid, System.currentTimeMillis(), null, null);
+    }
+
+    /* package-private */  Uri insertHistoryItem(String url, String guid, Long lastVisited, Integer visitCount, String title) throws RemoteException {
         ContentValues historyItem = new ContentValues();
         historyItem.put(BrowserContract.History.URL, url);
         if (guid != null) {
             historyItem.put(BrowserContract.History.GUID, guid);
         }
         if (visitCount != null) {
             historyItem.put(BrowserContract.History.VISITS, visitCount);
         }
         historyItem.put(BrowserContract.History.DATE_LAST_VISITED, lastVisited);
+        if (title != null) {
+            historyItem.put(BrowserContract.History.TITLE, title);
+        }
 
         return historyClient.insert(historyTestUri, historyItem);
     }
 }