Add GeoSpatial backends for geocoding

Signed-off-by: Thomas Citharel <tcit@tcit.fr>

Geospatial Backend

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-03-12 11:52:28 +01:00
parent f7284740e3
commit 98b7618338
29 changed files with 1301 additions and 1 deletions

View File

@@ -0,0 +1,28 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://api-adresse.data.gouv.fr/reverse/?lon=4.842569&lat=45.751718"
},
"response": {
"binary": false,
"body": "{\"limit\": 1, \"features\": [{\"geometry\": {\"coordinates\": [4.842569, 45.751718], \"type\": \"Point\"}, \"properties\": {\"y\": 6518613.6, \"city\": \"Lyon\", \"label\": \"10 Rue Jangot 69007 Lyon\", \"score\": 1.0, \"distance\": 0, \"type\": \"housenumber\", \"street\": \"Rue Jangot\", \"name\": \"10 Rue Jangot\", \"x\": 843191.7, \"id\": \"69387_3650_f5ec2a\", \"housenumber\": \"10\", \"citycode\": \"69387\", \"context\": \"69, Rh\\u00f4ne, Auvergne-Rh\\u00f4ne-Alpes (Rh\\u00f4ne-Alpes)\", \"postcode\": \"69007\", \"importance\": 0.3164}, \"type\": \"Feature\"}], \"attribution\": \"BAN\", \"version\": \"draft\", \"type\": \"FeatureCollection\", \"licence\": \"ODbL 1.0\"}",
"headers": {
"Server": "nginx/1.13.4",
"Date": "Wed, 13 Mar 2019 17:22:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "598",
"Connection": "keep-alive",
"X-Cache-Status": "MISS",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "X-Requested-With"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,29 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://api-adresse.data.gouv.fr/search/?q=10%20rue%20Jangot&limit=10"
},
"response": {
"binary": false,
"body": "{\"limit\": 10, \"features\": [{\"geometry\": {\"coordinates\": [4.842569, 45.751718], \"type\": \"Point\"}, \"properties\": {\"y\": 6518573.3, \"city\": \"Lyon\", \"label\": \"10 Rue Jangot 69007 Lyon\", \"score\": 0.8469454545454544, \"type\": \"housenumber\", \"street\": \"Rue Jangot\", \"name\": \"10 Rue Jangot\", \"x\": 843232.2, \"id\": \"ADRNIVX_0000000260022046\", \"housenumber\": \"10\", \"citycode\": \"69387\", \"context\": \"69, Rh\\u00f4ne, Auvergne-Rh\\u00f4ne-Alpes (Rh\\u00f4ne-Alpes)\", \"postcode\": \"69007\", \"importance\": 0.3164}, \"type\": \"Feature\"}, {\"geometry\": {\"coordinates\": [2.440118, 50.371066], \"type\": \"Point\"}, \"properties\": {\"y\": 7030518.3, \"city\": \"Bailleul-aux-Cornailles\", \"label\": \"Rue Jangon 62127 Bailleul-aux-Cornailles\", \"score\": 0.5039055944055943, \"name\": \"Rue Jangon\", \"x\": 660114.7, \"id\": \"62070_0100_9b8d3c\", \"type\": \"street\", \"citycode\": \"62070\", \"context\": \"62, Pas-de-Calais, Hauts-de-France (Nord-Pas-de-Calais)\", \"postcode\": \"62127\", \"importance\": 0.0045}, \"type\": \"Feature\"}], \"attribution\": \"BAN\", \"version\": \"draft\", \"type\": \"FeatureCollection\", \"licence\": \"ODbL 1.0\", \"query\": \"10 rue Jangot\"}",
"headers": {
"Server": "nginx/1.13.4",
"Date": "Wed, 13 Mar 2019 17:01:21 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "1087",
"Connection": "keep-alive",
"Vary": "Accept-Encoding",
"X-Cache-Status": "MISS",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "X-Requested-With"
},
"status_code": 200,
"type": "ok"
}
}
]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://maps.googleapis.com/maps/api/geocode/json?address=10%20rue%20Jangot&limit=10&key=toto&language=en"
},
"response": {
"binary": false,
"body": "{\n \"results\" : [\n {\n \"address_components\" : [\n {\n \"long_name\" : \"10\",\n \"short_name\" : \"10\",\n \"types\" : [ \"street_number\" ]\n },\n {\n \"long_name\" : \"Rue Jangot\",\n \"short_name\" : \"Rue Jangot\",\n \"types\" : [ \"route\" ]\n },\n {\n \"long_name\" : \"Lyon\",\n \"short_name\" : \"Lyon\",\n \"types\" : [ \"locality\", \"political\" ]\n },\n {\n \"long_name\" : \"Rhône\",\n \"short_name\" : \"Rhône\",\n \"types\" : [ \"administrative_area_level_2\", \"political\" ]\n },\n {\n \"long_name\" : \"Auvergne-Rhône-Alpes\",\n \"short_name\" : \"Auvergne-Rhône-Alpes\",\n \"types\" : [ \"administrative_area_level_1\", \"political\" ]\n },\n {\n \"long_name\" : \"France\",\n \"short_name\" : \"FR\",\n \"types\" : [ \"country\", \"political\" ]\n },\n {\n \"long_name\" : \"69007\",\n \"short_name\" : \"69007\",\n \"types\" : [ \"postal_code\" ]\n }\n ],\n \"formatted_address\" : \"10 Rue Jangot, 69007 Lyon, France\",\n \"geometry\" : {\n \"location\" : {\n \"lat\" : 45.75164940000001,\n \"lng\" : 4.8424032\n },\n \"location_type\" : \"ROOFTOP\",\n \"viewport\" : {\n \"northeast\" : {\n \"lat\" : 45.75299838029151,\n \"lng\" : 4.843752180291502\n },\n \"southwest\" : {\n \"lat\" : 45.75030041970851,\n \"lng\" : 4.841054219708497\n }\n }\n },\n \"place_id\" : \"ChIJtW0QikTq9EcRLI4Vy6bRx0U\",\n \"plus_code\" : {\n \"compound_code\" : \"QR2R+MX Lyon, France\",\n \"global_code\" : \"8FQ6QR2R+MX\"\n },\n \"types\" : [ \"street_address\" ]\n }\n ],\n \"status\" : \"OK\"\n}\n",
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Date": "Wed, 13 Mar 2019 17:50:19 GMT",
"Expires": "Thu, 14 Mar 2019 17:50:19 GMT",
"Access-Control-Allow-Origin": "*",
"Server": "mafe",
"X-XSS-Protection": "1; mode=block",
"X-Frame-Options": "SAMEORIGIN",
"Server-Timing": "gfet4t7; dur=52",
"Cache-Control": "public, max-age=86400",
"Age": "17",
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"",
"Accept-Ranges": "none",
"Vary": "Accept-Encoding",
"Transfer-Encoding": "chunked"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,36 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://open.mapquestapi.com/geocoding/v1/reverse?key=secret_key&location=45.751718,4.842569&maxResults=10"
},
"response": {
"binary": false,
"body": "{\"info\":{\"statuscode\":0,\"copyright\":{\"text\":\"\\u00A9 2019 MapQuest, Inc.\",\"imageUrl\":\"http://api.mqcdn.com/res/mqlogo.gif\",\"imageAltText\":\"\\u00A9 2019 MapQuest, Inc.\"},\"messages\":[]},\"options\":{\"maxResults\":1,\"thumbMaps\":true,\"ignoreLatLngInput\":false},\"results\":[{\"providedLocation\":{\"latLng\":{\"lat\":45.751718,\"lng\":4.842569}},\"locations\":[{\"street\":\"10 Rue Jangot\",\"adminArea6\":\"\",\"adminArea6Type\":\"Neighborhood\",\"adminArea5\":\"Lyon\",\"adminArea5Type\":\"City\",\"adminArea4\":\"\",\"adminArea4Type\":\"County\",\"adminArea3\":\"Auvergne-Rh\\u00F4ne-Alpes\",\"adminArea3Type\":\"State\",\"adminArea1\":\"FR\",\"adminArea1Type\":\"Country\",\"postalCode\":\"69007\",\"geocodeQualityCode\":\"P1AAA\",\"geocodeQuality\":\"POINT\",\"dragPoint\":false,\"sideOfStreet\":\"N\",\"linkId\":\"0\",\"unknownInput\":\"\",\"type\":\"s\",\"latLng\":{\"lat\":45.751714,\"lng\":4.842566},\"displayLatLng\":{\"lat\":45.751714,\"lng\":4.842566},\"mapUrl\":\"http://open.mapquestapi.com/staticmap/v5/map?key=secret_key&type=map&size=225,160&locations=45.7517141,4.8425657|marker-sm-50318A-1&scalebar=true&zoom=15&rand=-570915433\"}]}]}",
"headers": {
"Access-Control-Allow-Methods": "OPTIONS,GET,POST",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "no-cache, must-revalidate",
"Content-Type": "application/json;charset=UTF-8",
"Date": "Thu, 14 Mar 2019 09:27:01 GMT",
"Expires": "Mon, 20 Dec 1998 01:00:00 GMT",
"GeocodeTransactionCount": "0",
"Last-Modified": "Thu, 14 Mar 2019 09:27:01 GMT",
"Pragma": "no-cache",
"ReverseGeocodeTransactionCount": "1",
"Server": "Apache-Coyote/1.1",
"Set-Cookie": "JSESSIONID=something; Path=/; HttpOnly",
"status": "success",
"transactionWeight": "1.0",
"Content-Length": "1063",
"Connection": "keep-alive"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,36 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://open.mapquestapi.com/geocoding/v1/address?key=secret_key&location=10%20rue%20Jangot&maxResults=10"
},
"response": {
"binary": false,
"body": "{\"info\":{\"statuscode\":0,\"copyright\":{\"text\":\"\\u00A9 2019 MapQuest, Inc.\",\"imageUrl\":\"http://api.mqcdn.com/res/mqlogo.gif\",\"imageAltText\":\"\\u00A9 2019 MapQuest, Inc.\"},\"messages\":[]},\"options\":{\"maxResults\":10,\"thumbMaps\":true,\"ignoreLatLngInput\":false},\"results\":[{\"providedLocation\":{\"location\":\"10 rue Jangot\"},\"locations\":[{\"street\":\"10 Rue Jangot\",\"adminArea6\":\"7e\",\"adminArea6Type\":\"Neighborhood\",\"adminArea5\":\"Lyon\",\"adminArea5Type\":\"City\",\"adminArea4\":\"Lyon\",\"adminArea4Type\":\"County\",\"adminArea3\":\"Auvergne-Rh\\u00F4ne-Alpes\",\"adminArea3Type\":\"State\",\"adminArea1\":\"FR\",\"adminArea1Type\":\"Country\",\"postalCode\":\"69007\",\"geocodeQualityCode\":\"P1AXX\",\"geocodeQuality\":\"POINT\",\"dragPoint\":false,\"sideOfStreet\":\"N\",\"linkId\":\"0\",\"unknownInput\":\"\",\"type\":\"s\",\"latLng\":{\"lat\":45.751714,\"lng\":4.842566},\"displayLatLng\":{\"lat\":45.751714,\"lng\":4.842566},\"mapUrl\":\"http://open.mapquestapi.com/staticmap/v5/map?key=secret_key&type=map&size=225,160&locations=45.7517141,4.8425657|marker-sm-50318A-1&scalebar=true&zoom=15&rand=1358091752\"}]}]}",
"headers": {
"Access-Control-Allow-Methods": "OPTIONS,GET,POST",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "no-cache, must-revalidate",
"Content-Type": "application/json;charset=UTF-8",
"Date": "Thu, 14 Mar 2019 09:27:01 GMT",
"Expires": "Mon, 20 Dec 1998 01:00:00 GMT",
"GeocodeTransactionCount": "1",
"Last-Modified": "Thu, 14 Mar 2019 09:27:01 GMT",
"Pragma": "no-cache",
"ReverseGeocodeTransactionCount": "0",
"Server": "Apache-Coyote/1.1",
"Set-Cookie": "JSESSIONID=something; Path=/; HttpOnly",
"status": "success",
"transactionWeight": "1.0",
"Content-Length": "1055",
"Connection": "keep-alive"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,30 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=45.751718&lon=4.842569&addressdetails=1"
},
"response": {
"binary": false,
"body": "{\"place_id\":41453794,\"licence\":\"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright\",\"osm_type\":\"node\",\"osm_id\":3078260611,\"lat\":\"45.7517141\",\"lon\":\"4.8425657\",\"place_rank\":30,\"category\":\"place\",\"type\":\"house\",\"importance\":\"0\",\"addresstype\":\"place\",\"name\":null,\"display_name\":\"10, Rue Jangot, La Guillotière, Lyon 7e Arrondissement, Lyon, Métropole de Lyon, Circonscription départementale du Rhône, Auvergne-Rhône-Alpes, France métropolitaine, 69007, France\",\"address\":{\"house_number\":\"10\",\"road\":\"Rue Jangot\",\"suburb\":\"La Guillotière\",\"city_district\":\"Lyon 7e Arrondissement\",\"city\":\"Lyon\",\"county\":\"Lyon\",\"state_district\":\"Circonscription départementale du Rhône\",\"state\":\"Auvergne-Rhône-Alpes\",\"country\":\"France\",\"postcode\":\"69007\",\"country_code\":\"fr\"},\"boundingbox\":[\"45.7516141\",\"45.7518141\",\"4.8424657\",\"4.8426657\"]}",
"headers": {
"Date": "Thu, 14 Mar 2019 10:26:11 GMT",
"Server": "Apache/2.4.29 (Ubuntu)",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,GET",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
"Expect-CT": "max-age=0, report-uri=\"https://openstreetmap.report-uri.com/r/d/ct/reportOnly\"",
"Upgrade": "h2",
"Connection": "Upgrade, close",
"Transfer-Encoding": "chunked",
"Content-Type": "application/json; charset=UTF-8"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,30 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://nominatim.openstreetmap.org/search?format=jsonv2&q=10%20rue%20Jangot&limit=10&accept-language=en&addressdetails=1"
},
"response": {
"binary": false,
"body": "[{\"place_id\":41453794,\"licence\":\"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright\",\"osm_type\":\"node\",\"osm_id\":3078260611,\"boundingbox\":[\"45.7516641\",\"45.7517641\",\"4.8425157\",\"4.8426157\"],\"lat\":\"45.7517141\",\"lon\":\"4.8425657\",\"display_name\":\"10, Rue Jangot, La Guillotière, Lyon 7e Arrondissement, Lyon, Métropole de Lyon, Departemental constituency of Rhône, Auvergne-Rhône-Alpes, Metropolitan France, 69007, France\",\"place_rank\":30,\"category\":\"place\",\"type\":\"house\",\"importance\":0.31100000000000005,\"address\":{\"house_number\":\"10\",\"road\":\"Rue Jangot\",\"suburb\":\"La Guillotière\",\"city_district\":\"Lyon 7e Arrondissement\",\"city\":\"Lyon\",\"county\":\"Lyon\",\"state_district\":\"Departemental constituency of Rhône\",\"state\":\"Auvergne-Rhône-Alpes\",\"country\":\"France\",\"postcode\":\"69007\",\"country_code\":\"fr\"}}]",
"headers": {
"Date": "Thu, 14 Mar 2019 10:24:24 GMT",
"Server": "Apache/2.4.29 (Ubuntu)",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,GET",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
"Expect-CT": "max-age=0, report-uri=\"https://openstreetmap.report-uri.com/r/d/ct/reportOnly\"",
"Upgrade": "h2",
"Connection": "Upgrade, close",
"Transfer-Encoding": "chunked",
"Content-Type": "application/json; charset=UTF-8"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,26 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://photon.komoot.de/reverse?lon=4.842569&lat=45.751718"
},
"response": {
"binary": false,
"body": "{\"features\":[{\"geometry\":{\"coordinates\":[4.8416864,45.7605435],\"type\":\"Point\"},\"type\":\"Feature\",\"properties\":{\"osm_id\":4662865602,\"osm_type\":\"N\",\"country\":\"France\",\"osm_key\":\"leisure\",\"city\":\"Lyon\",\"street\":\"Rue Pravaz\",\"osm_value\":\"fitness_centre\",\"postcode\":\"69003\",\"name\":\"L'appart Fitness\",\"state\":\"Auvergne-Rhône-Alpes\"}}],\"type\":\"FeatureCollection\"}",
"headers": {
"Server": "nginx/1.9.3 (Ubuntu)",
"Date": "Thu, 14 Mar 2019 10:46:45 GMT",
"Content-Type": "application/json;charset=utf-8",
"Transfer-Encoding": "chunked",
"Connection": "keep-alive",
"Access-Control-Allow-Origin": "*"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,26 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "https://photon.komoot.de/api/?q=10%20rue%20Jangot&lang=en&limit=10"
},
"response": {
"binary": false,
"body": "{\"features\":[{\"geometry\":{\"coordinates\":[4.8425657,45.7517141],\"type\":\"Point\"},\"type\":\"Feature\",\"properties\":{\"osm_id\":3078260611,\"osm_type\":\"N\",\"country\":\"France\",\"osm_key\":\"place\",\"housenumber\":\"10\",\"city\":\"Lyon\",\"street\":\"Rue Jangot\",\"osm_value\":\"house\",\"postcode\":\"69007\",\"state\":\"Auvergne-Rhône-Alpes\"}},{\"geometry\":{\"coordinates\":[4.8424254,45.7517056],\"type\":\"Point\"},\"type\":\"Feature\",\"properties\":{\"osm_id\":3078260612,\"osm_type\":\"N\",\"country\":\"France\",\"osm_key\":\"place\",\"housenumber\":\"10bis\",\"city\":\"Lyon\",\"street\":\"Rue Jangot\",\"osm_value\":\"house\",\"postcode\":\"69007\",\"state\":\"Auvergne-Rhône-Alpes\"}}],\"type\":\"FeatureCollection\"}",
"headers": {
"Server": "nginx/1.9.3 (Ubuntu)",
"Date": "Thu, 14 Mar 2019 10:46:43 GMT",
"Content-Type": "application/json;charset=utf-8",
"Transfer-Encoding": "chunked",
"Connection": "keep-alive",
"Access-Control-Allow-Origin": "*"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,59 @@
defmodule Mobilizon.Service.Geospatial.AddokTest do
use Mobilizon.DataCase, async: false
alias Mobilizon.Service.Geospatial.Addok
alias Mobilizon.Addresses.Address
import Mock
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
@endpoint Application.get_env(:mobilizon, Mobilizon.Service.Geospatial.Addok)
|> get_in([:endpoint])
@fake_endpoint "https://domain.tld"
describe "search address" do
test "produces a valid search address" do
with_mock HTTPoison, get: fn _url -> "{}" end do
Addok.search("10 Rue Jangot")
assert_called(HTTPoison.get("#{@endpoint}/search/?q=10%20Rue%20Jangot&limit=10"))
end
end
test "produces a valid search address with options" do
with_mock HTTPoison, get: fn _url -> "{}" end do
Addok.search("10 Rue Jangot",
endpoint: @fake_endpoint,
limit: 5,
coords: %{lat: 49, lon: 12}
)
assert_called(
HTTPoison.get("#{@fake_endpoint}/search/?q=10%20Rue%20Jangot&limit=5&lat=49&lon=12")
)
end
end
test "returns a valid address from search" do
use_cassette "geospatial/addok/search" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{coordinates: {4.842569, 45.751718}, properties: %{}, srid: 4326}
} == Addok.search("10 rue Jangot") |> hd
end
end
test "returns a valid address from reverse geocode" do
use_cassette "geospatial/addok/geocode" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{coordinates: {4.842569, 45.751718}, properties: %{}, srid: 4326}
} == Addok.geocode(4.842569, 45.751718) |> hd
end
end
end
end

View File

@@ -0,0 +1,8 @@
defmodule Mobilizon.Service.GeospatialTest do
use Mobilizon.DataCase
alias Mobilizon.Service.Geospatial
describe "get service" do
assert Geospatial.service() === Elixir.Mobilizon.Service.Geospatial.Mock
end
end

View File

@@ -0,0 +1,80 @@
defmodule Mobilizon.Service.Geospatial.GoogleMapsTest do
use Mobilizon.DataCase, async: false
alias Mobilizon.Service.Geospatial.GoogleMaps
alias Mobilizon.Addresses.Address
import Mock
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
describe "search address" do
test "without API Key triggers an error" do
assert_raise ArgumentError, "API Key required to use Google Maps", fn ->
GoogleMaps.search("10 Rue Jangot")
end
end
test "produces a valid search address with options" do
with_mock HTTPoison,
get: fn _url ->
{:ok,
%HTTPoison.Response{status_code: 200, body: "{\"status\": \"OK\", \"results\": []}"}}
end do
GoogleMaps.search("10 Rue Jangot",
limit: 5,
lang: "fr",
api_key: "toto"
)
assert_called(
HTTPoison.get(
"https://maps.googleapis.com/maps/api/geocode/json?limit=5&key=toto&language=fr&address=10%20Rue%20Jangot"
)
)
end
end
test "triggers an error with an invalid API Key" do
assert_raise ArgumentError, "The provided API key is invalid.", fn ->
GoogleMaps.search("10 rue Jangot", api_key: "secret_key")
end
end
test "returns a valid address from search" do
use_cassette "geospatial/google_maps/search" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot, 69007 Lyon, France",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "France",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.8424032, 45.75164940000001},
properties: %{},
srid: 4326
}
} == GoogleMaps.search("10 rue Jangot", api_key: "toto") |> hd
end
end
test "returns a valid address from reverse geocode" do
use_cassette "geospatial/google_maps/geocode" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot, 69007 Lyon, France",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "France",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.8424967, 45.751725},
properties: %{},
srid: 4326
}
} ==
GoogleMaps.geocode(4.842569, 45.751718, api_key: "toto")
|> hd
end
end
end
end

View File

@@ -0,0 +1,85 @@
defmodule Mobilizon.Service.Geospatial.MapQuestTest do
use Mobilizon.DataCase, async: false
alias Mobilizon.Service.Geospatial.MapQuest
alias Mobilizon.Addresses.Address
import Mock
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
describe "search address" do
test "without API Key triggers an error" do
assert_raise ArgumentError, "API Key required to use MapQuest", fn ->
MapQuest.search("10 Rue Jangot")
end
end
test "produces a valid search address with options" do
with_mock HTTPoison,
get: fn _url ->
{:ok,
%HTTPoison.Response{
status_code: 200,
body: "{\"info\": {\"statuscode\": 0}, \"results\": []}"
}}
end do
MapQuest.search("10 Rue Jangot",
limit: 5,
lang: "fr",
api_key: "toto"
)
assert_called(
HTTPoison.get(
"https://open.mapquestapi.com/geocoding/v1/address?key=toto&location=10%20Rue%20Jangot&maxResults=5"
)
)
end
end
test "triggers an error with an invalid API Key" do
assert_raise ArgumentError, "The AppKey submitted with this request is invalid.", fn ->
MapQuest.search("10 rue Jangot", api_key: "secret_key")
end
end
test "returns a valid address from search" do
use_cassette "geospatial/map_quest/search" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "FR",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.842566, 45.751714},
properties: %{},
srid: 4326
}
} ==
MapQuest.search("10 rue Jangot", api_key: "secret_key")
|> hd
end
end
test "returns a valid address from reverse geocode" do
use_cassette "geospatial/map_quest/geocode" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "FR",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.842569, 45.751718},
properties: %{},
srid: 4326
}
} ==
MapQuest.geocode(4.842569, 45.751718, api_key: "secret_key")
|> hd
end
end
end
end

