Bug 1299201 - Introduce ActivityStream.extractLabel() to extravt a label from a URL. r?grisha
MozReview-Commit-ID: 8IM7qppwmJ6
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStream.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStream.java
@@ -1,31 +1,105 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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.activitystream;
import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.preferences.GeckoPreferences;
+import org.mozilla.gecko.util.StringUtils;
+import org.mozilla.gecko.util.publicsuffix.PublicSuffix;
+
+import java.util.Arrays;
+import java.util.List;
public class ActivityStream {
+ /**
+ * List of undesired prefixes for labels based on a URL.
+ *
+ * This list is by no means complete and is based on those sources:
+ * - https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
+ * - https://github.com/mozilla/activity-stream/issues/1311
+ */
+ private static final List<String> UNDESIRED_LABEL_PREFIXES = Arrays.asList(
+ "index.",
+ "home."
+ );
+
+ /**
+ * Undesired labels for labels based on a URL.
+ *
+ * This list is by no means complete and is based on those sources:
+ * - https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
+ * - https://github.com/mozilla/activity-stream/issues/1311
+ */
+ private static final List<String> UNDESIRED_LABELS = Arrays.asList(
+ "render",
+ "login",
+ "edit"
+ );
+
public static boolean isEnabled(Context context) {
if (!AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
return false;
}
return GeckoSharedPrefs.forApp(context)
.getBoolean(GeckoPreferences.PREFS_ACTIVITY_STREAM, false);
}
/**
* Query whether we want to display Activity Stream as a Home Panel (within the HomePager),
* or as a HomePager replacement.
*/
public static boolean isHomePanel() {
return true;
}
+
+ /**
+ * Extract a label from a URL to use in Activity Stream.
+ *
+ * This method implements the proposal from this desktop AS issue:
+ * https://github.com/mozilla/activity-stream/issues/1311
+ */
+ public static String extractLabel(String url) {
+ if (TextUtils.isEmpty(url)) {
+ return "";
+ }
+
+ final Uri uri = Uri.parse(url);
+
+ // Use last path segment if suitable
+ final String segment = uri.getLastPathSegment();
+ if (!TextUtils.isEmpty(segment)
+ && !UNDESIRED_LABELS.contains(segment)
+ && !segment.matches("^[0-9]+$")) {
+
+ boolean hasUndesiredPrefix = false;
+ for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
+ if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
+ hasUndesiredPrefix = true;
+ break;
+ }
+ }
+
+ if (!hasUndesiredPrefix) {
+ return segment;
+ }
+ }
+
+ // If no usable path segment was found then use the host without public suffix and common subdomains
+ final String host = uri.getHost();
+ if (TextUtils.isEmpty(host)) {
+ return url;
+ }
+
+ return StringUtils.stripCommonSubdomains(
+ PublicSuffix.stripPublicSuffix(host));
+ }
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/activitystream/TestActivityStream.java
@@ -0,0 +1,95 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.activitystream;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(TestRunner.class)
+public class TestActivityStream {
+ /**
+ * Unit tests for ActivityStream.extractLabel().
+ *
+ * Most test cases are based on this list:
+ * https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
+ */
+ @Test
+ public void testExtractLabel() {
+ // Empty values
+
+ assertEquals("", ActivityStream.extractLabel(""));
+ assertEquals("", ActivityStream.extractLabel(null));
+
+ // Without path
+
+ assertEquals("news.ycombinator",
+ ActivityStream.extractLabel("https://news.ycombinator.com/"));
+
+ assertEquals("sql.telemetry.mozilla",
+ ActivityStream.extractLabel("https://sql.telemetry.mozilla.org/"));
+
+ assertEquals("sso.mozilla",
+ ActivityStream.extractLabel("http://sso.mozilla.com/"));
+
+ assertEquals("youtube",
+ ActivityStream.extractLabel("http://youtube.com/"));
+
+ assertEquals("images.google",
+ ActivityStream.extractLabel("http://images.google.com/"));
+
+ assertEquals("smile.amazon",
+ ActivityStream.extractLabel("http://smile.amazon.com/"));
+
+ assertEquals("localhost",
+ ActivityStream.extractLabel("http://localhost:5000/"));
+
+ assertEquals("independent",
+ ActivityStream.extractLabel("http://www.independent.co.uk/"));
+
+ // With path
+
+ assertEquals("firefox",
+ ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/"));
+
+ assertEquals("activity-stream",
+ ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream"));
+
+ assertEquals("activity-stream",
+ ActivityStream.extractLabel("https://github.com/mozilla/activity-stream"));
+
+ assertEquals("sidekiq",
+ ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq"));
+
+ assertEquals("nchapman",
+ ActivityStream.extractLabel("https://github.com/nchapman/"));
+
+ // Unusable paths
+
+ assertEquals("phonebook.mozilla", // instead of "login"
+ ActivityStream.extractLabel("https://phonebook.mozilla.org/mellon/login?ReturnTo=https%3A%2F%2Fphonebook.mozilla.org%2F&IdP=http%3A%2F%2Fwww.okta.com"));
+
+ assertEquals("ipay.adp", // instead of "index.jsf"
+ ActivityStream.extractLabel("https://ipay.adp.com/iPay/index.jsf"));
+
+ assertEquals("calendar.google", // instead of "render"
+ ActivityStream.extractLabel("https://calendar.google.com/calendar/render?pli=1#main_7"));
+
+ assertEquals("myworkday", // instead of "home.htmld"
+ ActivityStream.extractLabel("https://www.myworkday.com/vhr_mozilla/d/home.htmld"));
+
+ assertEquals("mail.google", // instead of "1"
+ ActivityStream.extractLabel("https://mail.google.com/mail/u/1/#inbox"));
+
+ assertEquals("docs.google", // instead of "edit"
+ ActivityStream.extractLabel("https://docs.google.com/presentation/d/11cyrcwhKTmBdEBIZ3szLO0-_Imrx2CGV2B9_LZHDrds/edit#slide=id.g15d41bb0f3_0_82"));
+
+ // Special cases
+
+ assertEquals("irccloud.mozilla",
+ ActivityStream.extractLabel("https://irccloud.mozilla.com/#!/ircs://irc1.dmz.scl3.mozilla.com:6697/%23universal-search"));
+ }
+}