Fixes with addresses and iCalendar
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
a46f4c058c
commit
33f7c14db6
|
@ -69,4 +69,20 @@ defmodule Mobilizon.Addresses.Address do
|
||||||
|
|
||||||
put_change(changeset, :url, url)
|
put_change(changeset, :url, url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def coords(nil), do: nil
|
||||||
|
|
||||||
|
def coords(%__MODULE__{} = address) do
|
||||||
|
with %Geo.Point{coordinates: {latitude, longitude}, srid: 4326} <- address.geom do
|
||||||
|
{latitude, longitude}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def representation(nil), do: nil
|
||||||
|
|
||||||
|
def representation(%__MODULE__{} = address) do
|
||||||
|
"#{address.street} #{address.postal_code} #{address.locality} #{address.region} #{
|
||||||
|
address.country
|
||||||
|
}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -187,7 +187,8 @@ defmodule Mobilizon.Events.Event do
|
||||||
|
|
||||||
# In case the provided addresses is an existing one
|
# In case the provided addresses is an existing one
|
||||||
@spec put_address(Changeset.t(), map) :: Changeset.t()
|
@spec put_address(Changeset.t(), map) :: Changeset.t()
|
||||||
defp put_address(%Changeset{} = changeset, %{physical_address: %{id: id} = _physical_address}) when not is_nil(id) do
|
defp put_address(%Changeset{} = changeset, %{physical_address: %{id: id} = _physical_address})
|
||||||
|
when not is_nil(id) do
|
||||||
case Addresses.get_address(id) do
|
case Addresses.get_address(id) do
|
||||||
%Address{} = address ->
|
%Address{} = address ->
|
||||||
put_assoc(changeset, :physical_address, address)
|
put_assoc(changeset, :physical_address, address)
|
||||||
|
|
|
@ -6,6 +6,7 @@ defmodule Mobilizon.Service.Export.ICalendar do
|
||||||
alias Mobilizon.{Actors, Events, Users}
|
alias Mobilizon.{Actors, Events, Users}
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Events.{Event, FeedToken}
|
alias Mobilizon.Events.{Event, FeedToken}
|
||||||
|
alias Mobilizon.Addresses.Address
|
||||||
alias Mobilizon.Users.User
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -31,7 +32,10 @@ defmodule Mobilizon.Service.Export.ICalendar do
|
||||||
dtend: event.ends_on,
|
dtend: event.ends_on,
|
||||||
description: HtmlSanitizeEx.strip_tags(event.description),
|
description: HtmlSanitizeEx.strip_tags(event.description),
|
||||||
uid: event.uuid,
|
uid: event.uuid,
|
||||||
categories: event.tags |> Enum.map(& &1.slug)
|
url: event.url,
|
||||||
|
geo: Address.coords(event.physical_address),
|
||||||
|
location: Address.representation(event.physical_address),
|
||||||
|
categories: event.tags |> Enum.map(& &1.title)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
37
test/mobilizon/service/export/icalendar_test.exs
Normal file
37
test/mobilizon/service/export/icalendar_test.exs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
defmodule Mobilizon.Service.ICalendarTest do
|
||||||
|
alias Mobilizon.Service.Export.ICalendar, as: ICalendarService
|
||||||
|
alias Mobilizon.Events.Event
|
||||||
|
alias Mobilizon.Addresses.Address
|
||||||
|
alias ICalendar.Value
|
||||||
|
use Mobilizon.DataCase
|
||||||
|
|
||||||
|
import Mobilizon.Factory
|
||||||
|
|
||||||
|
describe "export an event to ics" do
|
||||||
|
test "export basic infos" do
|
||||||
|
%Event{} = event = insert(:event)
|
||||||
|
|
||||||
|
ics = """
|
||||||
|
BEGIN:VCALENDAR
|
||||||
|
CALSCALE:GREGORIAN
|
||||||
|
VERSION:2.0
|
||||||
|
PRODID:-//ICalendar//Mobilizon//EN
|
||||||
|
BEGIN:VEVENT
|
||||||
|
CATEGORIES:#{event.tags |> Enum.map(& &1.title) |> Enum.join(",")}
|
||||||
|
DESCRIPTION:Ceci est une description avec une première phrase assez longue\\,\\n puis sur une seconde ligne
|
||||||
|
DTEND:#{Value.to_ics(event.ends_on)}
|
||||||
|
DTSTAMP:#{Value.to_ics(event.publish_at)}
|
||||||
|
DTSTART:#{Value.to_ics(event.begins_on)}
|
||||||
|
GEO:#{event.physical_address |> Address.coords() |> Tuple.to_list() |> Enum.join(";")}
|
||||||
|
LOCATION:#{Address.representation(event.physical_address)}
|
||||||
|
SUMMARY:#{event.title}
|
||||||
|
UID:#{event.uuid}
|
||||||
|
URL:#{event.url}
|
||||||
|
END:VEVENT
|
||||||
|
END:VCALENDAR
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert {:ok, ics} == ICalendarService.export_public_event(event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,8 +36,10 @@ defmodule MobilizonWeb.FeedControllerTest do
|
||||||
assert entry.title in [event1.title, event2.title]
|
assert entry.title in [event1.title, event2.title]
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert entry1.categories == [tag2.slug, tag1.slug]
|
# It seems categories takes term instead of Label
|
||||||
assert entry2.categories == [tag1.slug]
|
# <category label=\"RSS\" term=\"rss\"/>
|
||||||
|
assert entry1.categories == [tag2.title, tag1.title] |> Enum.map(&String.downcase/1)
|
||||||
|
assert entry2.categories == [tag1.title] |> Enum.map(&String.downcase/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns a 404 for the actor's public events Atom feed if the actor is not publicly visible",
|
test "it returns a 404 for the actor's public events Atom feed if the actor is not publicly visible",
|
||||||
|
@ -112,8 +114,8 @@ defmodule MobilizonWeb.FeedControllerTest do
|
||||||
assert entry.summary in [event1.title, event2.title]
|
assert entry.summary in [event1.title, event2.title]
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert entry1.categories == [tag1.slug]
|
assert entry1.categories == [tag1.title]
|
||||||
assert entry2.categories == [tag1.slug, tag2.slug]
|
assert entry2.categories == [tag1.title, tag2.title]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns a 404 page for the actor's public events iCal feed with an actor not publicly visible",
|
test "it returns a 404 page for the actor's public events iCal feed with an actor not publicly visible",
|
||||||
|
@ -183,7 +185,7 @@ defmodule MobilizonWeb.FeedControllerTest do
|
||||||
|
|
||||||
assert entry1.summary == event1.title
|
assert entry1.summary == event1.title
|
||||||
|
|
||||||
assert entry1.categories == [tag1.slug, tag2.slug]
|
assert entry1.categories == [tag1.title, tag2.title]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -325,7 +327,7 @@ defmodule MobilizonWeb.FeedControllerTest do
|
||||||
|
|
||||||
[entry1] = ExIcal.parse(conn.resp_body)
|
[entry1] = ExIcal.parse(conn.resp_body)
|
||||||
assert entry1.summary == event1.title
|
assert entry1.summary == event1.title
|
||||||
assert entry1.categories == event1.tags |> Enum.map(& &1.slug)
|
assert entry1.categories == event1.tags |> Enum.map(& &1.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns 404 for an not existing feed", %{conn: conn} do
|
test "it returns 404 for an not existing feed", %{conn: conn} do
|
||||||
|
|
|
@ -124,6 +124,7 @@ defmodule Mobilizon.Factory do
|
||||||
visibility: :public,
|
visibility: :public,
|
||||||
tags: build_list(3, :tag),
|
tags: build_list(3, :tag),
|
||||||
mentions: [],
|
mentions: [],
|
||||||
|
publish_at: DateTime.utc_now(),
|
||||||
url: Routes.page_url(Endpoint, :event, uuid),
|
url: Routes.page_url(Endpoint, :event, uuid),
|
||||||
picture: insert(:picture),
|
picture: insert(:picture),
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
|
|
Loading…
Reference in a new issue