View File

@@ -0,0 +1,68 @@
defmodule Mobilizon.Service.Geospatial.NominatimTest do
use Mobilizon.DataCase, async: false
alias Mobilizon.Service.Geospatial.Nominatim
alias Mobilizon.Addresses.Address
import Mock
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
describe "search address" do
test "produces a valid search address with options" do
with_mock HTTPoison,
get: fn _url ->
{:ok, %HTTPoison.Response{status_code: 200, body: "[]"}}
end do
Nominatim.search("10 Rue Jangot",
limit: 5,
lang: "fr"
)
assert_called(
HTTPoison.get(
"https://nominatim.openstreetmap.org/search?format=jsonv2&q=10%20Rue%20Jangot&limit=5&accept-language=fr&addressdetails=1"
)
)
end
end
test "returns a valid address from search" do
use_cassette "geospatial/nominatim/search" do
assert %Address{
addressLocality: "Lyon",
description:
"10, Rue Jangot, La Guillotière, Lyon 7e Arrondissement, Lyon, Métropole de Lyon, Departemental constituency of Rhône, Auvergne-Rhône-Alpes, Metropolitan France, 69007, France",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "France",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.8425657, 45.7517141},
properties: %{},
srid: 4326
}
} == Nominatim.search("10 rue Jangot") |> hd
end
end
test "returns a valid address from reverse geocode" do
use_cassette "geospatial/nominatim/geocode" do
assert %Address{
addressLocality: "Lyon",
description:
"10, Rue Jangot, La Guillotière, Lyon 7e Arrondissement, Lyon, Métropole de Lyon, Circonscription départementale du Rhône, Auvergne-Rhône-Alpes, France métropolitaine, 69007, France",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "France",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.8425657, 45.7517141},
properties: %{},
srid: 4326
}
} ==
Nominatim.geocode(4.842569, 45.751718)
|> hd
end
end
end
end

