diff --git a/lib/mobilizon/addresses/address.ex b/lib/mobilizon/addresses/address.ex index 63a455952..c7c6453e1 100644 --- a/lib/mobilizon/addresses/address.ex +++ b/lib/mobilizon/addresses/address.ex @@ -69,4 +69,20 @@ defmodule Mobilizon.Addresses.Address do put_change(changeset, :url, url) 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 diff --git a/lib/mobilizon/events/event.ex b/lib/mobilizon/events/event.ex index 71820ee80..2978e785a 100644 --- a/lib/mobilizon/events/event.ex +++ b/lib/mobilizon/events/event.ex @@ -187,7 +187,8 @@ defmodule Mobilizon.Events.Event do # In case the provided addresses is an existing one @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 %Address{} = address -> put_assoc(changeset, :physical_address, address) diff --git a/lib/service/export/icalendar.ex b/lib/service/export/icalendar.ex index 2d65e519e..32ec1625e 100644 --- a/lib/service/export/icalendar.ex +++ b/lib/service/export/icalendar.ex @@ -6,6 +6,7 @@ defmodule Mobilizon.Service.Export.ICalendar do alias Mobilizon.{Actors, Events, Users} alias Mobilizon.Actors.Actor alias Mobilizon.Events.{Event, FeedToken} + alias Mobilizon.Addresses.Address alias Mobilizon.Users.User @doc """ @@ -31,7 +32,10 @@ defmodule Mobilizon.Service.Export.ICalendar do dtend: event.ends_on, description: HtmlSanitizeEx.strip_tags(event.description), 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 diff --git a/test/mobilizon/service/export/icalendar_test.exs b/test/mobilizon/service/export/icalendar_test.exs new file mode 100644 index 000000000..aae737b63 --- /dev/null +++ b/test/mobilizon/service/export/icalendar_test.exs @@ -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 diff --git a/test/mobilizon_web/controllers/feed_controller_test.exs b/test/mobilizon_web/controllers/feed_controller_test.exs index d793586b3..a9d4423bd 100644 --- a/test/mobilizon_web/controllers/feed_controller_test.exs +++ b/test/mobilizon_web/controllers/feed_controller_test.exs @@ -36,8 +36,10 @@ defmodule MobilizonWeb.FeedControllerTest do assert entry.title in [event1.title, event2.title] end) - assert entry1.categories == [tag2.slug, tag1.slug] - assert entry2.categories == [tag1.slug] + # It seems categories takes term instead of Label + # + assert entry1.categories == [tag2.title, tag1.title] |> Enum.map(&String.downcase/1) + assert entry2.categories == [tag1.title] |> Enum.map(&String.downcase/1) end 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] end) - assert entry1.categories == [tag1.slug] - assert entry2.categories == [tag1.slug, tag2.slug] + assert entry1.categories == [tag1.title] + assert entry2.categories == [tag1.title, tag2.title] end 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.categories == [tag1.slug, tag2.slug] + assert entry1.categories == [tag1.title, tag2.title] end end @@ -325,7 +327,7 @@ defmodule MobilizonWeb.FeedControllerTest do [entry1] = ExIcal.parse(conn.resp_body) assert entry1.summary == event1.title - assert entry1.categories == event1.tags |> Enum.map(& &1.slug) + assert entry1.categories == event1.tags |> Enum.map(& &1.title) end test "it returns 404 for an not existing feed", %{conn: conn} do diff --git a/test/support/factory.ex b/test/support/factory.ex index bbb0d2250..336eccdf2 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -124,6 +124,7 @@ defmodule Mobilizon.Factory do visibility: :public, tags: build_list(3, :tag), mentions: [], + publish_at: DateTime.utc_now(), url: Routes.page_url(Endpoint, :event, uuid), picture: insert(:picture), uuid: uuid,