Bug 1404460: Add test for pocket locale enabling. r=liuche draft
authorMichael Comella <michael.l.comella@gmail.com>
Mon, 02 Oct 2017 18:36:41 -0700
changeset 674018 101ce5408e6f329bf04b5e889e942d6f42953500
parent 673988 777d0f4bc34829c8aacdeaac42fc0e27c3e7afd6
child 734193 aadbdc67f3843a746d4e5113f2cf0f437451004a
push id82691
push usermichael.l.comella@gmail.com
push dateTue, 03 Oct 2017 01:37:03 +0000
reviewersliuche
bugs1404460
milestone58.0a1
Bug 1404460: Add test for pocket locale enabling. r=liuche MozReview-Commit-ID: LHdQuICvVjE
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamConfiguration.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/activitystream/homepanel/TestActivityStreamConfiguration.java
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamConfiguration.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamConfiguration.java
@@ -1,51 +1,48 @@
 /* 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.homepanel;
 
 import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.support.annotation.VisibleForTesting;
 import org.mozilla.gecko.BrowserLocaleManager;
 import org.mozilla.gecko.Locales;
 
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
 
 /**
  * Static functions for accessing user configuration information.
  *
  * TODO (bug 1405161): we should move all configuration accesses to this class to centralize them.
  */
 public class ActivityStreamConfiguration {
 
-    private static final Set<Locale> enabledLocales;
+    private static final Set<Locale> pocketEnabledLocales;
+    @VisibleForTesting static final String[] pocketEnabledLocaleTags = new String[] {
+            // Sorted alphabetically to preserve blame for additions/removals.
+            "de-AT",
+            "de-CH",
+            "de-DE",
+            "en-GB",
+            "en-US",
+            "en-ZA",
+    };
 
     static {
-        final String[] enabledLocaleTags = new String[] {
-                // Sorted alphabetically to preserve blame for additions/removals.
-                "de-AT",
-                "de-CH",
-                "de-DE",
-                "en-GB",
-                "en-US",
-                "en-ZA",
-        };
-
         final Set<Locale> mutableEnabledLocales = new HashSet<>();
-        for (final String enabledLocaleTag : enabledLocaleTags) {
+        for (final String enabledLocaleTag : pocketEnabledLocaleTags) {
             mutableEnabledLocales.add(Locales.parseLocaleCode(enabledLocaleTag));
         }
-        enabledLocales = Collections.unmodifiableSet(mutableEnabledLocales);
+        pocketEnabledLocales = Collections.unmodifiableSet(mutableEnabledLocales);
     }
 
     private ActivityStreamConfiguration() {}
 
     public static boolean isPocketEnabledByLocale(final Context context) {
         // Unintuitively, `BrowserLocaleManager.getCurrentLocale` returns the current user overridden locale,
         // or null if the user hasn't overidden the system default.
         final Locale currentLocale;
@@ -56,11 +53,18 @@ public class ActivityStreamConfiguration
             // `locale` was deprecated in API 24 but our target SDK is too low to use the new method.
             currentLocale = context.getResources().getConfiguration().locale;
         }
 
         return isPocketEnabledByLocaleInner(currentLocale);
     }
 
     @VisibleForTesting static boolean isPocketEnabledByLocaleInner(final Locale locale) {
-        return enabledLocales.contains(locale);
+        // This comparison will use Locale.equals and thus compare all Locale fields including variant (some variant
+        // examples are "scotland" (Scottish english) and "oxendict" (Oxford Dictionary standard spelling)). The tags
+        // we've whitelisted have no variant so they will fail to match locales with variants, even if the language and
+        // country are the same. In practice, I can't find a use of variants in Android locales, so I've opted to leave
+        // this comparison the way it is to 1) avoid churn, 2) keep the code simple, and 3) because I don't know how
+        // Product would want to handle these variants. If we wanted to ignore variants in comparisons, we could compare
+        // the language and country only.
+        return pocketEnabledLocales.contains(locale);
     }
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/activitystream/homepanel/TestActivityStreamConfiguration.java
@@ -0,0 +1,63 @@
+/* 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.homepanel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import static android.R.attr.tag;
+import static junit.framework.Assert.*;
+
+@RunWith(TestRunner.class)
+public class TestActivityStreamConfiguration {
+
+    @Test
+    public void testIsPocketEnabledByLocaleInnerForWhitelistedLocaleTags() throws Exception {
+        for (final String tag : ActivityStreamConfiguration.pocketEnabledLocaleTags) {
+            final Locale whitelistedLocale = getLocaleFromLanguageTag(tag);
+            assertTrue("Expected Pocket enabled for locale: " + tag,
+                    ActivityStreamConfiguration.isPocketEnabledByLocaleInner(whitelistedLocale));
+        }
+    }
+
+    @Test
+    public void testIsPocketEnabledByLocaleInnerForNonWhitelistedLocaleTags() throws Exception {
+        final String nonWhitelistedLocaleTag = "sbp-TZ"; // Sangu, chosen b/c I think it'll take a while for us to have Pocket feeds for it.
+        if (Arrays.binarySearch(ActivityStreamConfiguration.pocketEnabledLocaleTags, nonWhitelistedLocaleTag) >= 0) {
+            throw new IllegalStateException("Precondition failed: locale, " + nonWhitelistedLocaleTag + ", has been " +
+                    "added to whitelisted locales. Please choose a new tag.");
+        }
+
+        final Locale nonWhitelistedLocale = getLocaleFromLanguageTag(nonWhitelistedLocaleTag);
+        assertFalse("Expected Pocket disabled for locale: " + nonWhitelistedLocaleTag,
+                ActivityStreamConfiguration.isPocketEnabledByLocaleInner(nonWhitelistedLocale));
+    }
+
+    @Test
+    public void testIsPocketEnabledByLocaleInnerEnglishVariant() throws Exception {
+        // Oxford english spelling variant via https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry.
+        final Locale enGBVariant = new Locale("en", "gb", "oxendict");
+
+        // See ActivityStreamConfiguration.isPocketenabledByLocaleInner for reasoning behind assertFalse.
+        assertFalse("Expected Pocket disabled for locale: " + enGBVariant.toLanguageTag(),
+                ActivityStreamConfiguration.isPocketEnabledByLocaleInner(enGBVariant));
+    }
+
+    /**
+     * Gets the {@link Locale} from the language tag, e.g. en-US. This duplicates
+     * {@link org.mozilla.gecko.Locales#parseLocaleCode(String)} which is intentional since that is not the method we're
+     * trying to test.
+     */
+    private Locale getLocaleFromLanguageTag(final String tag) {
+        final String[] split = tag.split("-");
+        return new Locale(split[0], split[1]);
+    }
+}
\ No newline at end of file