View File

@@ -0,0 +1,65 @@
defmodule Mobilizon.Service.Geospatial.PhotonTest do
use Mobilizon.DataCase, async: false
alias Mobilizon.Service.Geospatial.Photon
alias Mobilizon.Addresses.Address
import Mock
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
describe "search address" do
test "produces a valid search address with options" do
with_mock HTTPoison,
get: fn _url ->
{:ok, %HTTPoison.Response{status_code: 200, body: "{\"features\": []"}}
end do
Photon.search("10 Rue Jangot",
limit: 5,
lang: "fr"
)
assert_called(
HTTPoison.get("https://photon.komoot.de/api/?q=10%20Rue%20Jangot&lang=fr&limit=5")
)
end
end
test "returns a valid address from search" do
use_cassette "geospatial/photon/search" do
assert %Address{
addressLocality: "Lyon",
description: "10 Rue Jangot",
addressRegion: "Auvergne-Rhône-Alpes",
addressCountry: "France",
postalCode: "69007",
streetAddress: "10 Rue Jangot",
geom: %Geo.Point{
coordinates: {4.8425657, 45.7517141},
properties: %{},
srid: 4326
}
} == Photon.search("10 rue Jangot") |> hd
end
end
# Photon returns something quite wrong, so no need to test this right now.
# test "returns a valid address from reverse geocode" do
# use_cassette "geospatial/photon/geocode" do
# assert %Address{
# addressLocality: "Lyon",
# description: "",
# addressRegion: "Auvergne-Rhône-Alpes",
# addressCountry: "France",
# postalCode: "69007",
# streetAddress: "10 Rue Jangot",
# geom: %Geo.Point{
# coordinates: {4.8425657, 45.7517141},
# properties: %{},
# srid: 4326
# }
# } ==
# Photon.geocode(4.8425657, 45.7517141)
# |> hd
# end
# end
end
end

View File

@@ -0,0 +1,15 @@
defmodule Mobilizon.Mobilizon.Service.Geospatial.Mock do
@moduledoc """
Mock for Geospatial Provider implementations
"""
alias Mobilizon.Service.Geospatial.Provider
alias Mobilizon.Addresses.Address
@behaviour Provider
@impl Provider
def geocode(_lon, _lat, _options \\ []), do: [%Address{}]
@impl Provider
def search(_q, _options \\ []), do: [%Address{}]
end