Bug 1241810 - Add configuration/whitelist for known sites we want to show notifications for. r=mcomella
We'll start with Blogger and Medium.
MozReview-Commit-ID: FKXcsdE6F8M
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/knownsites/KnownSite.java
@@ -0,0 +1,38 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.feeds.knownsites;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+/**
+ * A site we know and for which we can guess the feed URL from an arbitrary URL.
+ */
+public interface KnownSite {
+ /**
+ * Get a search string to find URLs of this site in our database. This search string is usually
+ * a partial domain / URL.
+ *
+ * For example we could return "medium.com" to find all URLs that contain this string. This could
+ * obviously find URLs that are not actually medium.com sites. This is acceptable as long as
+ * getFeedFromURL() can handle these inputs and either returns a feed for valid URLs or null for
+ * other matches that are not related to this site.
+ */
+ @NonNull String getURLSearchString();
+
+ /**
+ * Get the Feed URL for this URL. For a known site we can "guess" the feed URL from an URL
+ * pointing to any page. The input URL will be a result from the database found with the value
+ * returned by getURLSearchString().
+ *
+ * Example:
+ * - Input: https://medium.com/@antlam/ux-thoughts-for-2016-1fc1d6e515e8
+ * - Output: https://medium.com/feed/@antlam
+ *
+ * @return the url representing a feed, or null if a feed could not be determined.
+ */
+ @Nullable String getFeedFromURL(String url);
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/knownsites/KnownSiteBlogger.java
@@ -0,0 +1,29 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.feeds.knownsites;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Blogger.com
+ */
+public class KnownSiteBlogger implements KnownSite {
+ @Override
+ public String getURLSearchString() {
+ return ".blogspot.com";
+ }
+
+ @Override
+ public String getFeedFromURL(String url) {
+ Pattern pattern = Pattern.compile("https?://(www\\.)?(.*?)\\.blogspot\\.com(/.*)?");
+ Matcher matcher = pattern.matcher(url);
+ if (matcher.matches()) {
+ return String.format("https://%s.blogspot.com/feeds/posts/default", matcher.group(2));
+ }
+ return null;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/knownsites/KnownSiteMedium.java
@@ -0,0 +1,29 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.feeds.knownsites;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Medium.com
+ */
+public class KnownSiteMedium implements KnownSite {
+ @Override
+ public String getURLSearchString() {
+ return "medium.com";
+ }
+
+ @Override
+ public String getFeedFromURL(String url) {
+ Pattern pattern = Pattern.compile("https?://medium.com/([^/]+)(/.*)?");
+ Matcher matcher = pattern.matcher(url);
+ if (matcher.matches()) {
+ return String.format("https://medium.com/feed/%s", matcher.group(1));
+ }
+ return null;
+ }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -272,16 +272,19 @@ gbjar.sources += ['java/org/mozilla/geck
'favicons/Favicons.java',
'favicons/LoadFaviconTask.java',
'favicons/OnFaviconLoadedListener.java',
'favicons/RemoteFavicon.java',
'feeds/action/CheckAction.java',
'feeds/action/SubscribeAction.java',
'feeds/FeedFetcher.java',
'feeds/FeedService.java',
+ 'feeds/knownsites/KnownSite.java',
+ 'feeds/knownsites/KnownSiteBlogger.java',
+ 'feeds/knownsites/KnownSiteMedium.java',
'feeds/parser/Feed.java',
'feeds/parser/Item.java',
'feeds/parser/SimpleFeedParser.java',
'feeds/subscriptions/FeedSubscription.java',
'feeds/subscriptions/SubscriptionStorage.java',
'FilePicker.java',
'FilePickerResultHandler.java',
'FindInPageBar.java',
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/feeds/knownsites/TestKnownSiteBlogger.java
@@ -0,0 +1,74 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.feeds.knownsites;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.helpers.AssertUtil;
+
+@RunWith(TestRunner.class)
+public class TestKnownSiteBlogger {
+ /**
+ * Test that the search string is a substring of some known URLs.
+ */
+ @Test
+ public void testURLSearchString() {
+ final KnownSite blogger = new KnownSiteBlogger();
+ final String searchString = blogger.getURLSearchString();
+
+ AssertUtil.assertContains(
+ "http://mykzilla.blogspot.com/",
+ searchString);
+
+ AssertUtil.assertContains(
+ "http://example.blogspot.com",
+ searchString);
+
+ AssertUtil.assertContains(
+ "https://mykzilla.blogspot.com/2015/06/introducing-pluotsorbet.html",
+ searchString);
+
+ AssertUtil.assertContains(
+ "http://android-developers.blogspot.com/2016/02/android-support-library-232.html",
+ searchString);
+
+ AssertUtil.assertContainsNot(
+ "http://www.mozilla.org",
+ searchString);
+ }
+
+ /**
+ * Test that we get a feed URL for valid Blogger URLs.
+ */
+ @Test
+ public void testGettingFeedFromURL() {
+ final KnownSite blogger = new KnownSiteBlogger();
+
+ Assert.assertEquals(
+ "https://mykzilla.blogspot.com/feeds/posts/default",
+ blogger.getFeedFromURL("http://mykzilla.blogspot.com/"));
+
+ Assert.assertEquals(
+ "https://example.blogspot.com/feeds/posts/default",
+ blogger.getFeedFromURL("http://example.blogspot.com"));
+
+ Assert.assertEquals(
+ "https://mykzilla.blogspot.com/feeds/posts/default",
+ blogger.getFeedFromURL("https://mykzilla.blogspot.com/2015/06/introducing-pluotsorbet.html"));
+
+ Assert.assertEquals(
+ "https://android-developers.blogspot.com/feeds/posts/default",
+ blogger.getFeedFromURL("http://android-developers.blogspot.com/2016/02/android-support-library-232.html"));
+
+ Assert.assertEquals(
+ "https://example.blogspot.com/feeds/posts/default",
+ blogger.getFeedFromURL("http://example.blogspot.com/2016/03/i-moved-to-example.blogspot.com"));
+
+ Assert.assertNull(blogger.getFeedFromURL("http://www.mozilla.org"));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/feeds/knownsites/TestKnownSiteMedium.java
@@ -0,0 +1,66 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.feeds.knownsites;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.helpers.AssertUtil;
+
+@RunWith(TestRunner.class)
+public class TestKnownSiteMedium {
+ /**
+ * Test that the search string is a substring of some known URLs.
+ */
+ @Test
+ public void testURLSearchString() {
+ final KnownSite medium = new KnownSiteMedium();
+ final String searchString = medium.getURLSearchString();
+
+ AssertUtil.assertContains(
+ "https://medium.com/@Antlam/",
+ searchString);
+
+ AssertUtil.assertContains(
+ "https://medium.com/google-developers",
+ searchString);
+
+ AssertUtil.assertContains(
+ "http://medium.com/@brandonshin/how-slackbot-forced-us-to-workout-7b4741a2de73",
+ searchString
+ );
+
+ AssertUtil.assertContainsNot(
+ "http://www.mozilla.org",
+ searchString);
+ }
+
+ /**
+ * Test that we get a feed URL for valid Medium URLs.
+ */
+ @Test
+ public void testGettingFeedFromURL() {
+ final KnownSite medium = new KnownSiteMedium();
+
+ Assert.assertEquals(
+ "https://medium.com/feed/@Antlam",
+ medium.getFeedFromURL("https://medium.com/@Antlam/")
+ );
+
+ Assert.assertEquals(
+ "https://medium.com/feed/google-developers",
+ medium.getFeedFromURL("https://medium.com/google-developers")
+ );
+
+ Assert.assertEquals(
+ "https://medium.com/feed/@brandonshin",
+ medium.getFeedFromURL("http://medium.com/@brandonshin/how-slackbot-forced-us-to-workout-7b4741a2de73")
+ );
+
+ Assert.assertNull(medium.getFeedFromURL("http://www.mozilla.org"));
+ }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/helpers/AssertUtil.java
@@ -0,0 +1,29 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.helpers;
+
+import org.junit.Assert;
+
+/**
+ * Some additional assert methods on top of org.junit.Assert.
+ */
+public class AssertUtil {
+ /**
+ * Asserts that the String {@code text} contains the String {@code sequence}. If it doesn't then
+ * an {@link AssertionError} will be thrown.
+ */
+ public static void assertContains(String text, String sequence) {
+ Assert.assertTrue(text.contains(sequence));
+ }
+
+ /**
+ * Asserts that the String {@code text} contains not the String {@code sequence}. If it does
+ * then an {@link AssertionError} will be thrown.
+ */
+ public static void assertContainsNot(String text, String sequence) {
+ Assert.assertFalse(text.contains(sequence));
+ }
+}