Bug 1330280 - Refactor testActivityStreamContextMenu to use new Highlight/TopSite model classes. r=ahunt,Grisha
authorSebastian Kaspari <s.kaspari@gmail.com>
Thu, 12 Jan 2017 17:30:20 +0100
changeset 377253 deb2014e1eb50438f9390a0b5e378d86f3e6b18e
parent 377252 6ba01b40808abb8fdcab6c18ddcbb8b7dc25edb5
child 377254 5b25f62eff46f1332a62760efba4d04266bfa0fa
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersahunt, Grisha
bugs1330280
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1330280 - Refactor testActivityStreamContextMenu to use new Highlight/TopSite model classes. r=ahunt,Grisha MozReview-Commit-ID: 8pwUVQHwPu6
mobile/android/tests/browser/robocop/robocop.ini
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
--- a/mobile/android/tests/browser/robocop/robocop.ini
+++ b/mobile/android/tests/browser/robocop/robocop.ini
@@ -1,16 +1,14 @@
 [default]
 subsuite = robocop
 
 [src/org/mozilla/gecko/tests/testGeckoProfile.java]
 [src/org/mozilla/gecko/tests/testAboutPage.java]
 [src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java]
-# needs to be refactored, see bug 1330280
-skip-if = true
 [src/org/mozilla/gecko/tests/testAddonManager.java]
 # disabled on 4.3, bug 1144918
 skip-if = android_version == "18"
 [src/org/mozilla/gecko/tests/testAddSearchEngine.java]
 # disabled on 4.3, bug 1120759
 skip-if = android_version == "18"
 [src/org/mozilla/gecko/tests/testAdobeFlash.java]
 # disabled on 4.3, bug 1146420
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
@@ -1,102 +1,286 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tests;
 
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
 import android.view.MenuItem;
 import android.view.View;
 
 import com.robotium.solo.Condition;
 
+import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.R;
-import org.mozilla.gecko.activitystream.ActivityStream;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
+import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.db.BrowserDB;
+import org.mozilla.gecko.db.DBUtils;
 import org.mozilla.gecko.home.activitystream.menu.ActivityStreamContextMenu;
+import org.mozilla.gecko.home.activitystream.model.Highlight;
+import org.mozilla.gecko.home.activitystream.model.Item;
+import org.mozilla.gecko.home.activitystream.model.TopSite;
 
 /**
  * This test is unfortunately closely coupled to the current implementation, however it is still
  * useful in that it tests the bookmark/history/pinned state specific menu items for correctness.
  */
 public class testActivityStreamContextMenu extends BaseTest {
+    private static final String TEST_URL = "http://example.com/test/url";
+
+    private BrowserDB db;
+    private ContentResolver contentResolver;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        cleanup();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        cleanup();
+    }
+
+    /**
+     * Test the context menu for an item in all configuration states (highlight / top site).
+     */
     public void testActivityStreamContextMenu() {
         blockForGeckoReady();
 
-        final String testURL = "http://mozilla.org";
+        testActivityStreamContextMenuForHighlights();
+
+        cleanup();
+
+        testActivityStreamContextMenuForTopSites();
+    }
 
