feat(geo): Photon proxy, address-only location, nearby search. Refs EventHub/EventHubBack#77
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
-module(logic_geo_tests).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
setup() ->
|
||||
catch ets:delete(eventhub_geo_cache),
|
||||
catch ets:delete(eventhub_geo_rl),
|
||||
logic_geo:ensure(),
|
||||
application:unset_env(eventhub, geo_http_get),
|
||||
os:putenv("PHOTON_URL", "http://photon.test"),
|
||||
ok.
|
||||
|
||||
cleanup(_) ->
|
||||
application:unset_env(eventhub, geo_http_get),
|
||||
os:unsetenv("PHOTON_URL"),
|
||||
catch ets:delete(eventhub_geo_cache),
|
||||
catch ets:delete(eventhub_geo_rl),
|
||||
ok.
|
||||
|
||||
logic_geo_test_() ->
|
||||
{foreach,
|
||||
fun setup/0,
|
||||
fun cleanup/1,
|
||||
[
|
||||
{"Suggest too short", fun test_suggest_short/0},
|
||||
{"Suggest parses photon geojson", fun test_suggest_ok/0},
|
||||
{"Geocode empty features is not_found", fun test_geocode_not_found/0},
|
||||
{"Unavailable without photon url", fun test_unavailable/0},
|
||||
{"Reverse fallback address", fun test_reverse_empty/0},
|
||||
{"Format address from properties", fun test_format_address/0}
|
||||
]}.
|
||||
|
||||
sample_geojson() ->
|
||||
<<"{
|
||||
\"features\": [{
|
||||
\"geometry\": {\"coordinates\": [37.62, 55.75]},
|
||||
\"properties\": {
|
||||
\"name\": \"Red Square\",
|
||||
\"city\": \"Moscow\",
|
||||
\"country\": \"Russia\"
|
||||
}
|
||||
}]
|
||||
}">>.
|
||||
|
||||
test_suggest_short() ->
|
||||
?assertEqual({error, invalid_query}, logic_geo:suggest(<<"ab">>, <<"ru">>, <<"ip">>)).
|
||||
|
||||
test_suggest_ok() ->
|
||||
application:set_env(eventhub, geo_http_get, fun(_) -> {ok, sample_geojson()} end),
|
||||
{ok, Hits} = logic_geo:suggest(<<"красная площадь">>, <<"ru">>, <<"ip1">>),
|
||||
?assertMatch([#{<<"lat">> := 55.75, <<"lon">> := 37.62}], Hits),
|
||||
[#{<<"address">> := Addr}] = Hits,
|
||||
?assertNotEqual(<<>>, Addr).
|
||||
|
||||
test_geocode_not_found() ->
|
||||
application:set_env(eventhub, geo_http_get, fun(_) -> {ok, <<"{\"features\":[]}">>} end),
|
||||
?assertEqual({error, not_found},
|
||||
logic_geo:geocode(<<"nowherexyz">>, <<"ru">>, <<"u1">>)).
|
||||
|
||||
test_unavailable() ->
|
||||
os:unsetenv("PHOTON_URL"),
|
||||
application:unset_env(eventhub, geo_http_get),
|
||||
?assertEqual({error, unavailable},
|
||||
logic_geo:suggest(<<"москва центр">>, <<"ru">>, <<"ip2">>)).
|
||||
|
||||
test_reverse_empty() ->
|
||||
application:set_env(eventhub, geo_http_get, fun(_) -> {ok, <<"{\"features\":[]}">>} end),
|
||||
{ok, Hit} = logic_geo:reverse(55.75, 37.62, <<"ru">>, <<"u2">>),
|
||||
?assertEqual(<<"photon">>, maps:get(<<"source">>, Hit)),
|
||||
?assertEqual(55.75, maps:get(<<"lat">>, Hit)).
|
||||
|
||||
test_format_address() ->
|
||||
Addr = logic_geo:format_address(#{
|
||||
<<"housenumber">> => <<"1">>,
|
||||
<<"street">> => <<"Tverskaya">>,
|
||||
<<"city">> => <<"Moscow">>,
|
||||
<<"country">> => <<"Russia">>
|
||||
}),
|
||||
?assertEqual(<<"1 Tverskaya, Moscow, Russia">>, Addr).
|
||||
@@ -23,6 +23,9 @@ logic_search_test_() ->
|
||||
{"Search events by tags", fun test_search_events_by_tags/0},
|
||||
{"Search events by date range", fun test_search_events_by_date/0},
|
||||
{"Search events by location", fun test_search_events_by_location/0},
|
||||
{"Search calendars by location", fun test_search_calendars_by_location/0},
|
||||
{"Geo without radius keeps distant hits", fun test_geo_no_radius/0},
|
||||
{"Geo sort by distance", fun test_geo_sort_distance/0},
|
||||
{"Combined search", fun test_combined_search/0},
|
||||
{"Search calendars", fun test_search_calendars/0},
|
||||
{"Search calendars include image_url", fun test_search_calendars_image_url/0},
|
||||
@@ -152,6 +155,59 @@ test_search_events_by_location() ->
|
||||
#{lat => 59.9343, lon => 30.3351, radius => 10})),
|
||||
?assertEqual(1, Total2).
|
||||
|
||||
test_search_calendars_by_location() ->
|
||||
OwnerId = create_test_user(user),
|
||||
NearId = create_test_calendar(OwnerId, commercial, []),
|
||||
FarId = create_test_calendar(OwnerId, commercial, []),
|
||||
set_default_location(NearId, <<"Moscow">>, 55.7558, 37.6173),
|
||||
set_default_location(FarId, <<"SPb">>, 59.9343, 30.3351),
|
||||
{Total, Hits} = calendars_from(logic_search:search(<<"calendar">>, undefined, OwnerId,
|
||||
#{lat => 55.7558, lon => 37.6173, radius => 10})),
|
||||
?assertEqual(1, Total),
|
||||
[Hit] = Hits,
|
||||
?assertEqual(NearId, maps:get(id, Hit)),
|
||||
?assert(maps:is_key(distance_km, Hit)).
|
||||
|
||||
test_geo_no_radius() ->
|
||||
OwnerId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, commercial, []),
|
||||
StartTime = eh_test_support:future_start(),
|
||||
MoscowLoc = #location{address = <<"Moscow">>, lat = 55.7558, lon = 37.6173},
|
||||
SpbLoc = #location{address = <<"SPb">>, lat = 59.9343, lon = 30.3351},
|
||||
create_test_event(CalendarId, <<"Moscow Event">>, <<"">>, StartTime, [], MoscowLoc),
|
||||
create_test_event(CalendarId, <<"SPb Event">>, <<"">>, StartTime, [], SpbLoc),
|
||||
{Total, _} = events_from(logic_search:search(<<"event">>, undefined, OwnerId,
|
||||
#{lat => 55.7558, lon => 37.6173})),
|
||||
?assertEqual(2, Total).
|
||||
|
||||
test_geo_sort_distance() ->
|
||||
OwnerId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, commercial, []),
|
||||
StartTime = eh_test_support:future_start(),
|
||||
MoscowLoc = #location{address = <<"Moscow">>, lat = 55.7558, lon = 37.6173},
|
||||
SpbLoc = #location{address = <<"SPb">>, lat = 59.9343, lon = 30.3351},
|
||||
create_test_event(CalendarId, <<"Moscow Event">>, <<"">>, StartTime, [], MoscowLoc),
|
||||
create_test_event(CalendarId, <<"SPb Event">>, <<"">>, StartTime, [], SpbLoc),
|
||||
{_, [First | _]} = events_from(logic_search:search(<<"event">>, undefined, OwnerId,
|
||||
#{lat => 55.7558, lon => 37.6173})),
|
||||
?assertMatch(#{title := <<"Moscow Event">>}, First),
|
||||
?assert(maps:is_key(distance_km, First)).
|
||||
|
||||
set_default_location(CalendarId, Addr, Lat, Lon) ->
|
||||
{ok, Cal} = core_calendar:get_by_id(CalendarId),
|
||||
Settings0 = case Cal#calendar.settings of
|
||||
M when is_map(M) -> M;
|
||||
_ -> #{}
|
||||
end,
|
||||
Settings = Settings0#{
|
||||
<<"default_location">> => #{
|
||||
<<"address">> => Addr,
|
||||
<<"lat">> => Lat,
|
||||
<<"lon">> => Lon
|
||||
}
|
||||
},
|
||||
core_calendar:update(CalendarId, [{settings, Settings}]).
|
||||
|
||||
test_combined_search() ->
|
||||
OwnerId = create_test_user(user),
|
||||
CalendarId = create_test_calendar(OwnerId, commercial, []),
|
||||
|
||||
Reference in New Issue
Block a user