jenkins-bot has submitted this change and it was merged.

Change subject: Support for unmarshalling and using GeoIP cookies.
......................................................................


Support for unmarshalling and using GeoIP cookies.

Lays some groundwork for conditionally showing announcements based on
country code and other parameters.

Bug: T151085
Change-Id: I4857433286d415d1a1a15cf7e22e603cb6b70410
---
M app/src/main/java/org/wikipedia/SharedPreferenceCookieManager.java
A app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookie.java
A app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshaller.java
M app/src/main/java/org/wikipedia/page/linkpreview/LinkPreviewDialog.java
A app/src/main/java/org/wikipedia/util/GeoUtil.java
M app/src/main/java/org/wikipedia/util/UriUtil.java
A 
app/src/test/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshallerTest.java
7 files changed, 211 insertions(+), 22 deletions(-)

Approvals:
  Mholloway: Looks good to me, but someone else must approve
  jenkins-bot: Verified
  Niedzielski: Looks good to me, approved



diff --git a/app/src/main/java/org/wikipedia/SharedPreferenceCookieManager.java 
b/app/src/main/java/org/wikipedia/SharedPreferenceCookieManager.java
index cf2a157..5303e27 100644
--- a/app/src/main/java/org/wikipedia/SharedPreferenceCookieManager.java
+++ b/app/src/main/java/org/wikipedia/SharedPreferenceCookieManager.java
@@ -1,6 +1,7 @@
 package org.wikipedia;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import org.wikipedia.settings.Prefs;
 import org.wikipedia.util.StringUtil;
@@ -136,6 +137,18 @@
         return StringUtil.delimiterStringToList(str, DELIMITER);
     }
 