-        BrowserDB db = BrowserDB.from(getActivity());
-        db.removeHistoryEntry(getActivity().getContentResolver(), testURL);
-        db.removeBookmarksWithURL(getActivity().getContentResolver(), testURL);
+    /**
+     * Test the activity stream context menu for highlights.
+     *
+     * Not all combinations are possible with a highlight -> A highlight is either a bookmark or
+     * a history entry.
+     *
+     *    B
+     *    O
+     *    O
+     *    K V
+     *  P M I
+     *  I A S
+     *  N R I
+     *  N K T
+     *  E E E
+     *  D D D
+     *  -----
+     *  0 0 0 - Impossible
+     *  0 0 1 - Tested
+     *  0 1 0 - Tested
+     *  0 1 1 - Tested
+     *  1 0 0 - Impossible
+     *  1 0 1 - Tested
+     *  1 1 0 - Tested
+     *  1 1 1 - Tested
+     */
+    private void testActivityStreamContextMenuForHighlights() {
+        // (001) Insert a visit an hour ago - This will make sure that the URL shows up as highlight
+        insertVisit(TEST_URL, System.currentTimeMillis() - 60 * 1000 * 1000);
+
+        mAsserter.info("ContextMenu", "Highlight (Visited)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ false,
+                /* pinned */ false,
+                /* visited */ true);
 
-        testMenuForUrl(testURL, null, false, null, false, false);
+        // (011) Now let's insert a bookmark and test the menu again
+        db.addBookmark(contentResolver, "foobar", TEST_URL);
+
+        mAsserter.info("ContextMenu", "Highlight (Bookmarked, Visited)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ false,
+                /* visited */ true);
+
+        // (111) And now let's pin the page too.
+        db.pinSiteForAS(contentResolver, TEST_URL, "barfoo");
+
+        mAsserter.info("ContextMenu", "Highlight (Bookmarked, Pinned, Visited)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ true,
+                /* visited */ true);
+
+        // (110) Now let's get rid of the visit again
+        db.removeHistoryEntry(contentResolver, TEST_URL);
 
-        db.addBookmark(getActivity().getContentResolver(), "foobar", testURL);
-        testMenuForUrl(testURL, null, true, null, false, false);
-        testMenuForUrl(testURL, null, true, Boolean.FALSE, false, false);
-        testMenuForUrl(testURL, Boolean.TRUE, true, null, false, false);
-        testMenuForUrl(testURL, Boolean.TRUE, true, Boolean.FALSE, false, false);
+        mAsserter.info("ContextMenu", "Highlight (Bookmarked, Pinned)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ true,
+                /* visited */ false);
+
+        // (010) Unpin the site again
+        db.unpinSiteForAS(contentResolver, TEST_URL);
+
+        mAsserter.info("ContextMenu", "Highlight (Bookmarked)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ false,
+                /* visited */ false);
+
+        // (101) Remove the bookmark, but visit and pin the site
+        db.removeBookmarksWithURL(contentResolver, TEST_URL);
+        db.pinSiteForAS(contentResolver, TEST_URL, "barfoo");
+        insertVisit(TEST_URL, System.currentTimeMillis() - 60 * 1000 * 1000);
+
+        mAsserter.info("ContextMenu", "Highlight (Pinned, Visited)");
+        testMenuForHighlight(TEST_URL,
+                /* bookmarked */ false,
+                /* pinned */ true,
+                /* visited */ true);
+    }
 
-        db.updateVisitedHistory(getActivity().getContentResolver(), testURL);
-        testMenuForUrl(testURL, null, true, null, false, true);
-        testMenuForUrl(testURL, null, true, Boolean.FALSE, false, true);
-        testMenuForUrl(testURL, Boolean.TRUE, true, null, false, true);
-        testMenuForUrl(testURL, Boolean.TRUE, true, Boolean.FALSE, false, true);
+    /**
+     * Test the activity stream context menu for top sites.
+     *
+     * Not all combinations are possible with a top site -> A top site needs to be visited or
+     * pinned.
+     *
+     *    B
+     *    O
+     *    O
+     *    K V
+     *  P M I
+     *  I A S
+     *  N R I
+     *  N K T
+     *  E E E
+     *  D D D
+     *  -----
+     *  0 0 0 - Impossible
+     *  0 0 1 - Tested
+     *  0 1 0 - Impossible
+     *  0 1 1 - Tested
+     *  1 0 0 - Tested
+     *  1 0 1 - Tested
+     *  1 1 0 - Tested
+     *  1 1 1 - Tested
+     */
+    private void testActivityStreamContextMenuForTopSites() {
+        // (001) First insert a visit for the URL
+        insertVisit(TEST_URL, System.currentTimeMillis());
+
+        insertVisit(TEST_URL, System.currentTimeMillis());
+        insertVisit(TEST_URL, System.currentTimeMillis());
+        insertVisit(TEST_URL, System.currentTimeMillis());
+
+        mAsserter.info("ContextMenu", "Top Site (Visited)");
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ false,
+                /* pinned */ false,
+                /* visited */ true);
+
+        // (011) Now bookmark the URL
+        db.addBookmark(contentResolver, "foobar", TEST_URL);
 
-        db.removeBookmarksWithURL(getActivity().getContentResolver(), testURL);
-        testMenuForUrl(testURL, null, false, null, false, true);
-        testMenuForUrl(testURL, Boolean.FALSE, false, null, false, true);
+        mAsserter.info("ContextMenu", "Top Site (Bookmarked, Visited)");
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ false,
+                /* visited */ true);
+
+        // (111) And let's pin the site too
+        db.pinSiteForAS(contentResolver, TEST_URL, "foobar");
+
+        mAsserter.info("ContextMenu", "Top Site (Pinned, Bookmarked, Visited)");
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ true,
+                /* visited */ true);
+
+        // (110) Now remove the history entry.
+        db.removeHistoryEntry(contentResolver, TEST_URL);
+
+        mAsserter.info("ContextMenu", "Top Site (Pinned, Bookmarked)");
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ true,
+                /* pinned */ true,
+                /* visited */ false);
 
-        db.pinSiteForAS(getActivity().getContentResolver(), testURL, "test title");
-        testMenuForUrl(testURL, null, false, null, true, true);
-        testMenuForUrl(testURL, null, false, Boolean.TRUE, true, true);
+        // (100) Let's remove the bookmark too.
+        db.removeBookmarksWithURL(contentResolver, TEST_URL);
+
+        mAsserter.info("ContextMenu", "Top Site (Pinned)");
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ false,
+                /* pinned */ true,
+                /* visited */ false);
+
+        // (101) And finally let's visit the URL once more
+        insertVisit(TEST_URL, System.currentTimeMillis());
 
-        db.addBookmark(getActivity().getContentResolver(), "foobar", testURL);
-        testMenuForUrl(testURL, null, true, null, true, true);
-        testMenuForUrl(testURL, Boolean.TRUE, true, Boolean.TRUE, true, true);
+        testMenuForTopSite(TEST_URL,
+                /* bookmarked */ false,
+                /* pinned */ true,
+                /* visited */ true);
+    }
+
+    private void testMenuForHighlight(String url, boolean bookmarked, boolean pinned, boolean visited) {
+        final Highlight highlight = findHighlightByUrl(url);
+
+        testMenuForItem(highlight, bookmarked, pinned, visited);
+    }
+
+    private void testMenuForTopSite(String url, boolean bookmarked, boolean pinned, boolean visited) {
+        final TopSite topSite = findTopSiteByUrl(url);
+
+        testMenuForItem(topSite, bookmarked, pinned, visited);
     }
 
     /**
      * Test that the menu shows the expected menu items for a given URL, and that these items have
      * the correct state.
      */
-    private void testMenuForUrl(final String url, final Boolean isBookmarkedKnownState, final boolean isBookmarked, final Boolean isPinnedKnownState, final boolean isPinned, final boolean isVisited) {
-        // Needs to be refactored (Bug 1330280)
-        /*
+    private void testMenuForItem(Item item, boolean bookmarked, boolean pinned, boolean visited) {
         final View anchor = new View(getActivity());
         final ActivityStreamContextMenu menu = ActivityStreamContextMenu.show(
-                getActivity(), anchor, ActivityStreamTelemetry.Extras.builder(), ActivityStreamContextMenu.MenuMode.HIGHLIGHT, "foobar", url, isBookmarkedKnownState, isPinnedKnownState, null, null, 100, 100);
+                getActivity(), anchor, ActivityStreamTelemetry.Extras.builder(), ActivityStreamContextMenu.MenuMode.HIGHLIGHT, item, null, null, 100, 100);
 
         final int expectedBookmarkString;
-        if (isBookmarked) {
+        if (bookmarked) {
             expectedBookmarkString = R.string.bookmark_remove;
         } else {
             expectedBookmarkString = R.string.bookmark;
         }
 
         final int expectedPinnedString;
-        if (isPinned) {
+        if (pinned) {
             expectedPinnedString = R.string.contextmenu_top_sites_unpin;
         } else {
             expectedPinnedString = R.string.contextmenu_top_sites_pin;
         }
 
         final MenuItem pinItem = menu.getItemByID(R.id.pin);
         assertMenuItemHasString(pinItem, expectedPinnedString);
 
         final MenuItem bookmarkItem = menu.getItemByID(R.id.bookmark);
         assertMenuItemHasString(bookmarkItem, expectedBookmarkString);
 
         final MenuItem deleteItem = menu.getItemByID(R.id.delete);
-        assertMenuItemIsVisible(deleteItem, isVisited);
+        assertMenuItemIsVisible(deleteItem, visited);
 
         menu.dismiss();
-        */
     }
 
     private void assertMenuItemIsVisible(final MenuItem item, final boolean shouldBeVisible) {
         waitForCondition(new Condition() {
             @Override
             public boolean isSatisfied() {
                 return (item.isVisible() == shouldBeVisible);
             }
@@ -111,10 +295,92 @@ public class testActivityStreamContextMe
             public boolean isSatisfied() {
                 return item.isEnabled();
             }
         }, 5000);
 
         final String expectedTitle = getActivity().getResources().getString(stringID);
         mAsserter.is(item.getTitle(), expectedTitle, "Title does not match expected title");
     }