+    @Nullable
+    public synchronized String getCookieByName(@NonNull String name) {
+        for (String domainSpec: cookieJar.keySet()) {
+            for (String cookie : cookieJar.get(domainSpec).keySet()) {
+                if (cookie.equals(name)) {
+                    return cookieJar.get(domainSpec).get(cookie);
+                }
+            }
+        }
+        return null;
+    }
+
     private Map<String, String> makeCookieMap(@NonNull List<String> cookies) {
         Map<String, String> cookiesMap = new HashMap<>();
         for (String cookie : cookies) {
diff --git a/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookie.java 
b/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookie.java
new file mode 100644
index 0000000..257394d
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookie.java
@@ -0,0 +1,40 @@
+package org.wikipedia.feed.announcement;
+
+import android.location.Location;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+public class GeoIPCookie {
+
+    @NonNull private final String country;
+    @NonNull private final String region;
+    @NonNull private final String city;
+    @Nullable private final Location location;
+
+    GeoIPCookie(@NonNull String country, @NonNull String region, @NonNull 
String city, @Nullable Location location) {
+        this.country = country;
+        this.region = region;
+        this.city = city;
+        this.location = location;
+    }
+
+    @NonNull
+    public String country() {
+        return country;
+    }
+
+    @NonNull
+    public String region() {
+        return region;
+    }
+
+    @NonNull
+    public String city() {
+        return city;
+    }
+
+    @Nullable
+    public Location location() {
+        return location;
+    }
+}
diff --git 
a/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshaller.java
 
b/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshaller.java
new file mode 100644
index 0000000..9ca0d32
--- /dev/null
+++ 
b/app/src/main/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshaller.java
@@ -0,0 +1,59 @@
+package org.wikipedia.feed.announcement;
+
+import android.location.Location;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+
+import org.wikipedia.WikipediaApp;
+
+/*
+This currently supports the "v4" version of the GeoIP cookie.
+For some info about the format and contents of the cookie:
+https://phabricator.wikimedia.org/diffusion/ECNO/browse/master/resources/subscribing/ext.centralNotice.geoIP.js
+ */
+public final class GeoIPCookieUnmarshaller {
+    private static final String COOKIE_NAME = "GeoIP";
+
+    private enum Component {
+        COUNTRY, REGION, CITY, LATITUDE, LONGITUDE, VERSION
+    }
+
+    @NonNull
+    public static GeoIPCookie unmarshal(@NonNull WikipediaApp app) {
+        return unmarshal(app.getCookieManager().getCookieByName(COOKIE_NAME));
+    }
+
+    @VisibleForTesting
+    @NonNull
+    static GeoIPCookie unmarshal(@Nullable String cookie) throws 
IllegalArgumentException {
+        if (TextUtils.isEmpty(cookie)) {
+            throw new IllegalArgumentException("Cookie is empty.");
+        }
+        String[] components = cookie.split(":");
+        if (components.length < Component.values().length) {
+            throw new IllegalArgumentException("Cookie is malformed.");
+        } else if (!components[Component.VERSION.ordinal()].equals("v4")) {
+            throw new IllegalArgumentException("Incorrect cookie version.");
+        }
+        Location location = null;
+        if (!TextUtils.isEmpty(components[Component.LATITUDE.ordinal()])
+                && 
!TextUtils.isEmpty(components[Component.LONGITUDE.ordinal()])) {
+            location = new Location("");
+            try {
+                
location.setLatitude(Double.parseDouble(components[Component.LATITUDE.ordinal()]));
+                
location.setLongitude(Double.parseDouble(components[Component.LONGITUDE.ordinal()]));
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Location is malformed.");
+            }
+        }
+        return new GeoIPCookie(components[Component.COUNTRY.ordinal()],
+                components[Component.REGION.ordinal()],
+                components[Component.CITY.ordinal()],
+                location);
+    }
+
+    private GeoIPCookieUnmarshaller() {
+    }
+}
diff --git 
a/app/src/main/java/org/wikipedia/page/linkpreview/LinkPreviewDialog.java 
b/app/src/main/java/org/wikipedia/page/linkpreview/LinkPreviewDialog.java
index d954388..230e15c 100755
--- a/app/src/main/java/org/wikipedia/page/linkpreview/LinkPreviewDialog.java
+++ b/app/src/main/java/org/wikipedia/page/linkpreview/LinkPreviewDialog.java
@@ -38,7 +38,7 @@
 import org.wikipedia.server.PageServiceFactory;
 import org.wikipedia.server.PageSummary;
 import org.wikipedia.util.FeedbackUtil;
-import org.wikipedia.util.UriUtil;
+import org.wikipedia.util.GeoUtil;
 import org.wikipedia.util.log.L;
 import org.wikipedia.views.ViewUtil;
 
@@ -404,7 +404,7 @@
     private void goToExternalMapsApp() {
         if (location != null) {
             dismiss();
-            UriUtil.sendGeoIntent(getActivity(), location, 
pageTitle.getDisplayText());
+            GeoUtil.sendGeoIntent(getActivity(), location, 
pageTitle.getDisplayText());
         }
     }
 
diff --git a/app/src/main/java/org/wikipedia/util/GeoUtil.java 
b/app/src/main/java/org/wikipedia/util/GeoUtil.java
new file mode 100644
index 0000000..2186e82
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/util/GeoUtil.java
@@ -0,0 +1,34 @@
+package org.wikipedia.util;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.location.Location;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import org.wikipedia.R;
+
+public final class GeoUtil {
+
+    public static void sendGeoIntent(@NonNull Activity activity,
+                                     @NonNull Location location,
+                                     @Nullable String placeName) {
+        String geoStr = "geo:";
+        geoStr += Double.toString(location.getLatitude()) + ","
+                + Double.toString(location.getLongitude());
+        if (!TextUtils.isEmpty(placeName)) {
+            geoStr += "?q=" + Uri.encode(placeName);
+        }
+        try {
+            activity.startActivity(new Intent(Intent.ACTION_VIEW, 
Uri.parse(geoStr)));
+        } catch (ActivityNotFoundException e) {
+            FeedbackUtil.showMessage(activity, R.string.error_no_maps_app);
+        }
+    }
+
+    private GeoUtil() {
+    }
+}
diff --git a/app/src/main/java/org/wikipedia/util/UriUtil.java 
b/app/src/main/java/org/wikipedia/util/UriUtil.java
index 485dbda..e69c0a6 100644
--- a/app/src/main/java/org/wikipedia/util/UriUtil.java
+++ b/app/src/main/java/org/wikipedia/util/UriUtil.java
@@ -1,17 +1,13 @@
 package org.wikipedia.util;
 
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
-import android.location.Location;
 import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.annotation.StringRes;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 
-import org.wikipedia.R;
 import org.wikipedia.WikipediaApp;
 import org.wikipedia.page.PageTitle;
 import org.wikipedia.settings.Prefs;
@@ -102,22 +98,6 @@
         }
 
         showZeroExitInterstitialDialog(context, uri);
-    }
-
-    public static void sendGeoIntent(@NonNull Activity activity,
-                                     @NonNull Location location,
-                                     String placeName) {
-        String geoStr = "geo:";
-        geoStr += Double.toString(location.getLatitude()) + ","
-                + Double.toString(location.getLongitude());
-        if (!TextUtils.isEmpty(placeName)) {
-            geoStr += "?q=" + Uri.encode(placeName);
-        }
-        try {
-            activity.startActivity(new Intent(Intent.ACTION_VIEW, 
Uri.parse(geoStr)));
-        } catch (ActivityNotFoundException e) {
-            FeedbackUtil.showMessage(activity, R.string.error_no_maps_app);
-        }
     }
 
     public static String getUrlWithProvenance(Context context, PageTitle title,
diff --git 
a/app/src/test/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshallerTest.java
 
b/app/src/test/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshallerTest.java
new file mode 100644
index 0000000..0d8459c
--- /dev/null
+++ 
b/app/src/test/java/org/wikipedia/feed/announcement/GeoIPCookieUnmarshallerTest.java
@@ -0,0 +1,63 @@
+package org.wikipedia.feed.announcement;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.wikipedia.test.TestRunner;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+@RunWith(TestRunner.class)
+public class GeoIPCookieUnmarshallerTest {
+
+    private static final double LATITUDE = 37.33;
+    private static final double LONGITUDE = -121.89;
+
+    @Test public void testGeoIPWithLocation() {
+        GeoIPCookie cookie = 
GeoIPCookieUnmarshaller.unmarshal("US:California:San Francisco:" + LATITUDE + 
":" + LONGITUDE + ":v4");
+        assertThat(cookie.country(), is("US"));
+        assertThat(cookie.region(), is("California"));
+        assertThat(cookie.city(), is("San Francisco"));
+        assertThat(cookie.location(), is(notNullValue()));
+        assertThat(cookie.location().getLatitude(), is(LATITUDE));
+        assertThat(cookie.location().getLongitude(), is(LONGITUDE));
+    }
+
+    @Test public void testGeoIPWithoutLocation() {
+        GeoIPCookie cookie = 
GeoIPCookieUnmarshaller.unmarshal("FR::Paris:::v4");
+        assertThat(cookie.country(), is("FR"));
+        assertThat(cookie.region(), is(""));
+        assertThat(cookie.city(), is("Paris"));
+        assertThat(cookie.location(), is(nullValue()));
+    }
+
+    @Test public void testGeoIPEmpty() {
+        GeoIPCookie cookie = GeoIPCookieUnmarshaller.unmarshal(":::::v4");
+        assertThat(cookie.country(), is(""));
+        assertThat(cookie.region(), is(""));
+        assertThat(cookie.city(), is(""));
+        assertThat(cookie.location(), is(nullValue()));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGeoIPWrongVersion() {
+        GeoIPCookieUnmarshaller.unmarshal("RU::Moscow:1:2:v5");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGeoIPWrongParamCount() {
+        GeoIPCookieUnmarshaller.unmarshal("CA:Toronto:v4");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGeoIPMalformed() {
+        GeoIPCookieUnmarshaller.unmarshal("foo");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGeoIPWithBadLocation() {
+        GeoIPCookieUnmarshaller.unmarshal("US:California:San 
Francisco:foo:bar:v4");
+    }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/322700
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4857433286d415d1a1a15cf7e22e603cb6b70410
Gerrit-PatchSet: 5
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>
Gerrit-Reviewer: BearND <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Dbrant <[email protected]>
Gerrit-Reviewer: Mholloway <[email protected]>
Gerrit-Reviewer: Niedzielski <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to