+
+
+    private Highlight findHighlightByUrl(String url) {
+        final Cursor cursor = db.getHighlights(getActivity(), 20).loadInBackground();
+        mAsserter.isnot(cursor, null, "Highlights cursor is not null");
+
+        try {
+            mAsserter.ok(cursor.getCount() > 0, "Highlights cursor has entries", null);
+
+            mAsserter.dumpLog("Database returned " + cursor.getCount() + " highlights");
+
+            mAsserter.ok(cursor.moveToFirst(), "Move to beginning of cursor", null);
+
+            do {
+                final Highlight highlight = Highlight.fromCursor(cursor);
+                if (url.equals(highlight.getUrl())) {
+                    return highlight;
+                }
+            } while (cursor.moveToNext());
+
+            mAsserter.ok(false, "Could not find highlight for URL: " + url, null);
+            return null; // The call to fail() will throw an exception but the compiler doesn't know
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private TopSite findTopSiteByUrl(String url) {
+        final Cursor cursor = db.getActivityStreamTopSites(getActivity(), 5, 20).loadInBackground();
+        mAsserter.isnot(cursor, null, "Top Sites cursor is not null");
+
+        try {
+            mAsserter.ok(cursor.getCount() > 0, "Top Sites cursor has entries", null);
+
+            mAsserter.ok(cursor.moveToFirst(), "Move to beginning of cursor", null);
+
+            do {
+                final TopSite topSite = TopSite.fromCursor(cursor);
+                if (url.equals(topSite.getUrl())) {
+                    return topSite;
+                }
+            } while (cursor.moveToNext());
+
+            mAsserter.ok(false, "Could not find Top Site for URL: " + url, null);
+            return null; // The call to fail() will throw an exception but the compiler doesn't know
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private void insertVisit(String url, long dateLastVisited) {
+        ContentValues values = new ContentValues();
+        values.put(BrowserContract.History.URL, url);
+        values.put(BrowserContract.History.DATE_LAST_VISITED, dateLastVisited);
+        values.put(BrowserContract.History.IS_DELETED, 0);
+
+        Uri mHistoryUriWithProfile = DBUtils.appendProfile(
+                GeckoProfile.get(getActivity()).getName(), BrowserContract.History.CONTENT_URI);
+
+        Uri mUpdateHistoryUriWithProfile =
+                mHistoryUriWithProfile.buildUpon()
+                        .appendQueryParameter(BrowserContract.PARAM_INCREMENT_VISITS, "true")
+                        .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true")
+                        .build();
+
+        contentResolver.update(mUpdateHistoryUriWithProfile,
+                values,
+                BrowserContract.History.URL + " = ?",
+                new String[] { url });
+    }
+
+    private void cleanup() {
+        final Context context = getActivity();
+
+        contentResolver = context.getContentResolver();
+
+        // Let's always start with no traces in the db
+        db = BrowserDB.from(context);
+        db.removeHistoryEntry(contentResolver, TEST_URL);
+        db.removeBookmarksWithURL(contentResolver, TEST_URL);
+        db.unpinSiteForAS(contentResolver, TEST_URL);
+    }
 }