From 979aad5acb7215c1a3430487ac523d6f6903734a Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 27 Jul 2018 10:45:35 +0200 Subject: [PATCH] Remove credo and use mix format, and lint everything Signed-off-by: Thomas Citharel --- .formatter.exs | 3 + .gitlab-ci.yml | 2 +- config/config.exs | 34 +- config/dogma.exs | 21 +- config/prod.exs | 18 +- config/test.exs | 9 +- lib/eventos/actors/actor.ex | 182 ++++-- lib/eventos/actors/actors.ex | 206 ++++--- lib/eventos/actors/bot.ex | 9 +- lib/eventos/actors/follower.ex | 9 +- lib/eventos/actors/member.ex | 9 +- lib/eventos/actors/service/activation.ex | 7 +- lib/eventos/actors/service/reset_password.ex | 38 +- lib/eventos/actors/user.ex | 79 ++- lib/eventos/addresses/address.ex | 31 +- lib/eventos/addresses/addresses.ex | 2 +- lib/eventos/application.ex | 2 +- lib/eventos/email/user.ex | 13 +- lib/eventos/events/category.ex | 7 +- lib/eventos/events/comment.ex | 19 +- lib/eventos/events/event.ex | 77 +-- lib/eventos/events/events.ex | 115 ++-- lib/eventos/events/participant.ex | 7 +- lib/eventos/events/session.ex | 49 +- lib/eventos/events/tag.ex | 15 +- lib/eventos/events/track.ex | 11 +- lib/eventos/export/icalendar.ex | 17 +- lib/eventos/postgrex_types.ex | 6 +- lib/eventos/slug.ex | 1 + lib/eventos_web.ex | 5 +- lib/eventos_web/auth_pipeline.ex | 14 +- lib/eventos_web/channels/user_socket.ex | 2 +- .../controllers/actor_controller.ex | 38 +- .../controllers/address_controller.ex | 11 +- lib/eventos_web/controllers/bot_controller.ex | 6 +- .../controllers/category_controller.ex | 3 +- .../controllers/comment_controller.ex | 3 +- .../controllers/event_controller.ex | 64 ++- .../controllers/event_request_controller.ex | 4 +- .../controllers/group_controller.ex | 11 +- .../controllers/inboxes_controller.ex | 2 - .../controllers/nodeinfo_controller.ex | 10 +- .../controllers/outboxes_controller.ex | 1 - .../controllers/page_controller.ex | 4 +- .../controllers/participant_controller.ex | 8 +- .../controllers/search_controller.ex | 9 +- .../controllers/session_controller.ex | 3 +- lib/eventos_web/controllers/tag_controller.ex | 3 +- .../controllers/track_controller.ex | 3 +- .../controllers/user_controller.ex | 33 +- .../controllers/user_session_controller.ex | 11 +- lib/eventos_web/endpoint.ex | 36 +- lib/eventos_web/guardian.ex | 11 +- lib/eventos_web/http_signature.ex | 14 +- lib/eventos_web/router.ex | 161 +++--- .../views/activity_pub/actor_view.ex | 40 +- .../views/activity_pub/object_view.ex | 6 +- lib/eventos_web/views/actor_view.ex | 19 +- lib/eventos_web/views/address_view.ex | 8 +- lib/eventos_web/views/bot_view.ex | 4 +- lib/eventos_web/views/category_view.ex | 6 +- lib/eventos_web/views/comment_view.ex | 6 +- lib/eventos_web/views/error_helpers.ex | 4 +- lib/eventos_web/views/error_view.ex | 2 +- lib/eventos_web/views/event_view.ex | 25 +- lib/eventos_web/views/group_view.ex | 8 +- lib/eventos_web/views/participant_view.ex | 3 +- lib/eventos_web/views/search_view.ex | 2 +- lib/eventos_web/views/session_view.ex | 6 +- lib/eventos_web/views/tag_view.ex | 3 +- lib/eventos_web/views/track_view.ex | 5 +- lib/eventos_web/views/user_view.ex | 17 +- lib/mix/tasks/create_bot.ex | 13 +- lib/service/activity_pub/activity_pub.ex | 170 +++--- lib/service/activity_pub/transmogrifier.ex | 528 +++++++++--------- lib/service/activity_pub/utils.ex | 193 ++++--- lib/service/federator.ex | 12 +- .../http_signatures/http_signatures.ex | 15 +- lib/service/streamer.ex | 12 +- lib/service/web_finger/web_finger.ex | 24 +- mix.exs | 2 +- priv/repo/seeds.exs | 31 +- test/eventos/actors/actors_test.exs | 67 ++- test/eventos/addresses/addresses_test.exs | 33 +- test/eventos/events/events_test.exs | 82 ++- .../service/activitypub/activitypub_test.exs | 4 +- .../service/web_finger/web_finger_test.exs | 15 +- .../activity_pub_controller_test.exs | 198 +++---- .../controllers/actor_controller_test.exs | 58 +- .../controllers/address_controller_test.exs | 110 ++-- .../controllers/bot_controller_test.exs | 45 +- .../controllers/category_controller_test.exs | 55 +- .../controllers/comment_controller_test.exs | 56 +- .../controllers/event_controller_test.exs | 105 +++- .../controllers/page_controller_test.exs | 2 +- .../controllers/session_controller_test.exs | 105 ++-- .../controllers/tag_controller_test.exs | 31 +- .../controllers/track_controller_test.exs | 63 ++- .../controllers/user_controller_test.exs | 61 +- test/eventos_web/views/error_view_test.exs | 9 +- test/support/channel_case.ex | 4 +- test/support/conn_case.ex | 5 +- test/support/factory.ex | 23 +- test/test_helper.exs | 2 +- 104 files changed, 2278 insertions(+), 1487 deletions(-) create mode 100644 .formatter.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 000000000..2bed17cc0 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e31d8cea3..2e201f751 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,5 +31,5 @@ before_script: mix: script: - - mix credo + - mix format --check-formatted --dry-run - mix coveralls diff --git a/config/config.exs b/config/config.exs index 474c73cae..c5792d8ec 100644 --- a/config/config.exs +++ b/config/config.exs @@ -24,8 +24,7 @@ config :eventos, EventosWeb.Endpoint, url: [host: "localhost"], secret_key_base: "1yOazsoE0Wqu4kXk3uC5gu3jDbShOimTCzyFL3OjCdBmOXMyHX87Qmf3+Tu9s0iM", render_errors: [view: EventosWeb.ErrorView, accepts: ~w(html json)], - pubsub: [name: Eventos.PubSub, - adapter: Phoenix.PubSub.PG2], + pubsub: [name: Eventos.PubSub, adapter: Phoenix.PubSub.PG2], instance: "localhost", email_from: "noreply@localhost", email_to: "noreply@localhost" @@ -37,23 +36,26 @@ config :logger, :console, # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. -import_config "#{Mix.env}.exs" +import_config "#{Mix.env()}.exs" config :eventos, EventosWeb.Guardian, - issuer: "eventos", - secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo" + issuer: "eventos", + secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo" config :guardian, Guardian.DB, - repo: Eventos.Repo, - schema_name: "guardian_tokens", # default - token_types: ["refresh_token"], # store all token types if not set - sweep_interval: 60 # default: 60 minutes + repo: Eventos.Repo, + # default + schema_name: "guardian_tokens", + # store all token types if not set + token_types: ["refresh_token"], + # default: 60 minutes + sweep_interval: 60 config :geolix, - databases: [ - %{ - id: :city, - adapter: Geolix.Adapter.MMDB2, - source: System.get_env("GEOLITE_CITIES_PATH") || "priv/static/GeoLite2-City.mmdb" - } - ] + databases: [ + %{ + id: :city, + adapter: Geolix.Adapter.MMDB2, + source: System.get_env("GEOLITE_CITIES_PATH") || "priv/static/GeoLite2-City.mmdb" + } + ] diff --git a/config/dogma.exs b/config/dogma.exs index fd2dba779..8c2d5141f 100644 --- a/config/dogma.exs +++ b/config/dogma.exs @@ -2,16 +2,15 @@ use Mix.Config alias Dogma.Rule config :dogma, + # Select a set of rules as a base + rule_set: Dogma.RuleSet.All, - # Select a set of rules as a base - rule_set: Dogma.RuleSet.All, + # Pick paths not to lint + exclude: [ + ~r(\Alib/vendor/) + ], - # Pick paths not to lint - exclude: [ - ~r(\Alib/vendor/), - ], - - # Override an existing rule configuration - override: [ - %Rule.LineLength{ enabled: false }, - ] + # Override an existing rule configuration + override: [ + %Rule.LineLength{enabled: false} + ] diff --git a/config/prod.exs b/config/prod.exs index deb26ba0c..4b8df652a 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -23,13 +23,19 @@ config :eventos, Eventos.Mailer, server: "localhost", hostname: "localhost", port: 25, - username: nil, # or {:system, "SMTP_USERNAME"} - password: nil, # or {:system, "SMTP_PASSWORD"} - tls: :if_available, # can be `:always` or `:never` - allowed_tls_versions: [:"tlsv1", :"tlsv1.1", :"tlsv1.2"], # or {":system", ALLOWED_TLS_VERSIONS"} w/ comma seprated values (e.g. "tlsv1.1,tlsv1.2") - ssl: false, # can be `true` + # or {:system, "SMTP_USERNAME"} + username: nil, + # or {:system, "SMTP_PASSWORD"} + password: nil, + # can be `:always` or `:never` + tls: :if_available, + # or {":system", ALLOWED_TLS_VERSIONS"} w/ comma seprated values (e.g. "tlsv1.1,tlsv1.2") + allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"], + # can be `true` + ssl: false, retries: 1, - no_mx_lookups: false # can be `true` + # can be `true` + no_mx_lookups: false # Do not print debug messages in production config :logger, level: :info diff --git a/config/test.exs b/config/test.exs index 5ed375218..9d67a4ee8 100644 --- a/config/test.exs +++ b/config/test.exs @@ -8,9 +8,9 @@ config :eventos, EventosWeb.Endpoint, # Print only warnings and errors during test config :logger, - backends: [:console], - compile_time_purge_level: :debug, - level: :info + backends: [:console], + compile_time_purge_level: :debug, + level: :info # Configure your database config :eventos, Eventos.Repo, @@ -22,5 +22,4 @@ config :eventos, Eventos.Repo, pool: Ecto.Adapters.SQL.Sandbox, types: Eventos.PostgresTypes - config :eventos, Eventos.Mailer, - adapter: Bamboo.TestAdapter +config :eventos, Eventos.Mailer, adapter: Bamboo.TestAdapter diff --git a/lib/eventos/actors/actor.ex b/lib/eventos/actors/actor.ex index 411cafb3a..e98ded408 100644 --- a/lib/eventos/actors/actor.ex +++ b/lib/eventos/actors/actor.ex @@ -13,11 +13,16 @@ defmodule Eventos.Actors.Actor.TitleSlug do end defp build_unique_slug(slug, changeset) do - query = from a in Actor, - where: a.slug == ^slug + query = + from( + a in Actor, + where: a.slug == ^slug + ) case Repo.one(query) do - nil -> slug + nil -> + slug + _story -> slug |> Eventos.Slug.increment_slug() @@ -27,8 +32,14 @@ defmodule Eventos.Actors.Actor.TitleSlug do end import EctoEnum -defenum Eventos.Actors.ActorTypeEnum, :actor_type, [:Person, :Application, :Group, :Organization, :Service] +defenum(Eventos.Actors.ActorTypeEnum, :actor_type, [ + :Person, + :Application, + :Group, + :Organization, + :Service +]) defmodule Eventos.Actors.Actor do @moduledoc """ @@ -46,29 +57,29 @@ defmodule Eventos.Actors.Actor do import Logger -# @type t :: %Actor{description: String.t, id: integer(), inserted_at: DateTime.t, updated_at: DateTime.t, display_name: String.t, domain: String.t, keys: String.t, suspended: boolean(), url: String.t, username: String.t, organized_events: list(), groups: list(), group_request: list(), user: User.t, field: ActorTypeEnum.t} + # @type t :: %Actor{description: String.t, id: integer(), inserted_at: DateTime.t, updated_at: DateTime.t, display_name: String.t, domain: String.t, keys: String.t, suspended: boolean(), url: String.t, username: String.t, organized_events: list(), groups: list(), group_request: list(), user: User.t, field: ActorTypeEnum.t} schema "actors" do - field :url, :string - field :outbox_url, :string - field :inbox_url, :string - field :following_url, :string - field :followers_url, :string - field :shared_inbox_url, :string - field :type, Eventos.Actors.ActorTypeEnum, default: :Person - field :name, :string - field :domain, :string - field :summary, :string - field :preferred_username, :string - field :keys, :string - field :manually_approves_followers, :boolean, default: false - field :suspended, :boolean, default: false - field :avatar_url, :string - field :banner_url, :string - many_to_many :followers, Actor, join_through: Follower - has_many :organized_events, Event, [foreign_key: :organizer_actor_id] - many_to_many :memberships, Actor, join_through: Member - belongs_to :user, User + field(:url, :string) + field(:outbox_url, :string) + field(:inbox_url, :string) + field(:following_url, :string) + field(:followers_url, :string) + field(:shared_inbox_url, :string) + field(:type, Eventos.Actors.ActorTypeEnum, default: :Person) + field(:name, :string) + field(:domain, :string) + field(:summary, :string) + field(:preferred_username, :string) + field(:keys, :string) + field(:manually_approves_followers, :boolean, default: false) + field(:suspended, :boolean, default: false) + field(:avatar_url, :string) + field(:banner_url, :string) + many_to_many(:followers, Actor, join_through: Follower) + has_many(:organized_events, Event, foreign_key: :organizer_actor_id) + many_to_many(:memberships, Actor, join_through: Member) + belongs_to(:user, User) timestamps() end @@ -76,7 +87,25 @@ defmodule Eventos.Actors.Actor do @doc false def changeset(%Actor{} = actor, attrs) do actor - |> Ecto.Changeset.cast(attrs, [:url, :outbox_url, :inbox_url, :shared_inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :keys, :manually_approves_followers, :suspended, :avatar_url, :banner_url, :user_id]) + |> Ecto.Changeset.cast(attrs, [ + :url, + :outbox_url, + :inbox_url, + :shared_inbox_url, + :following_url, + :followers_url, + :type, + :name, + :domain, + :summary, + :preferred_username, + :keys, + :manually_approves_followers, + :suspended, + :avatar_url, + :banner_url, + :user_id + ]) |> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{attrs["prefered_username"]}") |> validate_required([:preferred_username, :keys, :suspended, :url]) |> unique_constraint(:prefered_username, name: :actors_preferred_username_domain_index) @@ -84,7 +113,19 @@ defmodule Eventos.Actors.Actor do def registration_changeset(%Actor{} = actor, attrs) do actor - |> Ecto.Changeset.cast(attrs, [:preferred_username, :domain, :name, :summary, :keys, :keys, :suspended, :url, :type, :avatar_url, :user_id]) + |> Ecto.Changeset.cast(attrs, [ + :preferred_username, + :domain, + :name, + :summary, + :keys, + :keys, + :suspended, + :url, + :type, + :avatar_url, + :user_id + ]) |> unique_constraint(:preferred_username, name: :actors_preferred_username_domain_index) |> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{attrs["prefered_username"]}") |> validate_required([:preferred_username, :keys, :suspended, :url, :type]) @@ -94,27 +135,70 @@ defmodule Eventos.Actors.Actor do def remote_actor_creation(params) do changes = %Actor{} - |> Ecto.Changeset.cast(params, [:url, :outbox_url, :inbox_url, :shared_inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :keys, :manually_approves_followers, :avatar_url, :banner_url]) - |> validate_required([:url, :outbox_url, :inbox_url, :type, :name, :domain, :preferred_username, :keys]) + |> Ecto.Changeset.cast(params, [ + :url, + :outbox_url, + :inbox_url, + :shared_inbox_url, + :following_url, + :followers_url, + :type, + :name, + :domain, + :summary, + :preferred_username, + :keys, + :manually_approves_followers, + :avatar_url, + :banner_url + ]) + |> validate_required([ + :url, + :outbox_url, + :inbox_url, + :type, + :name, + :domain, + :preferred_username, + :keys + ]) |> unique_constraint(:preferred_username, name: :actors_preferred_username_domain_index) |> validate_length(:summary, max: 5000) |> validate_length(:preferred_username, max: 100) |> put_change(:local, false) Logger.debug("Remote actor creation") - Logger.debug(inspect changes) + Logger.debug(inspect(changes)) changes end def group_creation(%Actor{} = actor, params) do actor - |> Ecto.Changeset.cast(params, [:url, :outbox_url, :inbox_url, :shared_inbox_url, :type, :name, :domain, :summary, :preferred_username, :avatar_url, :banner_url]) - |> put_change(:outbox_url, "#{EventosWeb.Endpoint.url()}/@#{params["prefered_username"]}/outbox") - |> put_change(:inbox_url, "#{EventosWeb.Endpoint.url()}/@#{params["prefered_username"]}/inbox") + |> Ecto.Changeset.cast(params, [ + :url, + :outbox_url, + :inbox_url, + :shared_inbox_url, + :type, + :name, + :domain, + :summary, + :preferred_username, + :avatar_url, + :banner_url + ]) + |> put_change( + :outbox_url, + "#{EventosWeb.Endpoint.url()}/@#{params["prefered_username"]}/outbox" + ) + |> put_change( + :inbox_url, + "#{EventosWeb.Endpoint.url()}/@#{params["prefered_username"]}/inbox" + ) |> put_change(:shared_inbox_url, "#{EventosWeb.Endpoint.url()}/inbox") |> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{params["prefered_username"]}") |> put_change(:domain, nil) - |> put_change(:type, "Group") + |> put_change(:type, :Group) |> validate_required([:url, :outbox_url, :inbox_url, :type, :name, :preferred_username]) |> validate_length(:summary, max: 5000) |> validate_length(:preferred_username, max: 100) @@ -128,24 +212,26 @@ defmodule Eventos.Actors.Actor do case ActivityPub.make_actor_from_url(url) do {:ok, user} -> user - _ -> {:error, "Could not fetch by AP id"} + + _ -> + {:error, "Could not fetch by AP id"} end end end - #@spec get_public_key_for_url(Actor.t) :: {:ok, String.t} + # @spec get_public_key_for_url(Actor.t) :: {:ok, String.t} def get_public_key_for_url(url) do with %Actor{} = actor <- get_or_fetch_by_url(url) do actor |> get_keys_for_actor - |> Eventos.Service.ActivityPub.Utils.pem_to_public_key + |> Eventos.Service.ActivityPub.Utils.pem_to_public_key() else _ -> :error end end @deprecated "Use get_keys_for_actor/1 instead" - #@spec get_public_key_for_actor(Actor.t) :: {:ok, String.t} + # @spec get_public_key_for_actor(Actor.t) :: {:ok, String.t} def get_public_key_for_actor(%Actor{} = actor) do {:ok, actor.keys} end @@ -158,24 +244,30 @@ defmodule Eventos.Actors.Actor do end @deprecated "Use get_keys_for_actor/1 instead" - #@spec get_private_key_for_actor(Actor.t) :: {:ok, String.t} + # @spec get_private_key_for_actor(Actor.t) :: {:ok, String.t} def get_private_key_for_actor(%Actor{} = actor) do actor.keys end def get_followers(%Actor{id: actor_id} = actor) do Repo.all( - from a in Actor, - join: f in Follower, on: a.id == f.actor_id, - where: f.target_actor_id == ^actor_id + from( + a in Actor, + join: f in Follower, + on: a.id == f.actor_id, + where: f.target_actor_id == ^actor_id + ) ) end def get_followings(%Actor{id: actor_id} = actor) do Repo.all( - from a in Actor, - join: f in Follower, on: a.id == f.target_actor_id, - where: f.actor_id == ^actor_id + from( + a in Actor, + join: f in Follower, + on: a.id == f.target_actor_id, + where: f.actor_id == ^actor_id + ) ) end end diff --git a/lib/eventos/actors/actors.ex b/lib/eventos/actors/actors.ex index ba90d284f..e8ed9ece7 100644 --- a/lib/eventos/actors/actors.ex +++ b/lib/eventos/actors/actors.ex @@ -130,16 +130,18 @@ defmodule Eventos.Actors do List the groups """ def list_groups do - Repo.all(from a in Actor, where: a.type == "Group") + Repo.all(from(a in Actor, where: a.type == "Group")) end def get_group_by_name(name) do - actor = case String.split(name, "@") do - [name] -> - Repo.get_by(Actor, preferred_username: name, type: :Group) - [name, domain] -> - Repo.get_by(Actor, preferred_username: name, domain: domain, type: :Group) - end + actor = + case String.split(name, "@") do + [name] -> + Repo.get_by(Actor, preferred_username: name, type: :Group) + + [name, domain] -> + Repo.get_by(Actor, preferred_username: name, domain: domain, type: :Group) + end end @doc """ @@ -185,22 +187,36 @@ defmodule Eventos.Actors do def insert_or_update_actor(data) do cs = Actor.remote_actor_creation(data) - Repo.insert(cs, on_conflict: [set: [keys: data.keys, avatar_url: data.avatar_url, banner_url: data.banner_url, name: data.name]], conflict_target: [:preferred_username, :domain]) + + Repo.insert( + cs, + on_conflict: [ + set: [ + keys: data.keys, + avatar_url: data.avatar_url, + banner_url: data.banner_url, + name: data.name + ] + ], + conflict_target: [:preferred_username, :domain] + ) end -# def increase_event_count(%Actor{} = actor) do -# event_count = (actor.info["event_count"] || 0) + 1 -# new_info = Map.put(actor.info, "note_count", note_count) -# -# cs = info_changeset(actor, %{info: new_info}) -# -# update_and_set_cache(cs) -# end + # def increase_event_count(%Actor{} = actor) do + # event_count = (actor.info["event_count"] || 0) + 1 + # new_info = Map.put(actor.info, "note_count", note_count) + # + # cs = info_changeset(actor, %{info: new_info}) + # + # update_and_set_cache(cs) + # end def count_users() do Repo.one( - from u in User, - select: count(u.id) + from( + u in User, + select: count(u.id) + ) ) end @@ -230,28 +246,35 @@ defmodule Eventos.Actors do end def get_actor_by_name(name) do - actor = case String.split(name, "@") do - [name] -> - Repo.get_by(Actor, preferred_username: name) - [name, domain] -> - Repo.get_by(Actor, preferred_username: name, domain: domain) - end + actor = + case String.split(name, "@") do + [name] -> + Repo.get_by(Actor, preferred_username: name) + + [name, domain] -> + Repo.get_by(Actor, preferred_username: name, domain: domain) + end end def get_local_actor_by_name(name) do - Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) + Repo.one(from(a in Actor, where: a.preferred_username == ^name and is_nil(a.domain))) end def get_local_actor_by_name_with_everything(name) do - actor = Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) + actor = Repo.one(from(a in Actor, where: a.preferred_username == ^name and is_nil(a.domain))) Repo.preload(actor, :organized_events) end def get_actor_by_name_with_everything(name) do - actor = case String.split(name, "@") do - [name] -> Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) - [name, domain] -> Repo.one from a in Actor, where: a.preferred_username == ^name and a.domain == ^domain - end + actor = + case String.split(name, "@") do + [name] -> + Repo.one(from(a in Actor, where: a.preferred_username == ^name and is_nil(a.domain))) + + [name, domain] -> + Repo.one(from(a in Actor, where: a.preferred_username == ^name and a.domain == ^domain)) + end + Repo.preload(actor, :organized_events) end @@ -265,7 +288,8 @@ defmodule Eventos.Actors do {:ok, actor} -> actor - _ -> {:error, "Could not fetch by AP id"} + _ -> + {:error, "Could not fetch by AP id"} end end end @@ -274,7 +298,16 @@ defmodule Eventos.Actors do Find local users by it's username """ def find_local_by_username(username) do - actors = Repo.all from a in Actor, where: (ilike(a.preferred_username, ^like_sanitize(username)) or ilike(a.name, ^like_sanitize(username))) and is_nil(a.domain) + actors = + Repo.all( + from( + a in Actor, + where: + (ilike(a.preferred_username, ^like_sanitize(username)) or + ilike(a.name, ^like_sanitize(username))) and is_nil(a.domain) + ) + ) + Repo.preload(actors, :organized_events) end @@ -282,7 +315,14 @@ defmodule Eventos.Actors do Find actors by their name or displayed name """ def find_actors_by_username(username) do - Repo.all from a in Actor, where: ilike(a.preferred_username, ^like_sanitize(username)) or ilike(a.name, ^like_sanitize(username)) + Repo.all( + from( + a in Actor, + where: + ilike(a.preferred_username, ^like_sanitize(username)) or + ilike(a.name, ^like_sanitize(username)) + ) + ) end @doc """ @@ -294,17 +334,26 @@ defmodule Eventos.Actors do @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ def search(name) do - case find_actors_by_username(name) do # find already saved accounts + # find already saved accounts + case find_actors_by_username(name) do [] -> - with true <- Regex.match?(@email_regex, name), # no accounts found, let's test if it's an username@domain.tld - {:ok, actor} <- ActivityPub.find_or_make_actor_from_nickname(name) do # creating the actor in that case + # no accounts found, let's test if it's an username@domain.tld + with true <- Regex.match?(@email_regex, name), + # creating the actor in that case + {:ok, actor} <- ActivityPub.find_or_make_actor_from_nickname(name) do {:ok, [actor]} else - false -> {:ok, []} - {:error, err} -> {:error, err} # error fingering the actor + false -> + {:ok, []} + + # error fingering the actor + {:error, err} -> + {:error, err} end - actors = [_|_] -> - {:ok, actors} # actors already saved found ! + + actors = [_ | _] -> + # actors already saved found ! + {:ok, actors} end end @@ -315,6 +364,7 @@ defmodule Eventos.Actors do case Repo.preload(Repo.get_by(User, email: email), :actors) do nil -> {:error, nil} + user -> {:ok, user} end @@ -329,6 +379,7 @@ defmodule Eventos.Actors do true -> # Yes, create and return the token EventosWeb.Guardian.encode_and_sign(user) + _ -> # No, return an error {:error, :unauthorized} @@ -346,25 +397,29 @@ defmodule Eventos.Actors do import Exgravatar avatar_url = gravatar_url(email, default: "404") - avatar = case HTTPoison.get(avatar_url) do - {:ok, %HTTPoison.Response{status_code: 200}} -> - avatar_url - _ -> - nil - end - actor = Eventos.Actors.Actor.registration_changeset(%Eventos.Actors.Actor{}, %{ - preferred_username: username, - domain: nil, - keys: pem, - avatar_url: avatar, - }) + avatar = + case HTTPoison.get(avatar_url) do + {:ok, %HTTPoison.Response{status_code: 200}} -> + avatar_url - user = Eventos.Actors.User.registration_changeset(%Eventos.Actors.User{}, %{ - email: email, - password: password - }) + _ -> + nil + end + actor = + Eventos.Actors.Actor.registration_changeset(%Eventos.Actors.Actor{}, %{ + preferred_username: username, + domain: nil, + keys: pem, + avatar_url: avatar + }) + + user = + Eventos.Actors.User.registration_changeset(%Eventos.Actors.User{}, %{ + email: email, + password: password + }) actor_with_user = Ecto.Changeset.put_assoc(actor, :user, user) @@ -372,8 +427,8 @@ defmodule Eventos.Actors do Eventos.Repo.insert!(actor_with_user) find_by_email(email) rescue - e in Ecto.InvalidChangesetError -> - {:error, e.changeset} + e in Ecto.InvalidChangesetError -> + {:error, e.changeset} end end @@ -382,13 +437,14 @@ defmodule Eventos.Actors do entry = :public_key.pem_entry_encode(:RSAPrivateKey, key) pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing() - actor = Eventos.Actors.Actor.registration_changeset(%Eventos.Actors.Actor{}, %{ - preferred_username: name, - domain: nil, - keys: pem, - summary: summary, - type: :Service - }) + actor = + Eventos.Actors.Actor.registration_changeset(%Eventos.Actors.Actor{}, %{ + preferred_username: name, + domain: nil, + keys: pem, + summary: summary, + type: :Service + }) try do Eventos.Repo.insert!(actor) @@ -398,7 +454,6 @@ defmodule Eventos.Actors do end end - @doc """ Creates a user. @@ -563,21 +618,24 @@ defmodule Eventos.Actors do def groups_for_actor(%Actor{id: id} = _actor) do Repo.all( - from m in Member, - where: m.actor_id == ^id, - preload: [:parent] + from( + m in Member, + where: m.actor_id == ^id, + preload: [:parent] + ) ) end def members_for_group(%Actor{type: :Group, id: id} = _group) do Repo.all( - from m in Member, - where: m.parent_id == ^id, - preload: [:parent, :actor] + from( + m in Member, + where: m.parent_id == ^id, + preload: [:parent, :actor] + ) ) end - alias Eventos.Actors.Bot @doc """ @@ -609,7 +667,7 @@ defmodule Eventos.Actors do """ def get_bot!(id), do: Repo.get!(Bot, id) - @spec get_bot_by_actor(Actor.t) :: Bot.t + @spec get_bot_by_actor(Actor.t()) :: Bot.t() def get_bot_by_actor(%Actor{} = actor) do Repo.get_by!(Bot, actor_id: actor.id) end diff --git a/lib/eventos/actors/bot.ex b/lib/eventos/actors/bot.ex index 702b47942..a3307e48b 100644 --- a/lib/eventos/actors/bot.ex +++ b/lib/eventos/actors/bot.ex @@ -6,12 +6,11 @@ defmodule Eventos.Actors.Bot do import Ecto.Changeset alias Eventos.Actors.{Actor, User, Bot} - schema "bots" do - field :source, :string - field :type, :string, default: :ics - belongs_to :actor, Actor - belongs_to :user, User + field(:source, :string) + field(:type, :string, default: :ics) + belongs_to(:actor, Actor) + belongs_to(:user, User) timestamps() end diff --git a/lib/eventos/actors/follower.ex b/lib/eventos/actors/follower.ex index 5c63098ca..c6386679b 100644 --- a/lib/eventos/actors/follower.ex +++ b/lib/eventos/actors/follower.ex @@ -7,12 +7,11 @@ defmodule Eventos.Actors.Follower do alias Eventos.Actors.Follower alias Eventos.Actors.Actor - schema "followers" do - field :approved, :boolean, default: false - field :score, :integer, default: 1000 - belongs_to :target_actor, Actor - belongs_to :actor, Actor + field(:approved, :boolean, default: false) + field(:score, :integer, default: 1000) + belongs_to(:target_actor, Actor) + belongs_to(:actor, Actor) timestamps() end diff --git a/lib/eventos/actors/member.ex b/lib/eventos/actors/member.ex index 7cd020105..8e86bd755 100644 --- a/lib/eventos/actors/member.ex +++ b/lib/eventos/actors/member.ex @@ -9,10 +9,11 @@ defmodule Eventos.Actors.Member do @primary_key false schema "members" do - field :approved, :boolean, default: true - field :role, :integer, default: 0 # 0 : Member, 1 : Moderator, 2 : Admin - belongs_to :parent, Actor - belongs_to :actor, Actor + field(:approved, :boolean, default: true) + # 0 : Member, 1 : Moderator, 2 : Admin + field(:role, :integer, default: 0) + belongs_to(:parent, Actor) + belongs_to(:actor, Actor) timestamps() end diff --git a/lib/eventos/actors/service/activation.ex b/lib/eventos/actors/service/activation.ex index 5584f167d..d51c80a93 100644 --- a/lib/eventos/actors/service/activation.ex +++ b/lib/eventos/actors/service/activation.ex @@ -9,7 +9,12 @@ defmodule Eventos.Actors.Service.Activation do @doc false def check_confirmation_token(token) when is_binary(token) do with %User{} = user <- Repo.get_by(User, confirmation_token: token), - {:ok, %User{} = user} <- Actors.update_user(user, %{"confirmed_at" => DateTime.utc_now(), "confirmation_sent_at" => nil, "confirmation_token" => nil}) do + {:ok, %User{} = user} <- + Actors.update_user(user, %{ + "confirmed_at" => DateTime.utc_now(), + "confirmation_sent_at" => nil, + "confirmation_token" => nil + }) do {:ok, Repo.preload(user, :actors)} else _err -> diff --git a/lib/eventos/actors/service/reset_password.ex b/lib/eventos/actors/service/reset_password.ex index 80e79d7cb..65b9ad282 100644 --- a/lib/eventos/actors/service/reset_password.ex +++ b/lib/eventos/actors/service/reset_password.ex @@ -9,10 +9,16 @@ defmodule Eventos.Actors.Service.ResetPassword do @doc """ Check that the provided token is correct and update provided password """ - @spec check_reset_password_token(String.t, String.t) :: tuple + @spec check_reset_password_token(String.t(), String.t()) :: tuple def check_reset_password_token(password, token) do with %User{} = user <- Repo.get_by(User, reset_password_token: token) do - Repo.update(User.password_reset_changeset(user, %{"password" => password, "reset_password_sent_at" => nil, "reset_password_token" => nil})) + Repo.update( + User.password_reset_changeset(user, %{ + "password" => password, + "reset_password_sent_at" => nil, + "reset_password_token" => nil + }) + ) else _err -> {:error, :invalid_token} @@ -22,38 +28,48 @@ defmodule Eventos.Actors.Service.ResetPassword do @doc """ Send the email reset password, if it's not too soon since the last send """ - @spec send_password_reset_email(User.t, String.t) :: tuple + @spec send_password_reset_email(User.t(), String.t()) :: tuple def send_password_reset_email(%User{} = user, locale \\ "en") do with :ok <- we_can_send_email(user), - {:ok, %User{} = user_updated} <- Repo.update(User.send_password_reset_changeset(user, %{"reset_password_token" => random_string(30), "reset_password_sent_at" => DateTime.utc_now()})) do - mail = user_updated - |> UserEmail.reset_password_email(locale) - |> Mailer.deliver_later() + {:ok, %User{} = user_updated} <- + Repo.update( + User.send_password_reset_changeset(user, %{ + "reset_password_token" => random_string(30), + "reset_password_sent_at" => DateTime.utc_now() + }) + ) do + mail = + user_updated + |> UserEmail.reset_password_email(locale) + |> Mailer.deliver_later() + {:ok, mail} else {:error, reason} -> {:error, reason} end end - @spec random_string(integer) :: String.t + @spec random_string(integer) :: String.t() defp random_string(length) do length |> :crypto.strong_rand_bytes() - |> Base.url_encode64 + |> Base.url_encode64() end - @spec we_can_send_email(User.t) :: boolean + @spec we_can_send_email(User.t()) :: boolean defp we_can_send_email(%User{} = user) do case user.reset_password_sent_at do nil -> :ok + _ -> case Timex.before?(Timex.shift(user.reset_password_sent_at, hours: 1), DateTime.utc_now()) do true -> :ok + false -> {:error, :email_too_soon} end - end + end end end diff --git a/lib/eventos/actors/user.ex b/lib/eventos/actors/user.ex index b5869be5f..815c98755 100644 --- a/lib/eventos/actors/user.ex +++ b/lib/eventos/actors/user.ex @@ -7,16 +7,16 @@ defmodule Eventos.Actors.User do alias Eventos.Actors.{Actor, User} schema "users" do - field :email, :string - field :password_hash, :string - field :password, :string, virtual: true - field :role, :integer, default: 0 - has_many :actors, Actor - field :confirmed_at, :utc_datetime - field :confirmation_sent_at, :utc_datetime - field :confirmation_token, :string - field :reset_password_sent_at, :utc_datetime - field :reset_password_token, :string + field(:email, :string) + field(:password_hash, :string) + field(:password, :string, virtual: true) + field(:role, :integer, default: 0) + has_many(:actors, Actor) + field(:confirmed_at, :utc_datetime) + field(:confirmation_sent_at, :utc_datetime) + field(:confirmation_token, :string) + field(:reset_password_sent_at, :utc_datetime) + field(:reset_password_token, :string) timestamps() end @@ -24,11 +24,25 @@ defmodule Eventos.Actors.User do @doc false def changeset(%User{} = user, attrs) do user - |> cast(attrs, [:email, :role, :password_hash, :confirmed_at, :confirmation_sent_at, :confirmation_token, :reset_password_sent_at, :reset_password_token]) + |> cast(attrs, [ + :email, + :role, + :password_hash, + :confirmed_at, + :confirmation_sent_at, + :confirmation_token, + :reset_password_sent_at, + :reset_password_token + ]) |> validate_required([:email]) - |> unique_constraint(:email, [message: "registration.error.email_already_used"]) + |> unique_constraint(:email, message: "registration.error.email_already_used") |> validate_format(:email, ~r/@/) - |> validate_length(:password, min: 6, max: 100, message: "registration.error.password_too_short") + |> validate_length( + :password, + min: 6, + max: 100, + message: "registration.error.password_too_short" + ) end def registration_changeset(struct, params) do @@ -36,10 +50,18 @@ defmodule Eventos.Actors.User do |> changeset(params) |> cast(params, ~w(password)a, []) |> validate_required([:email, :password]) - |> validate_length(:password, min: 6, max: 100, message: "registration.error.password_too_short") + |> validate_length( + :password, + min: 6, + max: 100, + message: "registration.error.password_too_short" + ) |> hash_password() |> save_confirmation_token() - |> unique_constraint(:confirmation_token, [message: "regisration.error.confirmation_token_already_in_use"]) + |> unique_constraint( + :confirmation_token, + message: "regisration.error.confirmation_token_already_in_use" + ) end def send_password_reset_changeset(%User{} = user, attrs) do @@ -50,16 +72,21 @@ defmodule Eventos.Actors.User do def password_reset_changeset(%User{} = user, attrs) do user |> cast(attrs, [:password, :reset_password_token, :reset_password_sent_at]) - |> validate_length(:password, min: 6, max: 100, message: "registration.error.password_too_short") + |> validate_length( + :password, + min: 6, + max: 100, + message: "registration.error.password_too_short" + ) |> hash_password() end defp save_confirmation_token(changeset) do case changeset do - %Ecto.Changeset{valid?: true, - changes: %{email: _email}} -> - changeset = put_change(changeset, :confirmation_token, random_string(30)) - put_change(changeset, :confirmation_sent_at, DateTime.utc_now()) + %Ecto.Changeset{valid?: true, changes: %{email: _email}} -> + changeset = put_change(changeset, :confirmation_token, random_string(30)) + put_change(changeset, :confirmation_sent_at, DateTime.utc_now()) + _ -> changeset end @@ -68,7 +95,7 @@ defmodule Eventos.Actors.User do defp random_string(length) do length |> :crypto.strong_rand_bytes() - |> Base.url_encode64 + |> Base.url_encode64() end @doc """ @@ -76,11 +103,13 @@ defmodule Eventos.Actors.User do """ defp hash_password(changeset) do case changeset do - %Ecto.Changeset{valid?: true, - changes: %{password: password}} -> - put_change(changeset, + %Ecto.Changeset{valid?: true, changes: %{password: password}} -> + put_change( + changeset, :password_hash, - Comeonin.Argon2.hashpwsalt(password)) + Comeonin.Argon2.hashpwsalt(password) + ) + _ -> changeset end diff --git a/lib/eventos/addresses/address.ex b/lib/eventos/addresses/address.ex index 97737722f..c32c403b4 100644 --- a/lib/eventos/addresses/address.ex +++ b/lib/eventos/addresses/address.ex @@ -8,16 +8,16 @@ defmodule Eventos.Addresses.Address do alias Eventos.Groups.Group schema "addresses" do - field :addressCountry, :string - field :addressLocality, :string - field :addressRegion, :string - field :description, :string - field :floor, :string - field :geom, Geo.Geometry - field :postalCode, :string - field :streetAddress, :string - has_one :event, Event - has_one :group, Group + field(:addressCountry, :string) + field(:addressLocality, :string) + field(:addressRegion, :string) + field(:description, :string) + field(:floor, :string) + field(:geom, Geo.Geometry) + field(:postalCode, :string) + field(:streetAddress, :string) + has_one(:event, Event) + has_one(:group, Group) timestamps() end @@ -25,6 +25,15 @@ defmodule Eventos.Addresses.Address do @doc false def changeset(%Address{} = address, attrs) do address - |> cast(attrs, [:description, :floor, :geom, :addressCountry, :addressLocality, :addressRegion, :postalCode, :streetAddress]) + |> cast(attrs, [ + :description, + :floor, + :geom, + :addressCountry, + :addressLocality, + :addressRegion, + :postalCode, + :streetAddress + ]) end end diff --git a/lib/eventos/addresses/addresses.ex b/lib/eventos/addresses/addresses.ex index d80d60cb1..f56b9625b 100644 --- a/lib/eventos/addresses/addresses.ex +++ b/lib/eventos/addresses/addresses.ex @@ -116,7 +116,7 @@ defmodule Eventos.Addresses do String.to_existing_atom(type_input) rescue e in ArgumentError -> - Logger.error("#{type_input} is not an existing atom : #{inspect e}") + Logger.error("#{type_input} is not an existing atom : #{inspect(e)}") nil end else diff --git a/lib/eventos/application.ex b/lib/eventos/application.ex index e17b7a559..0fb3bf10e 100644 --- a/lib/eventos/application.ex +++ b/lib/eventos/application.ex @@ -18,7 +18,7 @@ defmodule Eventos.Application do # Start your own worker by calling: Eventos.Worker.start_link(arg1, arg2, arg3) # worker(Eventos.Worker, [arg1, arg2, arg3]), worker(Guardian.DB.Token.SweeperServer, []), - worker(Eventos.Service.Federator, []), + worker(Eventos.Service.Federator, []) ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/lib/eventos/email/user.ex b/lib/eventos/email/user.ex index e112e8713..9de7a9ecc 100644 --- a/lib/eventos/email/user.ex +++ b/lib/eventos/email/user.ex @@ -12,9 +12,12 @@ defmodule Eventos.Email.User do def confirmation_email(%User{} = user, locale \\ "en") do Gettext.put_locale(locale) instance_url = get_config(:instance) + base_email() |> to(user.email) - |> subject(gettext "Peakweaver: Confirmation instructions for %{instance}", instance: instance_url) + |> subject( + gettext("Peakweaver: Confirmation instructions for %{instance}", instance: instance_url) + ) |> put_header("Reply-To", get_config(:reply_to)) |> assign(:token, user.confirmation_token) |> assign(:instance, instance_url) @@ -24,9 +27,15 @@ defmodule Eventos.Email.User do def reset_password_email(%User{} = user, locale \\ "en") do Gettext.put_locale(locale) instance_url = get_config(:instance) + base_email() |> to(user.email) - |> subject(gettext "Peakweaver: Reset your password on %{instance} instructions", instance: instance_url) + |> subject( + gettext( + "Peakweaver: Reset your password on %{instance} instructions", + instance: instance_url + ) + ) |> put_header("Reply-To", get_config(:reply_to)) |> assign(:token, user.reset_password_token) |> assign(:instance, instance_url) diff --git a/lib/eventos/events/category.ex b/lib/eventos/events/category.ex index 6b93f1879..334eafd9b 100644 --- a/lib/eventos/events/category.ex +++ b/lib/eventos/events/category.ex @@ -6,11 +6,10 @@ defmodule Eventos.Events.Category do import Ecto.Changeset alias Eventos.Events.Category - schema "categories" do - field :description, :string - field :picture, :string - field :title, :string, null: false + field(:description, :string) + field(:picture, :string) + field(:title, :string, null: false) timestamps() end diff --git a/lib/eventos/events/comment.ex b/lib/eventos/events/comment.ex index 10aae2ab1..1ca5226b6 100644 --- a/lib/eventos/events/comment.ex +++ b/lib/eventos/events/comment.ex @@ -11,15 +11,15 @@ defmodule Eventos.Events.Comment do alias Eventos.Actors.Comment schema "comments" do - field :text, :string - field :url, :string - field :local, :boolean, default: true - field :uuid, Ecto.UUID - belongs_to :actor, Actor, [foreign_key: :actor_id] - belongs_to :attributed_to, Actor, [foreign_key: :attributed_to_id] - belongs_to :event, Event, [foreign_key: :event_id] - belongs_to :in_reply_to_comment, Comment, [foreign_key: :in_reply_to_comment_id] - belongs_to :origin_comment, Comment, [foreign_key: :origin_comment_id] + field(:text, :string) + field(:url, :string) + field(:local, :boolean, default: true) + field(:uuid, Ecto.UUID) + belongs_to(:actor, Actor, foreign_key: :actor_id) + belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id) + belongs_to(:event, Event, foreign_key: :event_id) + belongs_to(:in_reply_to_comment, Comment, foreign_key: :in_reply_to_comment_id) + belongs_to(:origin_comment, Comment, foreign_key: :origin_comment_id) timestamps() end @@ -27,6 +27,7 @@ defmodule Eventos.Events.Comment do @doc false def changeset(comment, attrs) do uuid = Ecto.UUID.generate() + comment |> cast(attrs, [:url, :text, :actor_id, :event_id, :in_reply_to_comment_id, :attributed_to_id]) |> validate_required([:text, :actor_id]) diff --git a/lib/eventos/events/event.ex b/lib/eventos/events/event.ex index 16c842db6..512a58160 100644 --- a/lib/eventos/events/event.ex +++ b/lib/eventos/events/event.ex @@ -1,5 +1,5 @@ import EctoEnum -defenum AddressTypeEnum, :address_type, [:physical, :url, :phone, :other] +defenum(AddressTypeEnum, :address_type, [:physical, :url, :phone, :other]) defmodule Eventos.Events.Event do @moduledoc """ @@ -12,30 +12,30 @@ defmodule Eventos.Events.Event do alias Eventos.Addresses.Address schema "events" do - field :url, :string - field :local, :boolean, default: true - field :begins_on, Timex.Ecto.DateTimeWithTimezone - field :description, :string - field :ends_on, Timex.Ecto.DateTimeWithTimezone - field :title, :string - field :state, :integer, default: 0 - field :status, :integer, default: 0 - field :public, :boolean, default: true - field :thumbnail, :string - field :large_image, :string - field :publish_at, Timex.Ecto.DateTimeWithTimezone - field :uuid, Ecto.UUID, default: Ecto.UUID.generate() - field :address_type, AddressTypeEnum, default: :physical - field :online_address, :string - field :phone, :string - belongs_to :organizer_actor, Actor, [foreign_key: :organizer_actor_id] - belongs_to :attributed_to, Actor, [foreign_key: :attributed_to_id] - many_to_many :tags, Tag, join_through: "events_tags" - belongs_to :category, Category - many_to_many :participants, Actor, join_through: Participant - has_many :tracks, Track - has_many :sessions, Session - belongs_to :physical_address, Address + field(:url, :string) + field(:local, :boolean, default: true) + field(:begins_on, Timex.Ecto.DateTimeWithTimezone) + field(:description, :string) + field(:ends_on, Timex.Ecto.DateTimeWithTimezone) + field(:title, :string) + field(:state, :integer, default: 0) + field(:status, :integer, default: 0) + field(:public, :boolean, default: true) + field(:thumbnail, :string) + field(:large_image, :string) + field(:publish_at, Timex.Ecto.DateTimeWithTimezone) + field(:uuid, Ecto.UUID, default: Ecto.UUID.generate()) + field(:address_type, AddressTypeEnum, default: :physical) + field(:online_address, :string) + field(:phone, :string) + belongs_to(:organizer_actor, Actor, foreign_key: :organizer_actor_id) + belongs_to(:attributed_to, Actor, foreign_key: :attributed_to_id) + many_to_many(:tags, Tag, join_through: "events_tags") + belongs_to(:category, Category) + many_to_many(:participants, Actor, join_through: Participant) + has_many(:tracks, Track) + has_many(:sessions, Session) + belongs_to(:physical_address, Address) timestamps(type: :utc_datetime) end @@ -45,11 +45,13 @@ defmodule Eventos.Events.Event do uuid = Ecto.UUID.generate() # TODO : check what's the use here. Tests ? - actor_url = if Map.has_key?(attrs, :organizer_actor) do - attrs.organizer_actor.preferred_username - else - "" - end + actor_url = + if Map.has_key?(attrs, :organizer_actor) do + attrs.organizer_actor.preferred_username + else + "" + end + event |> Ecto.Changeset.cast(attrs, [ :title, @@ -67,12 +69,21 @@ defmodule Eventos.Events.Event do :publish_at, :address_type, :online_address, - :phone, - ]) + :phone + ]) |> cast_assoc(:tags) |> cast_assoc(:physical_address) |> put_change(:uuid, uuid) |> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{actor_url}/#{uuid}") - |> validate_required([:title, :begins_on, :ends_on, :organizer_actor_id, :category_id, :url, :uuid, :address_type]) + |> validate_required([ + :title, + :begins_on, + :ends_on, + :organizer_actor_id, + :category_id, + :url, + :uuid, + :address_type + ]) end end diff --git a/lib/eventos/events/events.ex b/lib/eventos/events/events.ex index c3010184d..c6fc748ad 100644 --- a/lib/eventos/events/events.ex +++ b/lib/eventos/events/events.ex @@ -28,43 +28,66 @@ defmodule Eventos.Events do def get_events_for_actor(%Actor{id: actor_id} = _actor, page \\ 1, limit \\ 10) do start = (page - 1) * limit - query = from e in Event, - where: e.organizer_actor_id == ^actor_id, - limit: ^limit, - order_by: [desc: :id], - offset: ^start, - preload: [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :physical_address] + query = + from( + e in Event, + where: e.organizer_actor_id == ^actor_id, + limit: ^limit, + order_by: [desc: :id], + offset: ^start, + preload: [ + :organizer_actor, + :category, + :sessions, + :tracks, + :tags, + :participants, + :physical_address + ] + ) + events = Repo.all(query) - count_events = Repo.one(from e in Event, select: count(e.id), where: e.organizer_actor_id == ^actor_id) + + count_events = + Repo.one(from(e in Event, select: count(e.id), where: e.organizer_actor_id == ^actor_id)) + {:ok, events, count_events} end def count_local_events do Repo.one( - from e in Event, - select: count(e.id), - where: e.local == ^true + from( + e in Event, + select: count(e.id), + where: e.local == ^true + ) ) end def count_local_comments do Repo.one( - from c in Comment, - select: count(c.id), - where: c.local == ^true + from( + c in Comment, + select: count(c.id), + where: c.local == ^true + ) ) end import Geo.PostGIS - def find_close_events(lon, lat, radius \\ 50_000) do # 50 000 meters -> 50 kms + # 50 000 meters -> 50 kms + def find_close_events(lon, lat, radius \\ 50_000) do ip_point = Geo.WKT.decode("SRID=4326;POINT(#{lon} #{lat})") + Repo.all( - from e in Event, - join: a in Address, - on: a.id == e.physical_address_id, - where: st_dwithin_in_meters(^ip_point, a.geom, ^radius), - preload: :organizer_actor + from( + e in Event, + join: a in Address, + on: a.id == e.physical_address_id, + where: st_dwithin_in_meters(^ip_point, a.geom, ^radius), + preload: :organizer_actor + ) ) end @@ -103,7 +126,16 @@ defmodule Eventos.Events do """ def get_event_full!(id) do event = Repo.get!(Event, id) - Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :physical_address]) + + Repo.preload(event, [ + :organizer_actor, + :category, + :sessions, + :tracks, + :tags, + :participants, + :physical_address + ]) end @doc """ @@ -111,7 +143,16 @@ defmodule Eventos.Events do """ def get_event_full_by_url!(url) do event = Repo.get_by(Event, url: url) - Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :physical_address]) + + Repo.preload(event, [ + :organizer_actor, + :category, + :sessions, + :tracks, + :tags, + :participants, + :physical_address + ]) end @doc """ @@ -119,14 +160,23 @@ defmodule Eventos.Events do """ def get_event_full_by_uuid(uuid) do event = Repo.get_by(Event, uuid: uuid) - Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :physical_address]) + + Repo.preload(event, [ + :organizer_actor, + :category, + :sessions, + :tracks, + :tags, + :participants, + :physical_address + ]) end @doc """ Find events by name """ def find_events_by_name(name) do - events = Repo.all from a in Event, where: ilike(a.title, ^like_sanitize(name)) + events = Repo.all(from(a in Event, where: ilike(a.title, ^like_sanitize(name)))) Repo.preload(events, [:organizer_actor]) end @@ -154,7 +204,6 @@ defmodule Eventos.Events do {:ok, %Event{} = event} -> {:ok, Repo.preload(event, [:organizer_actor])} err -> err end - end @doc """ @@ -235,7 +284,7 @@ defmodule Eventos.Events do """ def get_category!(id), do: Repo.get!(Category, id) - @spec get_category_by_title(String.t) :: tuple() + @spec get_category_by_title(String.t()) :: tuple() def get_category_by_title(title) when is_binary(title) do Repo.get_by(Category, title: title) end @@ -431,7 +480,7 @@ defmodule Eventos.Events do """ def get_participant!(event_id, actor_id) do - Repo.get_by!(Participant, [event_id: event_id, actor_id: actor_id]) + Repo.get_by!(Participant, event_id: event_id, actor_id: actor_id) end @doc """ @@ -500,7 +549,7 @@ defmodule Eventos.Events do end def list_requests_for_actor(%Actor{} = actor) do - Repo.all(from p in Participant, where: p.actor_id == ^actor.id and p.approved == false) + Repo.all(from(p in Participant, where: p.actor_id == ^actor.id and p.approved == false)) end alias Eventos.Events.Session @@ -523,10 +572,12 @@ defmodule Eventos.Events do """ def list_sessions_for_event(event_uuid) do Repo.all( - from s in Session, - join: e in Event, - on: s.event_id == e.id, - where: e.uuid == ^event_uuid + from( + s in Session, + join: e in Event, + on: s.event_id == e.id, + where: e.uuid == ^event_uuid + ) ) end @@ -534,7 +585,7 @@ defmodule Eventos.Events do Returns the list of sessions for a track """ def list_sessions_for_track(track_id) do - Repo.all(from s in Session, where: s.track_id == ^track_id) + Repo.all(from(s in Session, where: s.track_id == ^track_id)) end @doc """ diff --git a/lib/eventos/events/participant.ex b/lib/eventos/events/participant.ex index cd1045aa9..116c604c9 100644 --- a/lib/eventos/events/participant.ex +++ b/lib/eventos/events/participant.ex @@ -9,9 +9,10 @@ defmodule Eventos.Events.Participant do @primary_key false schema "participants" do - field :role, :integer, default: 0 # 0 : not_approved, 1 : participant, 2 : moderator, 3 : administrator, 4 : creator - belongs_to :event, Event, primary_key: true - belongs_to :actor, Actor, primary_key: true + # 0 : not_approved, 1 : participant, 2 : moderator, 3 : administrator, 4 : creator + field(:role, :integer, default: 0) + belongs_to(:event, Event, primary_key: true) + belongs_to(:actor, Actor, primary_key: true) timestamps() end diff --git a/lib/eventos/events/session.ex b/lib/eventos/events/session.ex index c8853409e..34901e466 100644 --- a/lib/eventos/events/session.ex +++ b/lib/eventos/events/session.ex @@ -6,20 +6,19 @@ defmodule Eventos.Events.Session do import Ecto.Changeset alias Eventos.Events.{Session, Event, Track} - schema "sessions" do - field :audios_urls, :string - field :language, :string - field :long_abstract, :string - field :short_abstract, :string - field :slides_url, :string - field :subtitle, :string - field :title, :string - field :videos_urls, :string - field :begins_on, Timex.Ecto.DateTimeWithTimezone - field :ends_on, Timex.Ecto.DateTimeWithTimezone - belongs_to :event, Event - belongs_to :track, Track + field(:audios_urls, :string) + field(:language, :string) + field(:long_abstract, :string) + field(:short_abstract, :string) + field(:slides_url, :string) + field(:subtitle, :string) + field(:title, :string) + field(:videos_urls, :string) + field(:begins_on, Timex.Ecto.DateTimeWithTimezone) + field(:ends_on, Timex.Ecto.DateTimeWithTimezone) + belongs_to(:event, Event) + belongs_to(:track, Track) timestamps() end @@ -27,7 +26,27 @@ defmodule Eventos.Events.Session do @doc false def changeset(%Session{} = session, attrs) do session - |> cast(attrs, [:title, :subtitle, :short_abstract, :long_abstract, :language, :slides_url, :videos_urls, :audios_urls, :event_id, :track_id]) - |> validate_required([:title, :subtitle, :short_abstract, :long_abstract, :language, :slides_url, :videos_urls, :audios_urls]) + |> cast(attrs, [ + :title, + :subtitle, + :short_abstract, + :long_abstract, + :language, + :slides_url, + :videos_urls, + :audios_urls, + :event_id, + :track_id + ]) + |> validate_required([ + :title, + :subtitle, + :short_abstract, + :long_abstract, + :language, + :slides_url, + :videos_urls, + :audios_urls + ]) end end diff --git a/lib/eventos/events/tag.ex b/lib/eventos/events/tag.ex index 8f5410138..08137b212 100644 --- a/lib/eventos/events/tag.ex +++ b/lib/eventos/events/tag.ex @@ -13,11 +13,16 @@ defmodule Eventos.Events.Tag.TitleSlug do end defp build_unique_slug(slug, changeset) do - query = from t in Tag, - where: t.slug == ^slug + query = + from( + t in Tag, + where: t.slug == ^slug + ) case Repo.one(query) do - nil -> slug + nil -> + slug + _story -> slug |> Eventos.Slug.increment_slug() @@ -36,8 +41,8 @@ defmodule Eventos.Events.Tag do alias Eventos.Events.Tag.TitleSlug schema "tags" do - field :title, :string - field :slug, TitleSlug.Type + field(:title, :string) + field(:slug, TitleSlug.Type) timestamps() end diff --git a/lib/eventos/events/track.ex b/lib/eventos/events/track.ex index 9beaf94d6..62efd945c 100644 --- a/lib/eventos/events/track.ex +++ b/lib/eventos/events/track.ex @@ -6,13 +6,12 @@ defmodule Eventos.Events.Track do import Ecto.Changeset alias Eventos.Events.{Track, Event, Session} - schema "tracks" do - field :color, :string - field :description, :string - field :name, :string - belongs_to :event, Event - has_many :sessions, Session + field(:color, :string) + field(:description, :string) + field(:name, :string) + belongs_to(:event, Event) + has_many(:sessions, Session) timestamps() end diff --git a/lib/eventos/export/icalendar.ex b/lib/eventos/export/icalendar.ex index b22505c0c..08cd25776 100644 --- a/lib/eventos/export/icalendar.ex +++ b/lib/eventos/export/icalendar.ex @@ -7,13 +7,16 @@ defmodule Eventos.Export.ICalendar do @spec export_event(%Event{}) :: String def export_event(%Event{} = event) do - events = [%ICalendar.Event{ - summary: event.title, - dtstart: event.begins_on, - dtend: event.ends_on, - description: event.description, - uid: event.uuid - }] + events = [ + %ICalendar.Event{ + summary: event.title, + dtstart: event.begins_on, + dtend: event.ends_on, + description: event.description, + uid: event.uuid + } + ] + %ICalendar{events: events} |> ICalendar.to_ics() end diff --git a/lib/eventos/postgrex_types.ex b/lib/eventos/postgrex_types.ex index 9b3f37b50..a068a00d3 100644 --- a/lib/eventos/postgrex_types.ex +++ b/lib/eventos/postgrex_types.ex @@ -1,3 +1,5 @@ -Postgrex.Types.define(Eventos.PostgresTypes, +Postgrex.Types.define( + Eventos.PostgresTypes, [Geo.PostGIS.Extension] ++ Ecto.Adapters.Postgres.extensions(), - json: Poison) + json: Poison +) diff --git a/lib/eventos/slug.ex b/lib/eventos/slug.ex index 0ffd5fad6..e69ed9633 100644 --- a/lib/eventos/slug.ex +++ b/lib/eventos/slug.ex @@ -6,6 +6,7 @@ defmodule Eventos.Slug do case List.pop_at(String.split(slug, "-"), -1) do {nil, _} -> slug + {suffix, slug_parts} -> case Integer.parse(suffix) do {id, _} -> Enum.join(slug_parts, "-") <> "-" <> Integer.to_string(id + 1) diff --git a/lib/eventos_web.ex b/lib/eventos_web.ex index b517ed746..4d01fa711 100644 --- a/lib/eventos_web.ex +++ b/lib/eventos_web.ex @@ -28,8 +28,9 @@ defmodule EventosWeb do def view do quote do - use Phoenix.View, root: "lib/eventos_web/templates", - namespace: EventosWeb + use Phoenix.View, + root: "lib/eventos_web/templates", + namespace: EventosWeb # Import convenience functions from controllers import Phoenix.Controller, only: [get_flash: 2, view_module: 1] diff --git a/lib/eventos_web/auth_pipeline.ex b/lib/eventos_web/auth_pipeline.ex index dccdc5c21..c441c9ad4 100644 --- a/lib/eventos_web/auth_pipeline.ex +++ b/lib/eventos_web/auth_pipeline.ex @@ -3,12 +3,12 @@ defmodule EventosWeb.AuthPipeline do Handles the app sessions """ - use Guardian.Plug.Pipeline, otp_app: :eventos, - module: EventosWeb.Guardian, - error_handler: EventosWeb.AuthErrorHandler - - plug Guardian.Plug.VerifyHeader, claims: %{"typ" => "access"} - plug Guardian.Plug.EnsureAuthenticated - plug Guardian.Plug.LoadResource, ensure: true + use Guardian.Plug.Pipeline, + otp_app: :eventos, + module: EventosWeb.Guardian, + error_handler: EventosWeb.AuthErrorHandler + plug(Guardian.Plug.VerifyHeader, claims: %{"typ" => "access"}) + plug(Guardian.Plug.EnsureAuthenticated) + plug(Guardian.Plug.LoadResource, ensure: true) end diff --git a/lib/eventos_web/channels/user_socket.ex b/lib/eventos_web/channels/user_socket.ex index 89099bd91..dd0c3a156 100644 --- a/lib/eventos_web/channels/user_socket.ex +++ b/lib/eventos_web/channels/user_socket.ex @@ -8,7 +8,7 @@ defmodule EventosWeb.UserSocket do # channel "room:*", EventosWeb.RoomChannel # Transports - transport :websocket, Phoenix.Transports.WebSocket + transport(:websocket, Phoenix.Transports.WebSocket) # transport :longpoll, Phoenix.Transports.LongPoll # Socket params are passed from the client and can diff --git a/lib/eventos_web/controllers/actor_controller.ex b/lib/eventos_web/controllers/actor_controller.ex index f55f1ba9b..18dc166dc 100644 --- a/lib/eventos_web/controllers/actor_controller.ex +++ b/lib/eventos_web/controllers/actor_controller.ex @@ -8,7 +8,7 @@ defmodule EventosWeb.ActorController do alias Eventos.Actors.{Actor, User} alias Eventos.Service.ActivityPub - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do actors = Actors.list_actors() @@ -17,9 +17,9 @@ defmodule EventosWeb.ActorController do def create(conn, %{"actor" => actor_params}) do with %User{} = user <- Guardian.Plug.current_resource(conn), - actor_params <- Map.put(actor_params, "user_id", user.id), - actor_params <- Map.put(actor_params, "keys", keys_for_account()), - {:ok, %Actor{} = actor} <- Actors.create_actor(actor_params) do + actor_params <- Map.put(actor_params, "user_id", user.id), + actor_params <- Map.put(actor_params, "keys", keys_for_account()), + {:ok, %Actor{} = actor} <- Actors.create_actor(actor_params) do conn |> put_status(:created) |> put_resp_header("location", actor_path(conn, :show, actor.preferred_username)) @@ -30,6 +30,7 @@ defmodule EventosWeb.ActorController do defp keys_for_account() do key = :public_key.generate_key({:rsa, 2048, 65_537}) entry = :public_key.pem_entry_encode(:RSAPrivateKey, key) + [entry] |> :public_key.pem_encode() |> String.trim_trailing() @@ -42,10 +43,13 @@ defmodule EventosWeb.ActorController do @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ def search(conn, %{"name" => name}) do - case Actors.search(name) do # find already saved accounts + # find already saved accounts + case Actors.search(name) do {:ok, actors} -> render(conn, "index.json", actors: actors) - {:error, err} -> json(conn, err) + + {:error, err} -> + json(conn, err) end end @@ -57,15 +61,15 @@ defmodule EventosWeb.ActorController do end end -# def delete(conn, %{"id" => id_str}) do -# {id, _} = Integer.parse(id_str) -# if Guardian.Plug.current_resource(conn).actor.id == id do -# actor = Actors.get_actor!(id) -# with {:ok, %Actor{}} <- Actors.delete_actor(actor) do -# send_resp(conn, :no_content, "") -# end -# else -# send_resp(conn, 401, "") -# end -# end + # def delete(conn, %{"id" => id_str}) do + # {id, _} = Integer.parse(id_str) + # if Guardian.Plug.current_resource(conn).actor.id == id do + # actor = Actors.get_actor!(id) + # with {:ok, %Actor{}} <- Actors.delete_actor(actor) do + # send_resp(conn, :no_content, "") + # end + # else + # send_resp(conn, 401, "") + # end + # end end diff --git a/lib/eventos_web/controllers/address_controller.ex b/lib/eventos_web/controllers/address_controller.ex index 4dbbe4493..f33d999f4 100644 --- a/lib/eventos_web/controllers/address_controller.ex +++ b/lib/eventos_web/controllers/address_controller.ex @@ -8,7 +8,7 @@ defmodule EventosWeb.AddressController do alias Eventos.Addresses alias Eventos.Addresses.Address - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do addresses = Addresses.list_addresses() @@ -18,6 +18,7 @@ defmodule EventosWeb.AddressController do def create(conn, %{"address" => address_params}) do with {:ok, geom} <- Addresses.process_geom(address_params["geom"]) do address_params = %{address_params | "geom" => geom} + with {:ok, %Address{} = address} <- Addresses.create_address(address_params) do conn |> put_status(:created) @@ -30,15 +31,18 @@ defmodule EventosWeb.AddressController do def process_geom(%{"type" => type, "data" => data}) do import Logger Logger.debug("Process geom") - Logger.debug(inspect data) - Logger.debug(inspect type) + Logger.debug(inspect(data)) + Logger.debug(inspect(type)) types = [:point] + unless is_atom(type) do type = String.to_existing_atom(type) end + case type do :point -> %Geo.Point{coordinates: {data["latitude"], data["longitude"]}, srid: 4326} + nil -> nil end @@ -66,6 +70,7 @@ defmodule EventosWeb.AddressController do def delete(conn, %{"id" => id}) do address = Addresses.get_address!(id) + with {:ok, %Address{}} <- Addresses.delete_address(address) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/bot_controller.ex b/lib/eventos_web/controllers/bot_controller.ex index c6de235b4..c41d19b80 100644 --- a/lib/eventos_web/controllers/bot_controller.ex +++ b/lib/eventos_web/controllers/bot_controller.ex @@ -4,7 +4,7 @@ defmodule EventosWeb.BotController do alias Eventos.Actors alias Eventos.Actors.{Bot, Actor} - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do bots = Actors.list_bots() @@ -14,7 +14,8 @@ defmodule EventosWeb.BotController do def create(conn, %{"bot" => bot_params}) do with user <- Guardian.Plug.current_resource(conn), bot_params <- Map.put(bot_params, "user_id", user.id), - %Actor{} = actor <- Actors.register_bot_account(%{name: bot_params["name"], summary: bot_params["summary"]}), + %Actor{} = actor <- + Actors.register_bot_account(%{name: bot_params["name"], summary: bot_params["summary"]}), bot_params <- Map.put(bot_params, "actor_id", actor.id), {:ok, %Bot{} = bot} <- Actors.create_bot(bot_params) do conn @@ -39,6 +40,7 @@ defmodule EventosWeb.BotController do def delete(conn, %{"id" => id}) do bot = Actors.get_bot!(id) + with {:ok, %Bot{}} <- Actors.delete_bot(bot) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/category_controller.ex b/lib/eventos_web/controllers/category_controller.ex index a32cad6bb..b1d750862 100644 --- a/lib/eventos_web/controllers/category_controller.ex +++ b/lib/eventos_web/controllers/category_controller.ex @@ -7,7 +7,7 @@ defmodule EventosWeb.CategoryController do alias Eventos.Events alias Eventos.Events.Category - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do categories = Events.list_categories() @@ -38,6 +38,7 @@ defmodule EventosWeb.CategoryController do def delete(conn, %{"id" => id}) do category = Events.get_category!(id) + with {:ok, %Category{}} <- Events.delete_category(category) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/comment_controller.ex b/lib/eventos_web/controllers/comment_controller.ex index d8f096314..6d4e2f91b 100644 --- a/lib/eventos_web/controllers/comment_controller.ex +++ b/lib/eventos_web/controllers/comment_controller.ex @@ -4,7 +4,7 @@ defmodule EventosWeb.CommentController do alias Eventos.Events alias Eventos.Events.Comment - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do comments = Events.list_comments() @@ -35,6 +35,7 @@ defmodule EventosWeb.CommentController do def delete(conn, %{"uuid" => uuid}) do comment = Events.get_comment_with_uuid!(uuid) + with {:ok, %Comment{}} <- Events.delete_comment(comment) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/event_controller.ex b/lib/eventos_web/controllers/event_controller.ex index 516a044fb..3efc94225 100644 --- a/lib/eventos_web/controllers/event_controller.ex +++ b/lib/eventos_web/controllers/event_controller.ex @@ -10,27 +10,48 @@ defmodule EventosWeb.EventController do require Logger - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do ip = "88.161.154.97" - Logger.debug(inspect Geolix.lookup(ip), pretty: true) - with %{city: %Geolix.Result.City{city: city, country: country, location: %Geolix.Record.Location{latitude: latitude, longitude: longitude}}} <- Geolix.lookup(ip) do - Logger.debug(inspect city) - Logger.debug(inspect [latitude, longitude]) - distance = case city do - nil -> 500_000 - _ -> 50_000 - end + Logger.debug(inspect(Geolix.lookup(ip), pretty: true)) + + with %{ + city: %Geolix.Result.City{ + city: city, + country: country, + location: %Geolix.Record.Location{latitude: latitude, longitude: longitude} + } + } <- Geolix.lookup(ip) do + distance = + case city do + nil -> 500_000 + _ -> 50_000 + end + events = Events.find_close_events(longitude, latitude, distance) - render(conn, "index.json", events: events, coord: %{longitude: longitude, latitude: latitude, distance: distance}, city: city, country: country) + + render( + conn, + "index.json", + events: events, + coord: %{longitude: longitude, latitude: latitude, distance: distance}, + city: city, + country: country + ) end end + def index_all(conn, _params) do + events = Events.list_events() + render(conn, "index_all.json", events: events) + end + def create(conn, %{"event" => event_params}) do event_params = process_event_address(event_params) Logger.debug("creating event with") - Logger.debug(inspect event_params) + Logger.debug(inspect(event_params)) + with {:ok, %Event{} = event} <- Events.create_event(event_params) do conn |> put_status(:created) @@ -43,16 +64,22 @@ defmodule EventosWeb.EventController do cond do Map.has_key?(event, "address_type") && event["address_type"] !== :physical -> event + Map.has_key?(event, "physical_address") -> address = event["physical_address"] geom = EventosWeb.AddressController.process_geom(address["geom"]) - address = case geom do - nil -> - address - _ -> - %{address | "geom" => geom} - end + + address = + case geom do + nil -> + address + + _ -> + %{address | "geom" => geom} + end + %{event | "physical_address" => address} + true -> event end @@ -67,6 +94,7 @@ defmodule EventosWeb.EventController do case Events.get_event_full_by_uuid(uuid) do nil -> send_resp(conn, 404, "") + event -> render(conn, "show.json", event: event) end @@ -87,7 +115,7 @@ defmodule EventosWeb.EventController do def delete(conn, %{"uuid" => uuid}) do with event <- Events.get_event_by_uuid(uuid), - {:ok, %Event{}} <- Events.delete_event(event) do + {:ok, %Event{}} <- Events.delete_event(event) do send_resp(conn, :no_content, "") end end diff --git a/lib/eventos_web/controllers/event_request_controller.ex b/lib/eventos_web/controllers/event_request_controller.ex index 9e25c95e7..a2f3b9d8d 100644 --- a/lib/eventos_web/controllers/event_request_controller.ex +++ b/lib/eventos_web/controllers/event_request_controller.ex @@ -1,4 +1,4 @@ -#defmodule EventosWeb.EventRequestController do +# defmodule EventosWeb.EventRequestController do # @moduledoc """ # Controller for Event requests # """ @@ -49,4 +49,4 @@ # send_resp(conn, :no_content, "") # end # end -#end +# end diff --git a/lib/eventos_web/controllers/group_controller.ex b/lib/eventos_web/controllers/group_controller.ex index 530995617..ad4eb4cbe 100644 --- a/lib/eventos_web/controllers/group_controller.ex +++ b/lib/eventos_web/controllers/group_controller.ex @@ -7,7 +7,7 @@ defmodule EventosWeb.GroupController do alias Eventos.Actors alias Eventos.Actors.{Actor, Member} - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do groups = Actors.list_groups() @@ -16,7 +16,7 @@ defmodule EventosWeb.GroupController do def create(conn, %{"group" => group_params}) do with actor_admin = Guardian.Plug.current_resource(conn).actor, - {:ok, %Actor{} = group} <- Actors.create_group(group_params) do + {:ok, %Actor{} = group} <- Actors.create_group(group_params) do conn |> put_status(:created) |> put_resp_header("location", actor_path(conn, :show, group)) @@ -26,15 +26,16 @@ defmodule EventosWeb.GroupController do def join(conn, %{"name" => group_name}) do with actor = Guardian.Plug.current_resource(conn).actor, - group <- Actors.get_group_by_name(group_name), - %Member{} = member <- Actors.create_member(%{"parent_id" => group.id, "actor_id" => actor.id}) do + group <- Actors.get_group_by_name(group_name), + %Member{} = member <- + Actors.create_member(%{"parent_id" => group.id, "actor_id" => actor.id}) do conn |> put_status(:created) |> render(EventosWeb.MemberView, "member.json", member: member) else err -> import Logger - Logger.debug(inspect err) + Logger.debug(inspect(err)) end end end diff --git a/lib/eventos_web/controllers/inboxes_controller.ex b/lib/eventos_web/controllers/inboxes_controller.ex index 89060f24d..699abbd15 100644 --- a/lib/eventos_web/controllers/inboxes_controller.ex +++ b/lib/eventos_web/controllers/inboxes_controller.ex @@ -1,8 +1,6 @@ defmodule EventosWeb.InboxesController do - use EventosWeb, :controller def create(conn) do - end end diff --git a/lib/eventos_web/controllers/nodeinfo_controller.ex b/lib/eventos_web/controllers/nodeinfo_controller.ex index c00584bc0..b01e3f74f 100644 --- a/lib/eventos_web/controllers/nodeinfo_controller.ex +++ b/lib/eventos_web/controllers/nodeinfo_controller.ex @@ -22,8 +22,8 @@ defmodule EventosWeb.NodeinfoController do # Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json def nodeinfo(conn, %{"version" => "2.0.json"}) do import Logger - Logger.debug(inspect @instance) - #stats = Stats.get_stats() + Logger.debug(inspect(@instance)) + # stats = Stats.get_stats() response = %{ version: "2.0", @@ -39,12 +39,12 @@ defmodule EventosWeb.NodeinfoController do openRegistrations: Keyword.get(@instance, :registrations_open), usage: %{ users: %{ - #total: stats.user_count || 0 + # total: stats.user_count || 0 total: Actors.count_users() }, localPosts: Events.count_local_events(), - localComments: Events.count_local_comments(), - #localPosts: stats.status_count || 0 + localComments: Events.count_local_comments() + # localPosts: stats.status_count || 0 }, metadata: %{ nodeName: Keyword.get(@instance, :name) diff --git a/lib/eventos_web/controllers/outboxes_controller.ex b/lib/eventos_web/controllers/outboxes_controller.ex index f2dd0125e..bdd997ef3 100644 --- a/lib/eventos_web/controllers/outboxes_controller.ex +++ b/lib/eventos_web/controllers/outboxes_controller.ex @@ -1,5 +1,4 @@ defmodule EventosWeb.OutboxesController do - use EventosWeb, :controller def show(conn) do diff --git a/lib/eventos_web/controllers/page_controller.ex b/lib/eventos_web/controllers/page_controller.ex index 61b8f71ba..9179f462b 100644 --- a/lib/eventos_web/controllers/page_controller.ex +++ b/lib/eventos_web/controllers/page_controller.ex @@ -4,9 +4,9 @@ defmodule EventosWeb.PageController do """ use EventosWeb, :controller - plug :put_layout, false + plug(:put_layout, false) def index(conn, _params) do - render conn, "index.html" + render(conn, "index.html") end end diff --git a/lib/eventos_web/controllers/participant_controller.ex b/lib/eventos_web/controllers/participant_controller.ex index a9c6b142c..1507c597e 100644 --- a/lib/eventos_web/controllers/participant_controller.ex +++ b/lib/eventos_web/controllers/participant_controller.ex @@ -8,9 +8,11 @@ defmodule EventosWeb.ParticipantController do def join(conn, %{"uuid" => uuid}) do with event <- Events.get_event_by_uuid(uuid), - %{actor: actor} <- Guardian.Plug.current_resource(conn) do - participant = Events.create_participant(%{"event_id" => event.id, "actor_id" => actor.id, "role" => 1}) - render(conn, "participant.json", %{participant: participant}) + %{actor: actor} <- Guardian.Plug.current_resource(conn) do + participant = + Events.create_participant(%{"event_id" => event.id, "actor_id" => actor.id, "role" => 1}) + + render(conn, "participant.json", %{participant: participant}) end end end diff --git a/lib/eventos_web/controllers/search_controller.ex b/lib/eventos_web/controllers/search_controller.ex index bfdd1409f..7b3d5bb4f 100644 --- a/lib/eventos_web/controllers/search_controller.ex +++ b/lib/eventos_web/controllers/search_controller.ex @@ -7,14 +7,17 @@ defmodule EventosWeb.SearchController do alias Eventos.Events alias Eventos.Actors - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def search(conn, %{"name" => name}) do events = Events.find_events_by_name(name) - case Actors.search(name) do # find already saved accounts + # find already saved accounts + case Actors.search(name) do {:ok, actors} -> render(conn, "search.json", events: events, actors: actors) - {:error, err} -> json(conn, err) + + {:error, err} -> + json(conn, err) end end end diff --git a/lib/eventos_web/controllers/session_controller.ex b/lib/eventos_web/controllers/session_controller.ex index e66dea842..1a7c603ec 100644 --- a/lib/eventos_web/controllers/session_controller.ex +++ b/lib/eventos_web/controllers/session_controller.ex @@ -7,7 +7,7 @@ defmodule EventosWeb.SessionController do alias Eventos.Events alias Eventos.Events.Session - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do sessions = Events.list_sessions() @@ -48,6 +48,7 @@ defmodule EventosWeb.SessionController do def delete(conn, %{"id" => id}) do session = Events.get_session!(id) + with {:ok, %Session{}} <- Events.delete_session(session) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/tag_controller.ex b/lib/eventos_web/controllers/tag_controller.ex index ec35c12fe..9a169f0c7 100644 --- a/lib/eventos_web/controllers/tag_controller.ex +++ b/lib/eventos_web/controllers/tag_controller.ex @@ -7,7 +7,7 @@ defmodule EventosWeb.TagController do alias Eventos.Events alias Eventos.Events.Tag - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do tags = Events.list_tags() @@ -38,6 +38,7 @@ defmodule EventosWeb.TagController do def delete(conn, %{"id" => id}) do tag = Events.get_tag!(id) + with {:ok, %Tag{}} <- Events.delete_tag(tag) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/track_controller.ex b/lib/eventos_web/controllers/track_controller.ex index 99dc4145a..437811c9d 100644 --- a/lib/eventos_web/controllers/track_controller.ex +++ b/lib/eventos_web/controllers/track_controller.ex @@ -7,7 +7,7 @@ defmodule EventosWeb.TrackController do alias Eventos.Events alias Eventos.Events.Track - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do tracks = Events.list_tracks() @@ -38,6 +38,7 @@ defmodule EventosWeb.TrackController do def delete(conn, %{"id" => id}) do track = Events.get_track!(id) + with {:ok, %Track{}} <- Events.delete_track(track) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/user_controller.ex b/lib/eventos_web/controllers/user_controller.ex index e85134d7c..6ce2695a1 100644 --- a/lib/eventos_web/controllers/user_controller.ex +++ b/lib/eventos_web/controllers/user_controller.ex @@ -9,7 +9,7 @@ defmodule EventosWeb.UserController do alias Eventos.Repo alias Eventos.Actors.Service.{Activation, ResetPassword} - action_fallback EventosWeb.FallbackController + action_fallback(EventosWeb.FallbackController) def index(conn, _params) do users = Actors.list_users_with_actors() @@ -17,17 +17,20 @@ defmodule EventosWeb.UserController do end def register(conn, %{"username" => username, "email" => email, "password" => password}) do - with {:ok, %User{} = user} <- Actors.register(%{email: email, password: password, username: username}) do + with {:ok, %User{} = user} <- + Actors.register(%{email: email, password: password, username: username}) do Activation.send_confirmation_email(user, "locale") + conn - |> put_status(:created) - |> render("confirmation.json", %{user: user}) + |> put_status(:created) + |> render("confirmation.json", %{user: user}) end end def validate(conn, %{"token" => token}) do with {:ok, %User{} = user} <- Activation.check_confirmation_token(token) do {:ok, token, _claims} = EventosWeb.Guardian.encode_and_sign(user) + conn |> put_resp_header("location", user_path(conn, :show_current_actor)) |> render("show_with_token.json", %{user: user, token: token}) @@ -42,7 +45,8 @@ defmodule EventosWeb.UserController do def resend_confirmation(conn, %{"email" => email}) do with {:ok, %User{} = user} <- Actors.find_by_email(email), false <- is_nil(user.confirmation_token), - true <- Timex.before?(Timex.shift(user.confirmation_sent_at, hours: 1), DateTime.utc_now()) do + true <- + Timex.before?(Timex.shift(user.confirmation_sent_at, hours: 1), DateTime.utc_now()) do Activation.resend_confirmation_email(user) render(conn, "confirmation.json", %{user: user}) else @@ -50,6 +54,7 @@ defmodule EventosWeb.UserController do conn |> put_status(:not_found) |> json(%{"error" => "Unable to find an user with this email"}) + _ -> conn |> put_status(:not_found) @@ -66,6 +71,7 @@ defmodule EventosWeb.UserController do conn |> put_status(:not_found) |> json(%{"errors" => "Unable to find an user with this email"}) + {:error, :email_too_soon} -> conn |> put_status(:not_found) @@ -82,6 +88,7 @@ defmodule EventosWeb.UserController do conn |> put_status(:not_found) |> json(%{"errors" => %{"token" => ["Wrong token for password reset"]}}) + {:error, %Ecto.Changeset{} = changeset} -> conn |> put_status(:unprocessable_entity) @@ -90,9 +97,11 @@ defmodule EventosWeb.UserController do end def show_current_actor(conn, _params) do - user = conn - |> Guardian.Plug.current_resource() - |> Repo.preload(:actors) + user = + conn + |> Guardian.Plug.current_resource() + |> Repo.preload(:actors) + render(conn, "show_simple.json", user: user) end @@ -101,14 +110,13 @@ defmodule EventosWeb.UserController do |> Enum.map(fn {field, detail} -> "#{field} " <> render_detail(detail) end) - |> Enum.join + |> Enum.join() end - defp render_detail({message, values}) do - Enum.reduce values, message, fn {k, v}, acc -> + Enum.reduce(values, message, fn {k, v}, acc -> String.replace(acc, "%{#{k}}", to_string(v)) - end + end) end defp render_detail(message) do @@ -125,6 +133,7 @@ defmodule EventosWeb.UserController do def delete(conn, %{"id" => id}) do user = Actors.get_user!(id) + with {:ok, %User{}} <- Actors.delete_user(user) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/controllers/user_session_controller.ex b/lib/eventos_web/controllers/user_session_controller.ex index 96c2f127d..c3d5f0076 100644 --- a/lib/eventos_web/controllers/user_session_controller.ex +++ b/lib/eventos_web/controllers/user_session_controller.ex @@ -10,17 +10,22 @@ defmodule EventosWeb.UserSessionController do with {:ok, %User{} = user} <- Actors.find_by_email(email), {:ok, %User{} = _user} <- User.is_confirmed(user), {:ok, token, _claims} <- Actors.authenticate(%{user: user, password: password}) do - # Render the token - render conn, "token.json", %{token: token, user: user} + # Render the token + render(conn, "token.json", %{token: token, user: user}) else {:error, :not_found} -> conn |> put_status(401) |> json(%{"error_msg" => "No such user", "display_error" => "session.error.bad_login"}) + {:error, :unconfirmed} -> conn |> put_status(401) - |> json(%{"error_msg" => "User is not activated", "display_error" => "session.error.not_activated"}) + |> json(%{ + "error_msg" => "User is not activated", + "display_error" => "session.error.not_activated" + }) + {:error, :unauthorized} -> conn |> put_status(401) diff --git a/lib/eventos_web/endpoint.ex b/lib/eventos_web/endpoint.ex index 82dcb859a..e45f916d7 100644 --- a/lib/eventos_web/endpoint.ex +++ b/lib/eventos_web/endpoint.ex @@ -4,45 +4,53 @@ defmodule EventosWeb.Endpoint do """ use Phoenix.Endpoint, otp_app: :eventos - socket "/socket", EventosWeb.UserSocket + socket("/socket", EventosWeb.UserSocket) # Serve at "/" the static files from "priv/static" directory. # # You should set gzip to true if you are running phoenix.digest # when deploying your static files in production. - plug Plug.Static, - at: "/", from: :eventos, gzip: false, + plug( + Plug.Static, + at: "/", + from: :eventos, + gzip: false, only: ~w(css fonts images js favicon.ico robots.txt index.html) + ) # Code reloading can be explicitly enabled under the # :code_reloader configuration of your endpoint. if code_reloading? do - socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket - plug Phoenix.LiveReloader - plug Phoenix.CodeReloader + socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) + plug(Phoenix.LiveReloader) + plug(Phoenix.CodeReloader) end - plug CORSPlug - plug Plug.RequestId - plug Plug.Logger + plug(CORSPlug) + plug(Plug.RequestId) + plug(Plug.Logger) - plug Plug.Parsers, + plug( + Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], json_decoder: Poison + ) - plug Plug.MethodOverride - plug Plug.Head + plug(Plug.MethodOverride) + plug(Plug.Head) # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. - plug Plug.Session, + plug( + Plug.Session, store: :cookie, key: "_eventos_key", signing_salt: "F9CCTF22" + ) - plug EventosWeb.Router + plug(EventosWeb.Router) @doc """ Callback invoked for dynamically configuring the endpoint. diff --git a/lib/eventos_web/guardian.ex b/lib/eventos_web/guardian.ex index 590678ce8..333ac243d 100644 --- a/lib/eventos_web/guardian.ex +++ b/lib/eventos_web/guardian.ex @@ -2,10 +2,12 @@ defmodule EventosWeb.Guardian do @moduledoc """ Handles the JWT tokens encoding and decoding """ - use Guardian, otp_app: :eventos, permissions: %{ - superuser: [:moderate, :super], - user: [:base] - } + use Guardian, + otp_app: :eventos, + permissions: %{ + superuser: [:moderate, :super], + user: [:base] + } alias Eventos.Actors alias Eventos.Actors.User @@ -23,6 +25,7 @@ defmodule EventosWeb.Guardian do case Integer.parse(uid_str) do {uid, ""} -> {:ok, Actors.get_user_with_actor!(uid)} + _ -> {:error, :invalid_id} end diff --git a/lib/eventos_web/http_signature.ex b/lib/eventos_web/http_signature.ex index f5094e19e..554db61c0 100644 --- a/lib/eventos_web/http_signature.ex +++ b/lib/eventos_web/http_signature.ex @@ -19,9 +19,11 @@ defmodule EventosWeb.HTTPSignaturePlug do def call(conn, _opts) do user = conn.params["actor"] - Logger.debug fn -> + + Logger.debug(fn -> "Checking sig for #{user}" - end + end) + with [signature | _] <- get_req_header(conn, "signature") do cond do signature && String.contains?(signature, user) -> @@ -42,10 +44,10 @@ defmodule EventosWeb.HTTPSignaturePlug do Logger.debug("No signature header!") conn end - else - _ -> - Logger.debug("No signature header!") - conn + else + _ -> + Logger.debug("No signature header!") + conn end end end diff --git a/lib/eventos_web/router.ex b/lib/eventos_web/router.ex index b396ed314..f90ea4fae 100644 --- a/lib/eventos_web/router.ex +++ b/lib/eventos_web/router.ex @@ -5,107 +5,106 @@ defmodule EventosWeb.Router do use EventosWeb, :router pipeline :api do - plug :accepts, ["json"] + plug(:accepts, ["json"]) end pipeline :well_known do - plug :accepts, ["json/application", "jrd-json"] + plug(:accepts, ["json/application", "jrd-json"]) end pipeline :activity_pub do - plug :accepts, ["activity-json"] + plug(:accepts, ["activity-json"]) plug(EventosWeb.HTTPSignaturePlug) end pipeline :api_auth do - plug :accepts, ["json"] - plug EventosWeb.AuthPipeline + plug(:accepts, ["json"]) + plug(EventosWeb.AuthPipeline) end pipeline :browser do - plug :accepts, ["html"] - plug :fetch_session - plug :fetch_flash - plug :protect_from_forgery - plug :put_secure_browser_headers + plug(:accepts, ["html"]) + plug(:fetch_session) + plug(:fetch_flash) + plug(:protect_from_forgery) + plug(:put_secure_browser_headers) end scope "/api", EventosWeb do - pipe_through :api + pipe_through(:api) scope "/v1" do + post("/users", UserController, :register) + get("/users/validate/:token", UserController, :validate) + post("/users/resend", UserController, :resend_confirmation) - post "/users", UserController, :register - get "/users/validate/:token", UserController, :validate - post "/users/resend", UserController, :resend_confirmation + post("/users/password-reset/send", UserController, :send_reset_password) + post("/users/password-reset/post", UserController, :reset_password) - post "/users/password-reset/send", UserController, :send_reset_password - post "/users/password-reset/post", UserController, :reset_password + post("/login", UserSessionController, :sign_in) + get("/groups", GroupController, :index) + get("/events", EventController, :index) + get("/events/all", EventController, :index_all) + get("/events/search/:name", EventController, :search) + get("/events/:uuid/ics", EventController, :export_to_ics) + get("/events/:uuid/tracks", TrackController, :show_tracks_for_event) + get("/events/:uuid/sessions", SessionController, :show_sessions_for_event) + get("/events/:uuid", EventController, :show) + get("/comments/:uuid", CommentController, :show) + get("/bots/:id", BotController, :show) + get("/bots", BotController, :index) - post "/login", UserSessionController, :sign_in - get "/groups", GroupController, :index - get "/events", EventController, :index - get "/events/search/:name", EventController, :search - get "/events/:uuid/ics", EventController, :export_to_ics - get "/events/:uuid/tracks", TrackController, :show_tracks_for_event - get "/events/:uuid/sessions", SessionController, :show_sessions_for_event - get "/events/:uuid", EventController, :show - get "/comments/:uuid", CommentController, :show - get "/bots/:id", BotController, :show - get "/bots", BotController, :index + get("/actors", ActorController, :index) + get("/actors/search/:name", ActorController, :search) + get("/actors/:name", ActorController, :show) + resources("/tags", TagController, only: [:index, :show]) + resources("/categories", CategoryController, only: [:index, :show]) + resources("/sessions", SessionController, only: [:index, :show]) + resources("/tracks", TrackController, only: [:index, :show]) + resources("/addresses", AddressController, only: [:index, :show]) - get "/actors", ActorController, :index - get "/actors/search/:name", ActorController, :search - get "/actors/:name", ActorController, :show - resources "/tags", TagController, only: [:index, :show] - resources "/categories", CategoryController, only: [:index, :show] - resources "/sessions", SessionController, only: [:index, :show] - resources "/tracks", TrackController, only: [:index, :show] - resources "/addresses", AddressController, only: [:index, :show] - - get "/search/:name", SearchController, :search + get("/search/:name", SearchController, :search) end end # Other scopes may use custom stacks. scope "/api", EventosWeb do - pipe_through :api_auth + pipe_through(:api_auth) - scope "/v1" do - - get "/user", UserController, :show_current_actor - post "/sign-out", UserSessionController, :sign_out - resources "/users", UserController, except: [:new, :edit, :show] - post "/actors", ActorController, :create - patch "/actors/:name", ActorController, :update - post "/events", EventController, :create - patch "/events/:uuid", EventController, :update - put "/events/:uuid", EventController, :update - delete "/events/:uuid", EventController, :delete - post "/events/:uuid/join", ParticipantController, :join - post "/comments", CommentController, :create - patch "/comments/:uuid", CommentController, :update - put "/comments/:uuid", CommentController, :update - delete "/comments/:uuid", CommentController, :delete - resources "/bots", BotController, except: [:new, :edit, :show, :index] - post "/groups", GroupController, :create - post "/groups/:name/join", GroupController, :join - resources "/members", MemberController - resources "/sessions", SessionController, except: [:index, :show] - resources "/tracks", TrackController, except: [:index, :show] - get "/tracks/:id/sessions", SessionController, :show_sessions_for_track - resources "/categories", CategoryController - resources "/tags", TagController - resources "/addresses", AddressController, except: [:index, :show] - end + scope "/v1" do + get("/user", UserController, :show_current_actor) + post("/sign-out", UserSessionController, :sign_out) + resources("/users", UserController, except: [:new, :edit, :show]) + post("/actors", ActorController, :create) + patch("/actors/:name", ActorController, :update) + post("/events", EventController, :create) + patch("/events/:uuid", EventController, :update) + put("/events/:uuid", EventController, :update) + delete("/events/:uuid", EventController, :delete) + post("/events/:uuid/join", ParticipantController, :join) + post("/comments", CommentController, :create) + patch("/comments/:uuid", CommentController, :update) + put("/comments/:uuid", CommentController, :update) + delete("/comments/:uuid", CommentController, :delete) + resources("/bots", BotController, except: [:new, :edit, :show, :index]) + post("/groups", GroupController, :create) + post("/groups/:name/join", GroupController, :join) + resources("/members", MemberController) + resources("/sessions", SessionController, except: [:index, :show]) + resources("/tracks", TrackController, except: [:index, :show]) + get("/tracks/:id/sessions", SessionController, :show_sessions_for_track) + resources("/categories", CategoryController) + resources("/tags", TagController) + resources("/addresses", AddressController, except: [:index, :show]) + end end scope "/.well-known", EventosWeb do - pipe_through :well_known + pipe_through(:well_known) - get "/host-meta", WebFingerController, :host_meta - get "/webfinger", WebFingerController, :webfinger - get "/nodeinfo", NodeinfoController, :schemas + get("/host-meta", WebFingerController, :host_meta) + get("/webfinger", WebFingerController, :webfinger) + get("/nodeinfo", NodeinfoController, :schemas) end scope "/nodeinfo", EventosWeb do @@ -113,25 +112,25 @@ defmodule EventosWeb.Router do end scope "/", EventosWeb do - pipe_through :activity_pub + pipe_through(:activity_pub) - get "/@:name", ActivityPubController, :actor - get "/@:name/outbox", ActivityPubController, :outbox - get "/@:name/following", ActivityPubController, :following - get "/@:name/followers", ActivityPubController, :followers - get "/events/:uuid", ActivityPubController, :event - post "/@:name/inbox", ActivityPubController, :inbox - post "/inbox", ActivityPubController, :inbox + get("/@:name", ActivityPubController, :actor) + get("/@:name/outbox", ActivityPubController, :outbox) + get("/@:name/following", ActivityPubController, :following) + get("/@:name/followers", ActivityPubController, :followers) + get("/events/:uuid", ActivityPubController, :event) + post("/@:name/inbox", ActivityPubController, :inbox) + post("/inbox", ActivityPubController, :inbox) end - if Mix.env == :dev do + if Mix.env() == :dev do # If using Phoenix - forward "/sent_emails", Bamboo.SentEmailViewerPlug + forward("/sent_emails", Bamboo.SentEmailViewerPlug) end scope "/", EventosWeb do - pipe_through :browser + pipe_through(:browser) - get "/*path", PageController, :index + get("/*path", PageController, :index) end end diff --git a/lib/eventos_web/views/activity_pub/actor_view.ex b/lib/eventos_web/views/activity_pub/actor_view.ex index 025764974..79dff4bc5 100644 --- a/lib/eventos_web/views/activity_pub/actor_view.ex +++ b/lib/eventos_web/views/activity_pub/actor_view.ex @@ -34,16 +34,16 @@ defmodule EventosWeb.ActivityPub.ActorView do "publicKeyPem" => public_key }, "endpoints" => %{ - "sharedInbox" => actor.shared_inbox_url, - }, -# "icon" => %{ -# "type" => "Image", -# "url" => User.avatar_url(actor) -# }, -# "image" => %{ -# "type" => "Image", -# "url" => User.banner_url(actor) -# } + "sharedInbox" => actor.shared_inbox_url + } + # "icon" => %{ + # "type" => "Image", + # "url" => User.avatar_url(actor) + # }, + # "image" => %{ + # "type" => "Image", + # "url" => User.banner_url(actor) + # } } |> Map.merge(Utils.make_json_ld_header()) end @@ -87,13 +87,14 @@ defmodule EventosWeb.ActivityPub.ActorView do end def render("outbox.json", %{actor: actor, page: page}) do - {page, no_page} = if page == 0 do - {1, true} - else - {page, false} - end + {page, no_page} = + if page == 0 do + {1, true} + else + {page, false} + end - {activities, total} = ActivityPub.fetch_public_activities_for_actor(actor, page) + {activities, total} = ActivityPub.fetch_public_activities_for_actor(actor, page) collection = Enum.map(activities, fn act -> @@ -128,7 +129,12 @@ defmodule EventosWeb.ActivityPub.ActorView do def render("activity.json", %{activity: %Activity{local: local} = activity}) do %{ "id" => activity.data.url <> "/activity", - "type" => if local do "Create" else "Announce" end, + "type" => + if local do + "Create" + else + "Announce" + end, "actor" => activity.data.organizer_actor.url, "published" => Timex.now(), "to" => ["https://www.w3.org/ns/activitystreams#Public"], diff --git a/lib/eventos_web/views/activity_pub/object_view.ex b/lib/eventos_web/views/activity_pub/object_view.ex index 6073ef683..4a03510bc 100644 --- a/lib/eventos_web/views/activity_pub/object_view.ex +++ b/lib/eventos_web/views/activity_pub/object_view.ex @@ -2,6 +2,7 @@ defmodule EventosWeb.ActivityPub.ObjectView do use EventosWeb, :view alias EventosWeb.ActivityPub.ObjectView alias Eventos.Service.ActivityPub.Transmogrifier + @base %{ "@context" => [ "https://www.w3.org/ns/activitystreams", @@ -17,8 +18,6 @@ defmodule EventosWeb.ActivityPub.ObjectView do } def render("event.json", %{event: event}) do - - event = %{ "type" => "Event", "id" => event.url, @@ -27,8 +26,9 @@ defmodule EventosWeb.ActivityPub.ObjectView do "content" => event.description, "mediaType" => "text/markdown", "published" => Timex.format!(event.inserted_at, "{ISO:Extended}"), - "updated" => Timex.format!(event.updated_at, "{ISO:Extended}"), + "updated" => Timex.format!(event.updated_at, "{ISO:Extended}") } + Map.merge(event, @base) end diff --git a/lib/eventos_web/views/actor_view.ex b/lib/eventos_web/views/actor_view.ex index 15da33332..742b9db96 100644 --- a/lib/eventos_web/views/actor_view.ex +++ b/lib/eventos_web/views/actor_view.ex @@ -19,7 +19,8 @@ defmodule EventosWeb.ActorView do end def render("actor_basic.json", %{actor: actor}) do - %{id: actor.id, + %{ + id: actor.id, username: actor.preferred_username, domain: actor.domain, display_name: actor.name, @@ -28,12 +29,13 @@ defmodule EventosWeb.ActorView do # public_key: actor.public_key, suspended: actor.suspended, url: actor.url, - avatar: actor.avatar_url, + avatar: actor.avatar_url } end def render("actor.json", %{actor: actor}) do - output = %{id: actor.id, + output = %{ + id: actor.id, username: actor.preferred_username, domain: actor.domain, display_name: actor.name, @@ -46,11 +48,18 @@ defmodule EventosWeb.ActorView do banner: actor.banner_url, organized_events: render_many(actor.organized_events, EventView, "event_for_actor.json") } + import Logger - Logger.debug(inspect actor.type) + Logger.debug(inspect(actor.type)) + if actor.type == :Group do Logger.debug("I'm a group !") - Map.put(output, :members, render_many(Actors.members_for_group(actor), MemberView, "member.json")) + + Map.put( + output, + :members, + render_many(Actors.members_for_group(actor), MemberView, "member.json") + ) else Logger.debug("not a group") output diff --git a/lib/eventos_web/views/address_view.ex b/lib/eventos_web/views/address_view.ex index aed6766b7..604818a03 100644 --- a/lib/eventos_web/views/address_view.ex +++ b/lib/eventos_web/views/address_view.ex @@ -15,7 +15,8 @@ defmodule EventosWeb.AddressView do end def render("address.json", %{address: address}) do - %{id: address.id, + %{ + id: address.id, description: address.description, floor: address.floor, addressCountry: address.addressCountry, @@ -29,11 +30,12 @@ defmodule EventosWeb.AddressView do def render("geom.json", %{address: %Geo.Point{} = point}) do [lat, lon] = Tuple.to_list(point.coordinates) + %{ type: "point", data: %{ - "latitude": lat, - "longitude": lon, + latitude: lat, + longitude: lon } } end diff --git a/lib/eventos_web/views/bot_view.ex b/lib/eventos_web/views/bot_view.ex index 4074279c8..72cd072b0 100644 --- a/lib/eventos_web/views/bot_view.ex +++ b/lib/eventos_web/views/bot_view.ex @@ -11,8 +11,6 @@ defmodule EventosWeb.BotView do end def render("bot.json", %{bot: bot}) do - %{id: bot.id, - source: bot.source, - type: bot.type} + %{id: bot.id, source: bot.source, type: bot.type} end end diff --git a/lib/eventos_web/views/category_view.ex b/lib/eventos_web/views/category_view.ex index ae42637d6..ec28935d3 100644 --- a/lib/eventos_web/views/category_view.ex +++ b/lib/eventos_web/views/category_view.ex @@ -14,9 +14,11 @@ defmodule EventosWeb.CategoryView do end def render("category.json", %{category: category}) do - %{id: category.id, + %{ + id: category.id, title: category.title, description: category.description, - picture: category.picture} + picture: category.picture + } end end diff --git a/lib/eventos_web/views/comment_view.ex b/lib/eventos_web/views/comment_view.ex index 17654fe43..e273e5096 100644 --- a/lib/eventos_web/views/comment_view.ex +++ b/lib/eventos_web/views/comment_view.ex @@ -11,10 +11,6 @@ defmodule EventosWeb.CommentView do end def render("comment.json", %{comment: comment}) do - %{id: comment.id, - uuid: comment.uuid, - url: comment.url, - text: comment.text - } + %{id: comment.id, uuid: comment.uuid, url: comment.url, text: comment.text} end end diff --git a/lib/eventos_web/views/error_helpers.ex b/lib/eventos_web/views/error_helpers.ex index 0001115ca..375bc6c16 100644 --- a/lib/eventos_web/views/error_helpers.ex +++ b/lib/eventos_web/views/error_helpers.ex @@ -9,8 +9,8 @@ defmodule EventosWeb.ErrorHelpers do Generates tag for inlined form input errors. """ def error_tag(form, field) do - Enum.map(Keyword.get_values(form.errors, field), fn (error) -> - content_tag :span, translate_error(error), class: "help-block" + Enum.map(Keyword.get_values(form.errors, field), fn error -> + content_tag(:span, translate_error(error), class: "help-block") end) end diff --git a/lib/eventos_web/views/error_view.ex b/lib/eventos_web/views/error_view.ex index 7e8c57e00..9be85a2a7 100644 --- a/lib/eventos_web/views/error_view.ex +++ b/lib/eventos_web/views/error_view.ex @@ -19,6 +19,6 @@ defmodule EventosWeb.ErrorView do # In case no render clause matches or no # template is found, let's render it as 500 def template_not_found(_template, assigns) do - render "500.html", assigns + render("500.html", assigns) end end diff --git a/lib/eventos_web/views/event_view.ex b/lib/eventos_web/views/event_view.ex index f57887f12..35e766a72 100644 --- a/lib/eventos_web/views/event_view.ex +++ b/lib/eventos_web/views/event_view.ex @@ -10,7 +10,13 @@ defmodule EventosWeb.EventView do data: render_many(events, EventView, "event_simple.json"), coord: coord, city: city, - country: country, + country: country + } + end + + def render("index_all.json", %{events: events}) do + %{ + data: render_many(events, EventView, "event_simple.json") } end @@ -23,14 +29,12 @@ defmodule EventosWeb.EventView do end def render("event_for_actor.json", %{event: event}) do - %{id: event.id, - title: event.title, - uuid: event.uuid, - } + %{id: event.id, title: event.title, uuid: event.uuid} end def render("event_simple.json", %{event: event}) do - %{id: event.id, + %{ + id: event.id, title: event.title, description: event.description, begins_on: event.begins_on, @@ -39,15 +43,16 @@ defmodule EventosWeb.EventView do organizer: %{ username: event.organizer_actor.preferred_username, display_name: event.organizer_actor.name, - avatar: event.organizer_actor.avatar_url, + avatar: event.organizer_actor.avatar_url }, type: "Event", - address_type: event.address_type, + address_type: event.address_type } end def render("event.json", %{event: event}) do - %{id: event.id, + %{ + id: event.id, title: event.title, description: event.description, begins_on: event.begins_on, @@ -57,7 +62,7 @@ defmodule EventosWeb.EventView do participants: render_many(event.participants, ActorView, "actor_basic.json"), physical_address: render_one(event.physical_address, AddressView, "address.json"), type: "Event", - address_type: event.address_type, + address_type: event.address_type } end end diff --git a/lib/eventos_web/views/group_view.ex b/lib/eventos_web/views/group_view.ex index c3a6847b0..f2f159f4c 100644 --- a/lib/eventos_web/views/group_view.ex +++ b/lib/eventos_web/views/group_view.ex @@ -18,16 +18,18 @@ defmodule EventosWeb.GroupView do end def render("group_simple.json", %{group: group}) do - %{id: group.id, + %{ + id: group.id, title: group.title, description: group.description, suspended: group.suspended, - url: group.url, + url: group.url } end def render("group.json", %{group: group}) do - %{id: group.id, + %{ + id: group.id, title: group.title, description: group.description, suspended: group.suspended, diff --git a/lib/eventos_web/views/participant_view.ex b/lib/eventos_web/views/participant_view.ex index 123950fb8..ce489138c 100644 --- a/lib/eventos_web/views/participant_view.ex +++ b/lib/eventos_web/views/participant_view.ex @@ -14,7 +14,6 @@ defmodule EventosWeb.ParticipantView do end def render("participant.json", %{participant: participant}) do - %{id: participant.id, - role: participant.role} + %{id: participant.id, role: participant.role} end end diff --git a/lib/eventos_web/views/search_view.ex b/lib/eventos_web/views/search_view.ex index e04fff151..212086560 100644 --- a/lib/eventos_web/views/search_view.ex +++ b/lib/eventos_web/views/search_view.ex @@ -9,7 +9,7 @@ defmodule EventosWeb.SearchView do %{ data: %{ events: render_many(events, EventView, "event_simple.json"), - actors: render_many(actors, ActorView, "actor_basic.json"), + actors: render_many(actors, ActorView, "actor_basic.json") } } end diff --git a/lib/eventos_web/views/session_view.ex b/lib/eventos_web/views/session_view.ex index 5ed81d091..812f15fb1 100644 --- a/lib/eventos_web/views/session_view.ex +++ b/lib/eventos_web/views/session_view.ex @@ -14,7 +14,8 @@ defmodule EventosWeb.SessionView do end def render("session.json", %{session: session}) do - %{id: session.id, + %{ + id: session.id, title: session.title, subtitle: session.subtitle, short_abstract: session.short_abstract, @@ -22,6 +23,7 @@ defmodule EventosWeb.SessionView do language: session.language, slides_url: session.slides_url, videos_urls: session.videos_urls, - audios_urls: session.audios_urls} + audios_urls: session.audios_urls + } end end diff --git a/lib/eventos_web/views/tag_view.ex b/lib/eventos_web/views/tag_view.ex index 3508ed97a..94b9b3d2a 100644 --- a/lib/eventos_web/views/tag_view.ex +++ b/lib/eventos_web/views/tag_view.ex @@ -14,7 +14,6 @@ defmodule EventosWeb.TagView do end def render("tag.json", %{tag: tag}) do - %{id: tag.id, - title: tag.title} + %{id: tag.id, title: tag.title} end end diff --git a/lib/eventos_web/views/track_view.ex b/lib/eventos_web/views/track_view.ex index 15eb35579..55654922d 100644 --- a/lib/eventos_web/views/track_view.ex +++ b/lib/eventos_web/views/track_view.ex @@ -14,9 +14,6 @@ defmodule EventosWeb.TrackView do end def render("track.json", %{track: track}) do - %{id: track.id, - name: track.name, - description: track.description, - color: track.color} + %{id: track.id, name: track.name, description: track.description, color: track.color} end end diff --git a/lib/eventos_web/views/user_view.ex b/lib/eventos_web/views/user_view.ex index 480983523..13f25991d 100644 --- a/lib/eventos_web/views/user_view.ex +++ b/lib/eventos_web/views/user_view.ex @@ -26,35 +26,30 @@ defmodule EventosWeb.UserView do end def render("user_simple.json", %{user: user}) do - %{id: user.id, + %{ + id: user.id, role: user.role, actors: render_many(user.actors, ActorView, "actor_basic.json") } end def render("user.json", %{user: user}) do - %{id: user.id, - role: user.role, - actors: render_many(user.actors, ActorView, "actor.json") - } + %{id: user.id, role: user.role, actors: render_many(user.actors, ActorView, "actor.json")} end def render("user_private.json", %{user: user}) do - %{id: user.id, - email: user.email, - role: user.role, - } + %{id: user.id, email: user.email, role: user.role} end def render("confirmation.json", %{user: user}) do %{ - email: user.email, + email: user.email } end def render("password_reset.json", %{user: user}) do %{ - email: user.email, + email: user.email } end end diff --git a/lib/mix/tasks/create_bot.ex b/lib/mix/tasks/create_bot.ex index 4c8718649..a56c0ed08 100644 --- a/lib/mix/tasks/create_bot.ex +++ b/lib/mix/tasks/create_bot.ex @@ -15,12 +15,17 @@ defmodule Mix.Tasks.CreateBot do Mix.Task.run("app.start") with {:ok, %User{} = user} <- Actors.find_by_email(email), - actor <- Actors.register_bot_account(%{name: name, summary: summary}), - {:ok, %Bot{} = bot} <- Actors.create_bot(%{"type" => type, "source" => url, "actor_id" => actor.id, "user_id" => user.id}) do + actor <- Actors.register_bot_account(%{name: name, summary: summary}), + {:ok, %Bot{} = bot} <- + Actors.create_bot(%{ + "type" => type, + "source" => url, + "actor_id" => actor.id, + "user_id" => user.id + }) do bot - else - e -> Logger.error(inspect e) + e -> Logger.error(inspect(e)) end end end diff --git a/lib/service/activity_pub/activity_pub.ex b/lib/service/activity_pub/activity_pub.ex index 600a57710..1eaa3576b 100644 --- a/lib/service/activity_pub/activity_pub.ex +++ b/lib/service/activity_pub/activity_pub.ex @@ -27,12 +27,13 @@ defmodule Eventos.Service.ActivityPub do with map <- lazy_put_activity_defaults(map), :ok <- insert_full_object(map) do map = Map.put(map, "id", Ecto.UUID.generate()) + activity = %Activity{ - data: map, - local: local, - actor: map["actor"], - recipients: get_recipients(map) - } + data: map, + local: local, + actor: map["actor"], + recipients: get_recipients(map) + } # Notification.create_notifications(activity) # stream_out(activity) @@ -71,7 +72,7 @@ defmodule Eventos.Service.ActivityPub do {:ok, Events.get_event_by_url!(activity.data["object"]["id"])} else object = %Event{} -> {:ok, object} - e -> e + e -> e end end end @@ -89,12 +90,12 @@ defmodule Eventos.Service.ActivityPub do ), {:ok, activity} <- insert(create_data, local), :ok <- maybe_federate(activity) do - # {:ok, actor} <- Actors.increase_event_count(actor) do + # {:ok, actor} <- Actors.increase_event_count(actor) do {:ok, activity} else err -> Logger.debug("Something went wrong") - Logger.debug(inspect err) + Logger.debug(inspect(err)) end end @@ -114,12 +115,12 @@ defmodule Eventos.Service.ActivityPub do local = !(params[:local] == false) with data <- %{ - "to" => to, - "cc" => cc, - "type" => "Update", - "actor" => actor, - "object" => object - }, + "to" => to, + "cc" => cc, + "type" => "Update", + "actor" => actor, + "object" => object + }, {:ok, activity} <- insert(data, local), :ok <- maybe_federate(activity) do {:ok, activity} @@ -135,7 +136,6 @@ defmodule Eventos.Service.ActivityPub do end def delete(%Event{url: url, organizer_actor: actor} = event, local \\ true) do - data = %{ "type" => "Delete", "actor" => actor.url, @@ -145,14 +145,12 @@ defmodule Eventos.Service.ActivityPub do with Events.delete_event(event), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity) - do + :ok <- maybe_federate(activity) do {:ok, activity} end end def create_public_activities(%Actor{} = actor) do - end def make_actor_from_url(url) do @@ -161,12 +159,12 @@ defmodule Eventos.Service.ActivityPub do else e -> Logger.error("Failed to make actor from url") - Logger.error(inspect e) + Logger.error(inspect(e)) {:error, e} end end - @spec find_or_make_actor_from_nickname(String.t) :: tuple() + @spec find_or_make_actor_from_nickname(String.t()) :: tuple() def find_or_make_actor_from_nickname(nickname) do with %Actor{} = actor <- Actors.get_actor_by_name(nickname) do {:ok, actor} @@ -185,6 +183,7 @@ defmodule Eventos.Service.ActivityPub do def publish(actor, activity) do Logger.debug("Publishing an activity") + followers = if actor.followers_url in activity.recipients do {:ok, followers} = Actor.get_followers(actor) @@ -217,22 +216,26 @@ defmodule Eventos.Service.ActivityPub do signature = Eventos.Service.HTTPSignatures.sign(actor, %{host: host, "content-length": byte_size(json)}) - Logger.debug("signature") - Logger.debug(inspect signature) - {:ok, response} = HTTPoison.post( - inbox, - json, - [{"Content-Type", "application/activity+json"}, {"signature", signature}], - hackney: [pool: :default] - ) - Logger.debug(inspect response) + Logger.debug("signature") + Logger.debug(inspect(signature)) + + {:ok, response} = + HTTPoison.post( + inbox, + json, + [{"Content-Type", "application/activity+json"}, {"signature", signature}], + hackney: [pool: :default] + ) + + Logger.debug(inspect(response)) end def fetch_and_prepare_user_from_url(url) do Logger.debug("Fetching and preparing user from url") + with {:ok, %{status_code: 200, body: body}} <- - HTTPoison.get(url, [Accept: "application/activity+json"], [follow_redirect: true]), + HTTPoison.get(url, [Accept: "application/activity+json"], follow_redirect: true), {:ok, data} <- Jason.decode(body) do user_data_from_user_object(data) else @@ -241,17 +244,18 @@ defmodule Eventos.Service.ActivityPub do end def user_data_from_user_object(data) do - name = if String.trim(data["name"]) === "" do - data["preferredUsername"] - else - data["name"] - end + name = + if String.trim(data["name"]) === "" do + data["preferredUsername"] + else + data["name"] + end user_data = %{ url: data["id"], info: %{ "ap_enabled" => true, - "source_data" => data, + "source_data" => data }, avatar_url: data["icon"]["url"], banner_url: data["image"]["url"], @@ -267,38 +271,50 @@ defmodule Eventos.Service.ActivityPub do shared_inbox_url: data["endpoints"]["sharedInbox"], domain: URI.parse(data["id"]).host, manually_approves_followers: data["manuallyApprovesFollowers"], - type: data["type"], + type: data["type"] } Logger.debug("user_data_from_user_object") - Logger.debug(inspect user_data) + Logger.debug(inspect(user_data)) {:ok, user_data} end - @spec fetch_public_activities_for_actor(Actor.t, integer(), integer()) :: list() + @spec fetch_public_activities_for_actor(Actor.t(), integer(), integer()) :: list() def fetch_public_activities_for_actor(%Actor{} = actor, page \\ 1, limit \\ 10) do case actor.type do :Person -> {:ok, events, total} = Events.get_events_for_actor(actor, page, limit) - activities = Enum.map(events, fn event -> - {:ok, activity} = event_to_activity(event) - activity - end) + + activities = + Enum.map(events, fn event -> + {:ok, activity} = event_to_activity(event) + activity + end) + {activities, total} + :Service -> bot = Actors.get_bot_by_actor(actor) + case bot.type do "ics" -> {:ok, %HTTPoison.Response{body: body} = _resp} = HTTPoison.get(bot.source) - ical_events = body |> ExIcal.parse() |> ExIcal.by_range(DateTime.utc_now(), DateTime.utc_now() |> Timex.shift(years: 1)) - activities = ical_events - |> Enum.chunk_every(limit) - |> Enum.at(page - 1) - |> Enum.map(fn event -> - {:ok, activity} = ical_event_to_activity(event, actor, bot.source) - activity - end) + + ical_events = + body + |> ExIcal.parse() + |> ExIcal.by_range(DateTime.utc_now(), DateTime.utc_now() |> Timex.shift(years: 1)) + + activities = + ical_events + |> Enum.chunk_every(limit) + |> Enum.at(page - 1) + |> Enum.map(fn event -> + {:ok, activity} = ical_event_to_activity(event, actor, bot.source) + activity + end) + {activities, length(ical_events)} end end @@ -313,36 +329,42 @@ defmodule Eventos.Service.ActivityPub do } # Notification.create_notifications(activity) - #stream_out(activity) + # stream_out(activity) {:ok, activity} end defp ical_event_to_activity(%ExIcal.Event{} = ical_event, %Actor{} = actor, source) do # Logger.debug(inspect ical_event) # TODO : refactor me ! - category = if is_nil ical_event.categories do - nil - else - ical_category = ical_event.categories |> hd() |> String.downcase() - case ical_category |> Events.get_category_by_title() do - nil -> case Events.create_category(%{"title" => ical_category}) do - {:ok, %Category{} = category} -> category - _ -> nil - end - category -> category - end - end + category = + if is_nil(ical_event.categories) do + nil + else + ical_category = ical_event.categories |> hd() |> String.downcase() - {:ok, event} = Events.create_event(%{ - begins_on: ical_event.start, - ends_on: ical_event.end, - inserted_at: ical_event.stamp, - updated_at: ical_event.stamp, - description: ical_event.description |> sanitize_ical_event_strings, - title: ical_event.summary |> sanitize_ical_event_strings, - organizer_actor: actor, - category: category, - }) + case ical_category |> Events.get_category_by_title() do + nil -> + case Events.create_category(%{"title" => ical_category}) do + {:ok, %Category{} = category} -> category + _ -> nil + end + + category -> + category + end + end + + {:ok, event} = + Events.create_event(%{ + begins_on: ical_event.start, + ends_on: ical_event.end, + inserted_at: ical_event.stamp, + updated_at: ical_event.stamp, + description: ical_event.description |> sanitize_ical_event_strings, + title: ical_event.summary |> sanitize_ical_event_strings, + organizer_actor: actor, + category: category + }) event_to_activity(event, false) end diff --git a/lib/service/activity_pub/transmogrifier.ex b/lib/service/activity_pub/transmogrifier.ex index 430a19799..d4a848900 100644 --- a/lib/service/activity_pub/transmogrifier.ex +++ b/lib/service/activity_pub/transmogrifier.ex @@ -19,28 +19,28 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do |> Map.put("actor", object["attributedTo"]) |> fix_attachments |> fix_context - #|> fix_in_reply_to + # |> fix_in_reply_to |> fix_tag end -# def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) -# when not is_nil(in_reply_to_id) do -# case ActivityPub.fetch_object_from_id(in_reply_to_id) do -# {:ok, replied_object} -> -# activity = Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) -# -# object -# |> Map.put("inReplyTo", replied_object.data["id"]) -# |> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id) -# |> Map.put("inReplyToStatusId", activity.id) -# |> Map.put("conversation", replied_object.data["context"] || object["conversation"]) -# |> Map.put("context", replied_object.data["context"] || object["conversation"]) -# -# e -> -# Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}") -# object -# end -# end + # def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) + # when not is_nil(in_reply_to_id) do + # case ActivityPub.fetch_object_from_id(in_reply_to_id) do + # {:ok, replied_object} -> + # activity = Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) + # + # object + # |> Map.put("inReplyTo", replied_object.data["id"]) + # |> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id) + # |> Map.put("inReplyToStatusId", activity.id) + # |> Map.put("conversation", replied_object.data["context"] || object["conversation"]) + # |> Map.put("context", replied_object.data["context"] || object["conversation"]) + # + # e -> + # Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}") + # object + # end + # end def fix_in_reply_to(object), do: object @@ -78,6 +78,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do # - emoji def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do Logger.debug("Handle incoming to create notes") + with %Actor{} = actor <- Actor.get_or_fetch_by_url(data["actor"]) do Logger.debug("found actor") object = fix_object(data["object"]) @@ -100,32 +101,35 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do end end - def handle_incoming(%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data) do + def handle_incoming( + %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data + ) do with %Actor{} = followed <- Actors.get_actor_by_url(followed), %Actor{} = follower <- Actors.get_or_fetch_by_url(follower), {:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do ActivityPub.accept(%{to: [follower.url], actor: followed.url, object: data, local: true}) - #Actors.follow(follower, followed) + # Actors.follow(follower, followed) {:ok, activity} else _e -> :error end end -# -# def handle_incoming( -# %{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = data -# ) do -# with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), -# {:ok, object} <- -# get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), -# {:ok, activity, object} <- ActivityPub.like(actor, object, id, false) do -# {:ok, activity} -# else -# _e -> :error -# end -# end -# + + # + # def handle_incoming( + # %{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = data + # ) do + # with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), + # {:ok, object} <- + # get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), + # {:ok, activity, object} <- ActivityPub.like(actor, object, id, false) do + # {:ok, activity} + # else + # _e -> :error + # end + # end + # def handle_incoming( %{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data ) do @@ -138,63 +142,64 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do _e -> :error end end -# -# def handle_incoming( -# %{"type" => "Update", "object" => %{"type" => "Person"} = object, "actor" => actor_id} = -# data -# ) do -# with %User{ap_id: ^actor_id} = actor <- User.get_by_ap_id(object["id"]) do -# {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object) -# -# banner = new_user_data[:info]["banner"] -# -# update_data = -# new_user_data -# |> Map.take([:name, :bio, :avatar]) -# |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner})) -# -# actor -# |> User.upgrade_changeset(update_data) -# |> User.update_and_set_cache() -# -# ActivityPub.update(%{ -# local: false, -# to: data["to"] || [], -# cc: data["cc"] || [], -# object: object, -# actor: actor_id -# }) -# else -# e -> -# Logger.error(e) -# :error -# end -# end -# -# # TODO: Make secure. -# def handle_incoming( -# %{"type" => "Delete", "object" => object_id, "actor" => actor, "id" => id} = data -# ) do -# object_id = -# case object_id do -# %{"id" => id} -> id -# id -> id -# end -# -# with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), -# {:ok, object} <- -# get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), -# {:ok, activity} <- ActivityPub.delete(object, false) do -# {:ok, activity} -# else -# e -> :error -# end -# end -# -# # TODO -# # Accept -# # Undo -# + + # + # def handle_incoming( + # %{"type" => "Update", "object" => %{"type" => "Person"} = object, "actor" => actor_id} = + # data + # ) do + # with %User{ap_id: ^actor_id} = actor <- User.get_by_ap_id(object["id"]) do + # {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object) + # + # banner = new_user_data[:info]["banner"] + # + # update_data = + # new_user_data + # |> Map.take([:name, :bio, :avatar]) + # |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner})) + # + # actor + # |> User.upgrade_changeset(update_data) + # |> User.update_and_set_cache() + # + # ActivityPub.update(%{ + # local: false, + # to: data["to"] || [], + # cc: data["cc"] || [], + # object: object, + # actor: actor_id + # }) + # else + # e -> + # Logger.error(e) + # :error + # end + # end + # + # # TODO: Make secure. + # def handle_incoming( + # %{"type" => "Delete", "object" => object_id, "actor" => actor, "id" => id} = data + # ) do + # object_id = + # case object_id do + # %{"id" => id} -> id + # id -> id + # end + # + # with %User{} = actor <- User.get_or_fetch_by_ap_id(actor), + # {:ok, object} <- + # get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id), + # {:ok, activity} <- ActivityPub.delete(object, false) do + # {:ok, activity} + # else + # e -> :error + # end + # end + # + # # TODO + # # Accept + # # Undo + # def handle_incoming(_), do: :error def get_obj_helper(id) do @@ -211,16 +216,16 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do end def set_reply_to_uri(obj), do: obj -# -# # Prepares the object of an outgoing create activity. + # + # # Prepares the object of an outgoing create activity. def prepare_object(object) do object -# |> set_sensitive -# |> add_hashtags -# |> add_mention_tags -# |> add_emoji_tags + # |> set_sensitive + # |> add_hashtags + # |> add_mention_tags + # |> add_emoji_tags |> add_attributed_to -# |> prepare_attachments + # |> prepare_attachments |> set_conversation |> set_reply_to_uri end @@ -246,7 +251,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do def prepare_outgoing(%{"type" => type} = data) do data = data - #|> maybe_fix_object_url + # |> maybe_fix_object_url |> Map.put("@context", "https://www.w3.org/ns/activitystreams") {:ok, data} @@ -255,177 +260,180 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do def prepare_outgoing(%Event{} = event) do event = event - |> Map.from_struct - |> Map.drop([:"__meta__"]) + |> Map.from_struct() + |> Map.drop([:__meta__]) |> Map.put(:"@context", "https://www.w3.org/ns/activitystreams") |> prepare_object {:ok, event} end -# -# def maybe_fix_object_url(data) do -# if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do -# case ActivityPub.fetch_object_from_id(data["object"]) do -# {:ok, relative_object} -> -# if relative_object.data["external_url"] do -# data = -# data -# |> Map.put("object", relative_object.data["external_url"]) -# else -# data -# end -# -# e -> -# Logger.error("Couldn't fetch #{data["object"]} #{inspect(e)}") -# data -# end -# else -# data -# end -# end -# -# def add_mention_tags(object) do -# recipients = object["to"] ++ (object["cc"] || []) -# -# mentions = -# recipients -# |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) -# |> Enum.filter(& &1) -# |> Enum.map(fn user -> -# %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} -# end) -# -# tags = object["tag"] || [] -# -# object -# |> Map.put("tag", tags ++ mentions) -# end -# -# # TODO: we should probably send mtime instead of unix epoch time for updated -# def add_emoji_tags(object) do -# tags = object["tag"] || [] -# emoji = object["emoji"] || [] -# -# out = -# emoji -# |> Enum.map(fn {name, url} -> -# %{ -# "icon" => %{"url" => url, "type" => "Image"}, -# "name" => ":" <> name <> ":", -# "type" => "Emoji", -# "updated" => "1970-01-01T00:00:00Z", -# "id" => url -# } -# end) -# -# object -# |> Map.put("tag", tags ++ out) -# end -# + + # + # def maybe_fix_object_url(data) do + # if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do + # case ActivityPub.fetch_object_from_id(data["object"]) do + # {:ok, relative_object} -> + # if relative_object.data["external_url"] do + # data = + # data + # |> Map.put("object", relative_object.data["external_url"]) + # else + # data + # end + # + # e -> + # Logger.error("Couldn't fetch #{data["object"]} #{inspect(e)}") + # data + # end + # else + # data + # end + # end + # + # def add_mention_tags(object) do + # recipients = object["to"] ++ (object["cc"] || []) + # + # mentions = + # recipients + # |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) + # |> Enum.filter(& &1) + # |> Enum.map(fn user -> + # %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} + # end) + # + # tags = object["tag"] || [] + # + # object + # |> Map.put("tag", tags ++ mentions) + # end + # + # # TODO: we should probably send mtime instead of unix epoch time for updated + # def add_emoji_tags(object) do + # tags = object["tag"] || [] + # emoji = object["emoji"] || [] + # + # out = + # emoji + # |> Enum.map(fn {name, url} -> + # %{ + # "icon" => %{"url" => url, "type" => "Image"}, + # "name" => ":" <> name <> ":", + # "type" => "Emoji", + # "updated" => "1970-01-01T00:00:00Z", + # "id" => url + # } + # end) + # + # object + # |> Map.put("tag", tags ++ out) + # end + # def set_conversation(object) do Map.put(object, "conversation", object["context"]) end -# -# def set_sensitive(object) do -# tags = object["tag"] || [] -# Map.put(object, "sensitive", "nsfw" in tags) -# end -# + + # + # def set_sensitive(object) do + # tags = object["tag"] || [] + # Map.put(object, "sensitive", "nsfw" in tags) + # end + # def add_attributed_to(object) do attributed_to = object["attributedTo"] || object["actor"] object |> Map.put("attributedTo", attributed_to) end -# -# def prepare_attachments(object) do -# attachments = -# (object["attachment"] || []) -# |> Enum.map(fn data -> -# [%{"mediaType" => media_type, "href" => href} | _] = data["url"] -# %{"url" => href, "mediaType" => media_type, "name" => data["name"], "type" => "Document"} -# end) -# -# object -# |> Map.put("attachment", attachments) -# end -# -# defp user_upgrade_task(user) do -# old_follower_address = User.ap_followers(user) -# -# q = -# from( -# u in User, -# where: ^old_follower_address in u.following, -# update: [ -# set: [ -# following: -# fragment( -# "array_replace(?,?,?)", -# u.following, -# ^old_follower_address, -# ^user.follower_address -# ) -# ] -# ] -# ) -# -# Repo.update_all(q, []) -# -# maybe_retire_websub(user.ap_id) -# -# # Only do this for recent activties, don't go through the whole db. -# # Only look at the last 1000 activities. -# since = (Repo.aggregate(Activity, :max, :id) || 0) - 1_000 -# -# q = -# from( -# a in Activity, -# where: ^old_follower_address in a.recipients, -# where: a.id > ^since, -# update: [ -# set: [ -# recipients: -# fragment( -# "array_replace(?,?,?)", -# a.recipients, -# ^old_follower_address, -# ^user.follower_address -# ) -# ] -# ] -# ) -# -# Repo.update_all(q, []) -# end -# -# def upgrade_user_from_ap_id(ap_id, async \\ true) do -# with %User{local: false} = user <- User.get_by_ap_id(ap_id), -# {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do -# data = -# data -# |> Map.put(:info, Map.merge(user.info, data[:info])) -# -# already_ap = User.ap_enabled?(user) -# -# {:ok, user} = -# User.upgrade_changeset(user, data) -# |> Repo.update() -# -# if !already_ap do -# # This could potentially take a long time, do it in the background -# if async do -# Task.start(fn -> -# user_upgrade_task(user) -# end) -# else -# user_upgrade_task(user) -# end -# end -# -# {:ok, user} -# else -# e -> e -# end -# end -# + + # + # def prepare_attachments(object) do + # attachments = + # (object["attachment"] || []) + # |> Enum.map(fn data -> + # [%{"mediaType" => media_type, "href" => href} | _] = data["url"] + # %{"url" => href, "mediaType" => media_type, "name" => data["name"], "type" => "Document"} + # end) + # + # object + # |> Map.put("attachment", attachments) + # end + # + # defp user_upgrade_task(user) do + # old_follower_address = User.ap_followers(user) + # + # q = + # from( + # u in User, + # where: ^old_follower_address in u.following, + # update: [ + # set: [ + # following: + # fragment( + # "array_replace(?,?,?)", + # u.following, + # ^old_follower_address, + # ^user.follower_address + # ) + # ] + # ] + # ) + # + # Repo.update_all(q, []) + # + # maybe_retire_websub(user.ap_id) + # + # # Only do this for recent activties, don't go through the whole db. + # # Only look at the last 1000 activities. + # since = (Repo.aggregate(Activity, :max, :id) || 0) - 1_000 + # + # q = + # from( + # a in Activity, + # where: ^old_follower_address in a.recipients, + # where: a.id > ^since, + # update: [ + # set: [ + # recipients: + # fragment( + # "array_replace(?,?,?)", + # a.recipients, + # ^old_follower_address, + # ^user.follower_address + # ) + # ] + # ] + # ) + # + # Repo.update_all(q, []) + # end + # + # def upgrade_user_from_ap_id(ap_id, async \\ true) do + # with %User{local: false} = user <- User.get_by_ap_id(ap_id), + # {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do + # data = + # data + # |> Map.put(:info, Map.merge(user.info, data[:info])) + # + # already_ap = User.ap_enabled?(user) + # + # {:ok, user} = + # User.upgrade_changeset(user, data) + # |> Repo.update() + # + # if !already_ap do + # # This could potentially take a long time, do it in the background + # if async do + # Task.start(fn -> + # user_upgrade_task(user) + # end) + # else + # user_upgrade_task(user) + # end + # end + # + # {:ok, user} + # else + # e -> e + # end + # end + # end diff --git a/lib/service/activity_pub/utils.ex b/lib/service/activity_pub/utils.ex index ff245538f..799eb0c7b 100644 --- a/lib/service/activity_pub/utils.ex +++ b/lib/service/activity_pub/utils.ex @@ -44,28 +44,28 @@ defmodule Eventos.Service.ActivityPub.Utils do generate_id("contexts") end -# def generate_object_id do -# Helpers.o_status_url(Endpoint, :object, UUID.generate()) -# end + # def generate_object_id do + # Helpers.o_status_url(Endpoint, :object, UUID.generate()) + # end def generate_id(type) do "#{EventosWeb.Endpoint.url()}/#{type}/#{UUID.generate()}" end -# def create_context(context) do -# context = context || generate_id("contexts") -# changeset = Object.context_mapping(context) -# -# case Repo.insert(changeset) do -# {:ok, object} -> -# object -# -# # This should be solved by an upsert, but it seems ecto -# # has problems accessing the constraint inside the jsonb. -# {:error, _} -> -# Events.get_cached_by_url(context) -# end -# end + # def create_context(context) do + # context = context || generate_id("contexts") + # changeset = Object.context_mapping(context) + # + # case Repo.insert(changeset) do + # {:ok, object} -> + # object + # + # # This should be solved by an upsert, but it seems ecto + # # has problems accessing the constraint inside the jsonb. + # {:error, _} -> + # Events.get_cached_by_url(context) + # end + # end @doc """ Enqueues an activity for federation if it's local @@ -89,14 +89,14 @@ defmodule Eventos.Service.ActivityPub.Utils do also adds it to an included object """ def lazy_put_activity_defaults(map) do -# %{data: %{"id" => context}, id: context_id} = create_context(map["context"]) -# -# map = -# map -# |> Map.put_new_lazy("id", &generate_activity_id/0) -# |> Map.put_new_lazy("published", &make_date/0) -# |> Map.put_new("context", context) -# |> Map.put_new("context_id", context_id) + # %{data: %{"id" => context}, id: context_id} = create_context(map["context"]) + # + # map = + # map + # |> Map.put_new_lazy("id", &generate_activity_id/0) + # |> Map.put_new_lazy("published", &make_date/0) + # |> Map.put_new("context", context) + # |> Map.put_new("context_id", context_id) if is_map(map["object"]) do object = lazy_put_object_defaults(map["object"], map) @@ -111,7 +111,7 @@ defmodule Eventos.Service.ActivityPub.Utils do """ def lazy_put_object_defaults(map, activity \\ %{}) do map - #|> Map.put_new_lazy("id", &generate_object_id/0) + # |> Map.put_new_lazy("id", &generate_object_id/0) |> Map.put_new_lazy("published", &make_date/0) |> Map.put_new("context", activity["context"]) |> Map.put_new("context_id", activity["context_id"]) @@ -134,9 +134,16 @@ defmodule Eventos.Service.ActivityPub.Utils do when is_map(object_data) and type == "Note" do import Logger Logger.debug("insert full object") - Logger.debug(inspect object_data) + Logger.debug(inspect(object_data)) actor = Actors.get_actor_by_url(object_data["actor"]) - data = %{"text" => object_data["content"], "url" => object_data["id"], "actor_id" => actor.id, "in_reply_to_comment_id" => object_data["inReplyTo"]} + + data = %{ + "text" => object_data["content"], + "url" => object_data["id"], + "actor_id" => actor.id, + "in_reply_to_comment_id" => object_data["inReplyTo"] + } + with {:ok, _} <- Events.create_comment(data) do :ok end @@ -144,43 +151,43 @@ defmodule Eventos.Service.ActivityPub.Utils do def insert_full_object(_), do: :ok -# def update_object_in_activities(%{data: %{"id" => id}} = object) do -# # TODO -# # Update activities that already had this. Could be done in a seperate process. -# # Alternatively, just don't do this and fetch the current object each time. Most -# # could probably be taken from cache. -# relevant_activities = Activity.all_by_object_url(id) -# -# Enum.map(relevant_activities, fn activity -> -# new_activity_data = activity.data |> Map.put("object", object.data) -# changeset = Changeset.change(activity, data: new_activity_data) -# Repo.update(changeset) -# end) -# end + # def update_object_in_activities(%{data: %{"id" => id}} = object) do + # # TODO + # # Update activities that already had this. Could be done in a seperate process. + # # Alternatively, just don't do this and fetch the current object each time. Most + # # could probably be taken from cache. + # relevant_activities = Activity.all_by_object_url(id) + # + # Enum.map(relevant_activities, fn activity -> + # new_activity_data = activity.data |> Map.put("object", object.data) + # changeset = Changeset.change(activity, data: new_activity_data) + # Repo.update(changeset) + # end) + # end #### Like-related helpers -# @doc """ -# Returns an existing like if a user already liked an object -# """ -# def get_existing_like(actor, %{data: %{"id" => id}}) do -# query = -# from( -# activity in Activity, -# where: fragment("(?)->>'actor' = ?", activity.data, ^actor), -# # this is to use the index -# where: -# fragment( -# "coalesce((?)->'object'->>'id', (?)->>'object') = ?", -# activity.data, -# activity.data, -# ^id -# ), -# where: fragment("(?)->>'type' = 'Like'", activity.data) -# ) -# -# Repo.one(query) -# end + # @doc """ + # Returns an existing like if a user already liked an object + # """ + # def get_existing_like(actor, %{data: %{"id" => id}}) do + # query = + # from( + # activity in Activity, + # where: fragment("(?)->>'actor' = ?", activity.data, ^actor), + # # this is to use the index + # where: + # fragment( + # "coalesce((?)->'object'->>'id', (?)->>'object') = ?", + # activity.data, + # activity.data, + # ^id + # ), + # where: fragment("(?)->>'type' = 'Like'", activity.data) + # ) + # + # Repo.one(query) + # end def make_like_data(%Actor{url: url} = actor, %{data: %{"id" => id}} = object, activity_id) do data = %{ @@ -206,21 +213,21 @@ defmodule Eventos.Service.ActivityPub.Utils do end end -# def update_likes_in_object(likes, object) do -# update_element_in_object("like", likes, object) -# end -# -# def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do -# with likes <- [actor | object.data["likes"] || []] |> Enum.uniq() do -# update_likes_in_object(likes, object) -# end -# end -# -# def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do -# with likes <- (object.data["likes"] || []) |> List.delete(actor) do -# update_likes_in_object(likes, object) -# end -# end + # def update_likes_in_object(likes, object) do + # update_element_in_object("like", likes, object) + # end + # + # def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do + # with likes <- [actor | object.data["likes"] || []] |> Enum.uniq() do + # update_likes_in_object(likes, object) + # end + # end + # + # def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do + # with likes <- (object.data["likes"] || []) |> List.delete(actor) do + # update_likes_in_object(likes, object) + # end + # end #### Follow-related helpers @@ -239,22 +246,22 @@ defmodule Eventos.Service.ActivityPub.Utils do if activity_id, do: Map.put(data, "id", activity_id), else: data end -# def fetch_latest_follow(%Actor{url: follower_id}, %Actor{url: followed_id}) do -# query = -# from( -# activity in Activity, -# where: -# fragment( -# "? @> ?", -# activity.data, -# ^%{type: "Follow", actor: follower_id, object: followed_id} -# ), -# order_by: [desc: :id], -# limit: 1 -# ) -# -# Repo.one(query) -# end + # def fetch_latest_follow(%Actor{url: follower_id}, %Actor{url: followed_id}) do + # query = + # from( + # activity in Activity, + # where: + # fragment( + # "? @> ?", + # activity.data, + # ^%{type: "Follow", actor: follower_id, object: followed_id} + # ), + # order_by: [desc: :id], + # limit: 1 + # ) + # + # Repo.one(query) + # end #### Announce-related helpers diff --git a/lib/service/federator.ex b/lib/service/federator.ex index 0ac221229..e8b1b7843 100644 --- a/lib/service/federator.ex +++ b/lib/service/federator.ex @@ -17,7 +17,6 @@ defmodule Eventos.Service.Federator do end def start_link do - spawn(fn -> # 1 minute Process.sleep(1000 * 60) @@ -34,11 +33,10 @@ defmodule Eventos.Service.Federator do end def handle(:publish, activity) do - Logger.debug(inspect activity) + Logger.debug(inspect(activity)) Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end) with actor when not is_nil(actor) <- Actors.get_actor_by_url(activity.data["actor"]) do - Logger.info(fn -> "Sending #{activity.data["id"]} out via AP" end) ActivityPub.publish(actor, activity) end @@ -46,7 +44,7 @@ defmodule Eventos.Service.Federator do def handle(:incoming_ap_doc, params) do Logger.info("Handling incoming AP activity") - Logger.debug(inspect params) + Logger.debug(inspect(params)) with {:ok, _activity} <- Transmogrifier.handle_incoming(params) do else @@ -71,6 +69,7 @@ defmodule Eventos.Service.Federator do def enqueue(type, payload, priority \\ 1) do Logger.debug("enqueue") + if Mix.env() == :test do handle(type, payload) else @@ -105,9 +104,10 @@ defmodule Eventos.Service.Federator do end def handle_cast(m, state) do - Logger.error fn -> + Logger.error(fn -> "Unknown: #{inspect(m)}, #{inspect(state)}" - end + end) + {:noreply, state} end diff --git a/lib/service/http_signatures/http_signatures.ex b/lib/service/http_signatures/http_signatures.ex index 831fd6462..f722bbb85 100644 --- a/lib/service/http_signatures/http_signatures.ex +++ b/lib/service/http_signatures/http_signatures.ex @@ -28,12 +28,15 @@ defmodule Eventos.Service.HTTPSignatures do def validate(headers, signature, public_key) do sigstring = build_signing_string(headers, signature["headers"]) - Logger.debug fn -> + + Logger.debug(fn -> "Signature: #{signature["signature"]}" - end - Logger.debug fn -> + end) + + Logger.debug(fn -> "Sigstring: #{sigstring}" - end + end) + {:ok, sig} = Base.decode64(signature["signature"]) :public_key.verify(sigstring, :sha256, sig, public_key) end @@ -55,13 +58,13 @@ defmodule Eventos.Service.HTTPSignatures do public_key_code <- Actor.get_public_key_for_url(actor_id), [public_key] = :public_key.pem_decode(public_key_code), public_key = :public_key.pem_entry_decode(public_key) do - validate_conn(conn, public_key) + validate_conn(conn, public_key) end end else e -> Logger.debug("Could not found url for actor!") - Logger.debug(inspect e) + Logger.debug(inspect(e)) false end end diff --git a/lib/service/streamer.ex b/lib/service/streamer.ex index 5ffda4d0c..43c63df98 100644 --- a/lib/service/streamer.ex +++ b/lib/service/streamer.ex @@ -58,9 +58,11 @@ defmodule Eventos.Service.Streamer do sockets_for_topic = sockets[topic] || [] sockets_for_topic = Enum.uniq([socket | sockets_for_topic]) sockets = Map.put(sockets, topic, sockets_for_topic) - Logger.debug fn -> + + Logger.debug(fn -> "Got new conn for #{topic}" - end + end) + {:noreply, sockets} end @@ -69,9 +71,11 @@ defmodule Eventos.Service.Streamer do sockets_for_topic = sockets[topic] || [] sockets_for_topic = List.delete(sockets_for_topic, socket) sockets = Map.put(sockets, topic, sockets_for_topic) - Logger.debug fn -> + + Logger.debug(fn -> "Removed conn for #{topic}" - end + end) + {:noreply, sockets} end diff --git a/lib/service/web_finger/web_finger.ex b/lib/service/web_finger/web_finger.ex index c61807ad4..273f80999 100644 --- a/lib/service/web_finger/web_finger.ex +++ b/lib/service/web_finger/web_finger.ex @@ -52,7 +52,7 @@ defmodule Eventos.Service.WebFinger do "subject" => "acct:#{user.preferred_username}@#{EventosWeb.Endpoint.host() <> ":4001"}", "aliases" => [user.url], "links" => [ - %{"rel" => "self", "type" => "application/activity+json", "href" => user.url}, + %{"rel" => "self", "type" => "application/activity+json", "href" => user.url} ] } end @@ -63,10 +63,12 @@ defmodule Eventos.Service.WebFinger do case {link["type"], link["rel"]} do {"application/activity+json", "self"} -> Map.put(data, "url", link["href"]) + _ -> - Logger.debug fn -> + Logger.debug(fn -> "Unhandled type: #{inspect(link["type"])}" - end + end) + data end end) @@ -85,13 +87,19 @@ defmodule Eventos.Service.WebFinger do URI.parse(actor).host end - address = "http://#{domain}/.well-known/webfinger?resource=acct:#{actor}" + address = "http://#{domain}/.well-known/webfinger?resource=acct:#{actor}" - Logger.debug(inspect address) - with {:ok, %HTTPoison.Response{} = response} <- HTTPoison.get(address, [Accept: "application/json, application/activity+json, application/jrd+json"], follow_redirect: true), + Logger.debug(inspect(address)) + + with {:ok, %HTTPoison.Response{} = response} <- + HTTPoison.get( + address, + [Accept: "application/json, application/activity+json, application/jrd+json"], + follow_redirect: true + ), %{status_code: status_code, body: body} when status_code in 200..299 <- response do - {:ok, doc} = Jason.decode(body) - webfinger_from_json(doc) + {:ok, doc} = Jason.decode(body) + webfinger_from_json(doc) else e -> Logger.debug(fn -> "Couldn't finger #{actor}" end) diff --git a/mix.exs b/mix.exs index 163c8f93d..f81a25f92 100644 --- a/mix.exs +++ b/mix.exs @@ -37,6 +37,7 @@ defmodule Eventos.Mixfile do # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(:dev), do: ["lib", "test/support/factory.ex"] defp elixirc_paths(_), do: ["lib"] # Specifies your project dependencies. @@ -78,7 +79,6 @@ defmodule Eventos.Mixfile do # Dev and test dependencies {:phoenix_live_reload, "~> 1.0", only: :dev}, {:ex_machina, "~> 2.2", only: [:dev, :test]}, - {:credo, "~> 0.8", only: [:dev, :test], runtime: false}, {:excoveralls, "~> 0.8", only: :test}, {:ex_doc, "~> 0.16", only: :dev, runtime: false}, {:mix_test_watch, "~> 0.5", only: :dev, runtime: false}, diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 03a8cc0c4..752310971 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -10,27 +10,20 @@ # We recommend using the bang functions (`insert!`, `update!` # and so on) as they will fail if something goes wrong. -Eventos.Repo.delete_all Eventos.Accounts.User +import Eventos.Factory +# Insert an user +user = insert(:user) -{:ok, {privkey, pubkey}} = RsaEx.generate_keypair("4096") -account = Ecto.Changeset.change(%Eventos.Accounts.Account{}, %{ - username: "tcit", - description: "myaccount", - display_name: "Thomas Citharel", - domain: nil, - private_key: privkey, - public_key: pubkey, - uri: "", - url: "" -}) +# Insert an actor account +actor = insert(:actor, user: user) -user = Eventos.Accounts.User.registration_changeset(%Eventos.Accounts.User{}, %{ - email: "tcit@tcit.fr", - password: "tcittcit", - password_confirmation: "tcittcit" -}) +# Insert a second actor account for the same user +actor2 = insert(:actor, user: user) -account_with_user = Ecto.Changeset.put_assoc(account, :user, user) +# Make actor organize an event +event = insert(:event, organizer_actor: actor) + +# Insert a group +group = insert(:actor, type: :Group) -Eventos.Repo.insert!(account_with_user) diff --git a/test/eventos/actors/actors_test.exs b/test/eventos/actors/actors_test.exs index 550421819..f7e08b843 100644 --- a/test/eventos/actors/actors_test.exs +++ b/test/eventos/actors/actors_test.exs @@ -7,9 +7,36 @@ defmodule Eventos.ActorsTest do describe "actors" do alias Eventos.Actors.Actor - @valid_attrs %{summary: "some description", name: "some name", domain: "some domain", keys: "some keypair", suspended: true, uri: "some uri", url: "some url", preferred_username: "some username"} - @update_attrs %{summary: "some updated description", name: "some updated name", domain: "some updated domain", keys: "some updated keys", suspended: false, uri: "some updated uri", url: "some updated url", preferred_username: "some updated username"} - @invalid_attrs %{summary: nil, name: nil, domain: nil, keys: nil, suspended: nil, uri: nil, url: nil, preferred_username: nil} + @valid_attrs %{ + summary: "some description", + name: "some name", + domain: "some domain", + keys: "some keypair", + suspended: true, + uri: "some uri", + url: "some url", + preferred_username: "some username" + } + @update_attrs %{ + summary: "some updated description", + name: "some updated name", + domain: "some updated domain", + keys: "some updated keys", + suspended: false, + uri: "some updated uri", + url: "some updated url", + preferred_username: "some updated username" + } + @invalid_attrs %{ + summary: nil, + name: nil, + domain: nil, + keys: nil, + suspended: nil, + uri: nil, + url: nil, + preferred_username: nil + } def actor_fixture(attrs \\ %{}) do {:ok, actor} = @@ -77,7 +104,16 @@ defmodule Eventos.ActorsTest do describe "users" do alias Eventos.Actors.{User, Actor} - @actor_valid_attrs %{description: "some description", display_name: "some display_name", domain: "some domain", keys: "some keys", suspended: true, uri: "some uri", url: "some url", preferred_username: "some username"} + @actor_valid_attrs %{ + description: "some description", + display_name: "some display_name", + domain: "some domain", + keys: "some keys", + suspended: true, + uri: "some uri", + url: "some url", + preferred_username: "some username" + } @valid_attrs %{email: "foo@bar.tld", password: "some password", role: 42} @update_attrs %{email: "foo@fighters.tld", password: "some updated password", role: 43} @invalid_attrs %{email: nil, password_hash: nil, role: nil} @@ -138,12 +174,21 @@ defmodule Eventos.ActorsTest do end describe "groups" do - alias Eventos.Actors alias Eventos.Actors.Actor - @valid_attrs %{summary: "some description", suspended: true, preferred_username: "some-title", name: "Some Title"} - @update_attrs %{summary: "some updated description", suspended: false, preferred_username: "some-updated-title", name: "Some Updated Title"} + @valid_attrs %{ + summary: "some description", + suspended: true, + preferred_username: "some-title", + name: "Some Title" + } + @update_attrs %{ + summary: "some updated description", + suspended: false, + preferred_username: "some-updated-title", + name: "Some Updated Title" + } @invalid_attrs %{summary: nil, suspended: nil, preferred_username: nil, name: nil} test "create_group/1 with valid data creates a group" do @@ -184,9 +229,11 @@ defmodule Eventos.ActorsTest do end test "create_bot/1 with valid data creates a bot" do - attrs = @valid_attrs - |> Map.merge(%{actor_id: insert(:actor).id}) - |> Map.merge(%{user_id: insert(:user).id}) + attrs = + @valid_attrs + |> Map.merge(%{actor_id: insert(:actor).id}) + |> Map.merge(%{user_id: insert(:user).id}) + assert {:ok, %Bot{} = bot} = Actors.create_bot(attrs) assert bot.source == "some source" assert bot.type == "some type" diff --git a/test/eventos/addresses/addresses_test.exs b/test/eventos/addresses/addresses_test.exs index 0a86c2a4c..cf37b3e67 100644 --- a/test/eventos/addresses/addresses_test.exs +++ b/test/eventos/addresses/addresses_test.exs @@ -6,9 +6,36 @@ defmodule Eventos.AddressesTest do describe "addresses" do alias Eventos.Addresses.Address - @valid_attrs %{addressCountry: "some addressCountry", addressLocality: "some addressLocality", addressRegion: "some addressRegion", description: "some description", floor: "some floor", postalCode: "some postalCode", streetAddress: "some streetAddress", geom: %Geo.Point{coordinates: {10, -10}, srid: 4326}} - @update_attrs %{addressCountry: "some updated addressCountry", addressLocality: "some updated addressLocality", addressRegion: "some updated addressRegion", description: "some updated description", floor: "some updated floor", postalCode: "some updated postalCode", streetAddress: "some updated streetAddress", geom: %Geo.Point{coordinates: {20, -20}, srid: 4326}} - @invalid_attrs %{addressCountry: nil, addressLocality: nil, addressRegion: nil, description: nil, floor: nil, postalCode: nil, streetAddress: nil, geom: nil} + @valid_attrs %{ + addressCountry: "some addressCountry", + addressLocality: "some addressLocality", + addressRegion: "some addressRegion", + description: "some description", + floor: "some floor", + postalCode: "some postalCode", + streetAddress: "some streetAddress", + geom: %Geo.Point{coordinates: {10, -10}, srid: 4326} + } + @update_attrs %{ + addressCountry: "some updated addressCountry", + addressLocality: "some updated addressLocality", + addressRegion: "some updated addressRegion", + description: "some updated description", + floor: "some updated floor", + postalCode: "some updated postalCode", + streetAddress: "some updated streetAddress", + geom: %Geo.Point{coordinates: {20, -20}, srid: 4326} + } + @invalid_attrs %{ + addressCountry: nil, + addressLocality: nil, + addressRegion: nil, + description: nil, + floor: nil, + postalCode: nil, + streetAddress: nil, + geom: nil + } def address_fixture(attrs \\ %{}) do {:ok, address} = diff --git a/test/eventos/events/events_test.exs b/test/eventos/events/events_test.exs index abc2b3792..b455e1b19 100644 --- a/test/eventos/events/events_test.exs +++ b/test/eventos/events/events_test.exs @@ -6,7 +6,12 @@ defmodule Eventos.EventsTest do alias Eventos.Events alias Eventos.Actors - @event_valid_attrs %{begins_on: "2010-04-17 14:00:00.000000Z", description: "some description", ends_on: "2010-04-17 14:00:00.000000Z", title: "some title"} + @event_valid_attrs %{ + begins_on: "2010-04-17 14:00:00.000000Z", + description: "some description", + ends_on: "2010-04-17 14:00:00.000000Z", + title: "some title" + } def actor_fixture do insert(:actor) @@ -27,8 +32,18 @@ defmodule Eventos.EventsTest do describe "events" do alias Eventos.Events.Event - @valid_attrs %{begins_on: "2010-04-17 14:00:00.000000Z", description: "some description", ends_on: "2010-04-17 14:00:00.000000Z", title: "some title"} - @update_attrs %{begins_on: "2011-05-18 15:01:01.000000Z", description: "some updated description", ends_on: "2011-05-18 15:01:01.000000Z", title: "some updated title"} + @valid_attrs %{ + begins_on: "2010-04-17 14:00:00.000000Z", + description: "some description", + ends_on: "2010-04-17 14:00:00.000000Z", + title: "some title" + } + @update_attrs %{ + begins_on: "2011-05-18 15:01:01.000000Z", + description: "some updated description", + ends_on: "2011-05-18 15:01:01.000000Z", + title: "some updated title" + } @invalid_attrs %{begins_on: nil, description: nil, ends_on: nil, title: nil} test "list_events/0 returns all events" do @@ -45,11 +60,14 @@ defmodule Eventos.EventsTest do actor = actor_fixture() category = category_fixture() address = address_fixture() - valid_attrs = @event_valid_attrs + + valid_attrs = + @event_valid_attrs |> Map.put(:organizer_actor, actor) |> Map.put(:organizer_actor_id, actor.id) |> Map.put(:category_id, category.id) |> Map.put(:address_id, address.id) + assert {:ok, %Event{} = event} = Events.create_event(valid_attrs) assert event.begins_on == DateTime.from_naive!(~N[2010-04-17 14:00:00.000000Z], "Etc/UTC") assert event.description == "some description" @@ -93,7 +111,11 @@ defmodule Eventos.EventsTest do alias Eventos.Events.Category @valid_attrs %{description: "some description", picture: "some picture", title: "some title"} - @update_attrs %{description: "some updated description", picture: "some updated picture", title: "some updated title"} + @update_attrs %{ + description: "some updated description", + picture: "some updated picture", + title: "some updated title" + } @invalid_attrs %{description: nil, picture: nil, title: nil} test "list_categories/0 returns all categories" do @@ -216,6 +238,7 @@ defmodule Eventos.EventsTest do actor = actor_fixture() valid_attrs = Map.put(@valid_attrs, :event_id, event.id) valid_attrs = Map.put(valid_attrs, :actor_id, actor.id) + {:ok, participant} = attrs |> Enum.into(valid_attrs) @@ -229,10 +252,10 @@ defmodule Eventos.EventsTest do assert Events.list_participants() == [participant] end -# test "get_participant!/1 returns the participant with given id" do -# participant = participant_fixture() -# assert Events.get_participant!(participant.id) == participant -# end + # test "get_participant!/1 returns the participant with given id" do + # participant = participant_fixture() + # assert Events.get_participant!(participant.id) == participant + # end test "create_participant/1 with valid data creates a participant" do actor = actor_fixture() @@ -273,13 +296,41 @@ defmodule Eventos.EventsTest do describe "sessions" do alias Eventos.Events.Session - @valid_attrs %{audios_urls: "some audios_urls", language: "some language", long_abstract: "some long_abstract", short_abstract: "some short_abstract", slides_url: "some slides_url", subtitle: "some subtitle", title: "some title", videos_urls: "some videos_urls"} - @update_attrs %{audios_urls: "some updated audios_urls", language: "some updated language", long_abstract: "some updated long_abstract", short_abstract: "some updated short_abstract", slides_url: "some updated slides_url", subtitle: "some updated subtitle", title: "some updated title", videos_urls: "some updated videos_urls"} - @invalid_attrs %{audios_urls: nil, language: nil, long_abstract: nil, short_abstract: nil, slides_url: nil, subtitle: nil, title: nil, videos_urls: nil} + @valid_attrs %{ + audios_urls: "some audios_urls", + language: "some language", + long_abstract: "some long_abstract", + short_abstract: "some short_abstract", + slides_url: "some slides_url", + subtitle: "some subtitle", + title: "some title", + videos_urls: "some videos_urls" + } + @update_attrs %{ + audios_urls: "some updated audios_urls", + language: "some updated language", + long_abstract: "some updated long_abstract", + short_abstract: "some updated short_abstract", + slides_url: "some updated slides_url", + subtitle: "some updated subtitle", + title: "some updated title", + videos_urls: "some updated videos_urls" + } + @invalid_attrs %{ + audios_urls: nil, + language: nil, + long_abstract: nil, + short_abstract: nil, + slides_url: nil, + subtitle: nil, + title: nil, + videos_urls: nil + } def session_fixture(attrs \\ %{}) do event = event_fixture() valid_attrs = Map.put(@valid_attrs, :event_id, event.id) + {:ok, session} = attrs |> Enum.into(valid_attrs) @@ -352,12 +403,17 @@ defmodule Eventos.EventsTest do alias Eventos.Events.Track @valid_attrs %{color: "some color", description: "some description", name: "some name"} - @update_attrs %{color: "some updated color", description: "some updated description", name: "some updated name"} + @update_attrs %{ + color: "some updated color", + description: "some updated description", + name: "some updated name" + } @invalid_attrs %{color: nil, description: nil, name: nil} def track_fixture(attrs \\ %{}) do event = event_fixture() valid_attrs = Map.put(@valid_attrs, :event_id, event.id) + {:ok, track} = attrs |> Enum.into(valid_attrs) diff --git a/test/eventos/service/activitypub/activitypub_test.exs b/test/eventos/service/activitypub/activitypub_test.exs index f7656dc6f..300606001 100644 --- a/test/eventos/service/activitypub/activitypub_test.exs +++ b/test/eventos/service/activitypub/activitypub_test.exs @@ -1,5 +1,4 @@ defmodule Eventos.Service.Activitypub.ActivitypubTest do - use Eventos.DataCase import Eventos.Factory @@ -11,7 +10,8 @@ defmodule Eventos.Service.Activitypub.ActivitypubTest do describe "fetching actor from it's url" do test "returns an actor" do - assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"} = actor} = ActivityPub.make_actor_from_nickname("tcit@framapiaf.org") + assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"} = actor} = + ActivityPub.make_actor_from_nickname("tcit@framapiaf.org") end end diff --git a/test/eventos/service/web_finger/web_finger_test.exs b/test/eventos/service/web_finger/web_finger_test.exs index e22846120..919c3641f 100644 --- a/test/eventos/service/web_finger/web_finger_test.exs +++ b/test/eventos/service/web_finger/web_finger_test.exs @@ -17,6 +17,7 @@ defmodule Eventos.Service.WebFingerTest do {:ok, result} = WebFinger.webfinger("#{actor.preferred_username}@#{EventosWeb.Endpoint.host()}", "JSON") + assert is_map(result) end @@ -29,23 +30,29 @@ defmodule Eventos.Service.WebFingerTest do end describe "fingering" do - test "a mastodon actor" do actor = "tcit@social.tcit.fr" - assert {:ok, %{"subject" => "acct:" <> actor, "url" => "https://social.tcit.fr/users/tcit"}} = WebFinger.finger(actor) + assert {:ok, %{"subject" => "acct:" <> actor, "url" => "https://social.tcit.fr/users/tcit"}} = + WebFinger.finger(actor) end test "a pleroma actor" do actor = "@lain@pleroma.soykaf.com" - assert {:ok, %{"subject" => "acct:" <> actor, "url" => "https://pleroma.soykaf.com/users/lain"}} = WebFinger.finger(actor) + assert {:ok, + %{"subject" => "acct:" <> actor, "url" => "https://pleroma.soykaf.com/users/lain"}} = + WebFinger.finger(actor) end test "a peertube actor" do actor = "framasoft@framatube.org" - assert {:ok, %{"subject" => "acct:" <> actor, "url" => "https://framatube.org/accounts/framasoft"}} = WebFinger.finger(actor) + assert {:ok, + %{ + "subject" => "acct:" <> actor, + "url" => "https://framatube.org/accounts/framasoft" + }} = WebFinger.finger(actor) end test "a friendica actor" do diff --git a/test/eventos_web/controllers/activity_pub_controller_test.exs b/test/eventos_web/controllers/activity_pub_controller_test.exs index bf285e8f8..9a716ef3d 100644 --- a/test/eventos_web/controllers/activity_pub_controller_test.exs +++ b/test/eventos_web/controllers/activity_pub_controller_test.exs @@ -18,7 +18,7 @@ defmodule EventosWeb.ActivityPubControllerTest do actor = Actors.get_actor!(actor.id) assert json_response(conn, 200) == ActorView.render("actor.json", %{actor: actor}) - Logger.error(inspect ActorView.render("actor.json", %{actor: actor})) + Logger.error(inspect(ActorView.render("actor.json", %{actor: actor}))) end end @@ -32,106 +32,106 @@ defmodule EventosWeb.ActivityPubControllerTest do |> get("/events/#{event.uuid}") assert json_response(conn, 200) == ObjectView.render("event.json", %{event: event}) - Logger.error(inspect ObjectView.render("event.json", %{event: event})) + Logger.error(inspect(ObjectView.render("event.json", %{event: event}))) end end -# describe "/actors/:username/inbox" do -# test "it inserts an incoming activity into the database", %{conn: conn} do -# data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() -# -# conn = -# conn -# |> assign(:valid_signature, true) -# |> put_req_header("content-type", "application/activity+json") -# |> post("/inbox", data) -# -# assert "ok" == json_response(conn, 200) -# :timer.sleep(500) -# assert Activity.get_by_ap_id(data["id"]) -# end -# end + # describe "/actors/:username/inbox" do + # test "it inserts an incoming activity into the database", %{conn: conn} do + # data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + # + # conn = + # conn + # |> assign(:valid_signature, true) + # |> put_req_header("content-type", "application/activity+json") + # |> post("/inbox", data) + # + # assert "ok" == json_response(conn, 200) + # :timer.sleep(500) + # assert Activity.get_by_ap_id(data["id"]) + # end + # end -# describe "/actors/:nickname/followers" do -# test "it returns the followers in a collection", %{conn: conn} do -# user = insert(:user) -# user_two = insert(:user) -# User.follow(user, user_two) -# -# result = -# conn -# |> get("/users/#{user_two.nickname}/followers") -# |> json_response(200) -# -# assert result["first"]["orderedItems"] == [user.ap_id] -# end -# -# test "it works for more than 10 users", %{conn: conn} do -# user = insert(:user) -# -# Enum.each(1..15, fn _ -> -# other_user = insert(:user) -# User.follow(other_user, user) -# end) -# -# result = -# conn -# |> get("/users/#{user.nickname}/followers") -# |> json_response(200) -# -# assert length(result["first"]["orderedItems"]) == 10 -# assert result["first"]["totalItems"] == 15 -# assert result["totalItems"] == 15 -# -# result = -# conn -# |> get("/users/#{user.nickname}/followers?page=2") -# |> json_response(200) -# -# assert length(result["orderedItems"]) == 5 -# assert result["totalItems"] == 15 -# end -# end -# -# describe "/users/:nickname/following" do -# test "it returns the following in a collection", %{conn: conn} do -# user = insert(:user) -# user_two = insert(:user) -# User.follow(user, user_two) -# -# result = -# conn -# |> get("/users/#{user.nickname}/following") -# |> json_response(200) -# -# assert result["first"]["orderedItems"] == [user_two.ap_id] -# end -# -# test "it works for more than 10 users", %{conn: conn} do -# user = insert(:user) -# -# Enum.each(1..15, fn _ -> -# user = Repo.get(User, user.id) -# other_user = insert(:user) -# User.follow(user, other_user) -# end) -# -# result = -# conn -# |> get("/users/#{user.nickname}/following") -# |> json_response(200) -# -# assert length(result["first"]["orderedItems"]) == 10 -# assert result["first"]["totalItems"] == 15 -# assert result["totalItems"] == 15 -# -# result = -# conn -# |> get("/users/#{user.nickname}/following?page=2") -# |> json_response(200) -# -# assert length(result["orderedItems"]) == 5 -# assert result["totalItems"] == 15 -# end -# end + # describe "/actors/:nickname/followers" do + # test "it returns the followers in a collection", %{conn: conn} do + # user = insert(:user) + # user_two = insert(:user) + # User.follow(user, user_two) + # + # result = + # conn + # |> get("/users/#{user_two.nickname}/followers") + # |> json_response(200) + # + # assert result["first"]["orderedItems"] == [user.ap_id] + # end + # + # test "it works for more than 10 users", %{conn: conn} do + # user = insert(:user) + # + # Enum.each(1..15, fn _ -> + # other_user = insert(:user) + # User.follow(other_user, user) + # end) + # + # result = + # conn + # |> get("/users/#{user.nickname}/followers") + # |> json_response(200) + # + # assert length(result["first"]["orderedItems"]) == 10 + # assert result["first"]["totalItems"] == 15 + # assert result["totalItems"] == 15 + # + # result = + # conn + # |> get("/users/#{user.nickname}/followers?page=2") + # |> json_response(200) + # + # assert length(result["orderedItems"]) == 5 + # assert result["totalItems"] == 15 + # end + # end + # + # describe "/users/:nickname/following" do + # test "it returns the following in a collection", %{conn: conn} do + # user = insert(:user) + # user_two = insert(:user) + # User.follow(user, user_two) + # + # result = + # conn + # |> get("/users/#{user.nickname}/following") + # |> json_response(200) + # + # assert result["first"]["orderedItems"] == [user_two.ap_id] + # end + # + # test "it works for more than 10 users", %{conn: conn} do + # user = insert(:user) + # + # Enum.each(1..15, fn _ -> + # user = Repo.get(User, user.id) + # other_user = insert(:user) + # User.follow(user, other_user) + # end) + # + # result = + # conn + # |> get("/users/#{user.nickname}/following") + # |> json_response(200) + # + # assert length(result["first"]["orderedItems"]) == 10 + # assert result["first"]["totalItems"] == 15 + # assert result["totalItems"] == 15 + # + # result = + # conn + # |> get("/users/#{user.nickname}/following?page=2") + # |> json_response(200) + # + # assert length(result["orderedItems"]) == 5 + # assert result["totalItems"] == 15 + # end + # end end diff --git a/test/eventos_web/controllers/actor_controller_test.exs b/test/eventos_web/controllers/actor_controller_test.exs index f7e775d9d..7daed0bdc 100644 --- a/test/eventos_web/controllers/actor_controller_test.exs +++ b/test/eventos_web/controllers/actor_controller_test.exs @@ -15,11 +15,17 @@ defmodule EventosWeb.ActorControllerTest do entry = :public_key.pem_entry_encode(:RSAPrivateKey, key) pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing() - @create_attrs %{preferred_username: "otheridentity", summary: "This is my other identity", domain: nil, keys: pem, user: nil} + @create_attrs %{ + preferred_username: "otheridentity", + summary: "This is my other identity", + domain: nil, + keys: pem, + user: nil + } describe "index" do test "lists all actors", %{conn: conn, user: user, actor: actor} do - conn = get conn, actor_path(conn, :index) + conn = get(conn, actor_path(conn, :index)) assert hd(json_response(conn, 200)["data"])["username"] == actor.preferred_username end end @@ -27,32 +33,32 @@ defmodule EventosWeb.ActorControllerTest do describe "create actor" do test "from an existing user", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, actor_path(conn, :create), actor: @create_attrs + conn = post(conn, actor_path(conn, :create), actor: @create_attrs) assert json_response(conn, 201)["data"]["username"] == @create_attrs.preferred_username end end -### -# Not possible atm -### -# describe "delete actor" do -# setup [:create_actor] -# -# test "deletes own actor", %{conn: conn, user: user} do -# conn = auth_conn(conn, user) -# conn = delete conn, actor_path(conn, :delete, user.actor) -# assert response(conn, 204) -# assert_error_sent 404, fn -> -# get conn, actor_path(conn, :show, user.actor) -# end -# end -# -# test "deletes other actor", %{conn: conn, actor: actor, user: user} do -# conn = auth_conn(conn, user) -# conn = delete conn, actor_path(conn, :delete, actor) -# assert response(conn, 401) -# conn = get conn, actor_path(conn, :show, actor) -# assert response(conn, 200) -# end -# end + ### + # Not possible atm + ### + # describe "delete actor" do + # setup [:create_actor] + # + # test "deletes own actor", %{conn: conn, user: user} do + # conn = auth_conn(conn, user) + # conn = delete conn, actor_path(conn, :delete, user.actor) + # assert response(conn, 204) + # assert_error_sent 404, fn -> + # get conn, actor_path(conn, :show, user.actor) + # end + # end + # + # test "deletes other actor", %{conn: conn, actor: actor, user: user} do + # conn = auth_conn(conn, user) + # conn = delete conn, actor_path(conn, :delete, actor) + # assert response(conn, 401) + # conn = get conn, actor_path(conn, :show, actor) + # assert response(conn, 200) + # end + # end end diff --git a/test/eventos_web/controllers/address_controller_test.exs b/test/eventos_web/controllers/address_controller_test.exs index 7d058aa01..c2efc0f25 100644 --- a/test/eventos_web/controllers/address_controller_test.exs +++ b/test/eventos_web/controllers/address_controller_test.exs @@ -6,9 +6,36 @@ defmodule EventosWeb.AddressControllerTest do alias Eventos.Addresses alias Eventos.Addresses.Address - @create_attrs %{addressCountry: "some addressCountry", addressLocality: "some addressLocality", addressRegion: "some addressRegion", description: "some description", floor: "some floor", postalCode: "some postalCode", streetAddress: "some streetAddress", geom: %{type: :point, data: %{latitude: -20, longitude: 30}}} - @update_attrs %{addressCountry: "some updated addressCountry", addressLocality: "some updated addressLocality", addressRegion: "some updated addressRegion", description: "some updated description", floor: "some updated floor", postalCode: "some updated postalCode", streetAddress: "some updated streetAddress", geom: %{type: :point, data: %{latitude: -40, longitude: 40}}} - @invalid_attrs %{addressCountry: nil, addressLocality: nil, addressRegion: nil, description: nil, floor: nil, postalCode: nil, streetAddress: nil, geom: %{type: nil, data: %{latitude: nil, longitude: nil}}} + @create_attrs %{ + addressCountry: "some addressCountry", + addressLocality: "some addressLocality", + addressRegion: "some addressRegion", + description: "some description", + floor: "some floor", + postalCode: "some postalCode", + streetAddress: "some streetAddress", + geom: %{type: :point, data: %{latitude: -20, longitude: 30}} + } + @update_attrs %{ + addressCountry: "some updated addressCountry", + addressLocality: "some updated addressLocality", + addressRegion: "some updated addressRegion", + description: "some updated description", + floor: "some updated floor", + postalCode: "some updated postalCode", + streetAddress: "some updated streetAddress", + geom: %{type: :point, data: %{latitude: -40, longitude: 40}} + } + @invalid_attrs %{ + addressCountry: nil, + addressLocality: nil, + addressRegion: nil, + description: nil, + floor: nil, + postalCode: nil, + streetAddress: nil, + geom: %{type: nil, data: %{latitude: nil, longitude: nil}} + } def fixture(:address) do {:ok, address} = Addresses.create_address(@create_attrs) @@ -24,7 +51,7 @@ defmodule EventosWeb.AddressControllerTest do describe "index" do test "lists all addresses", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = get conn, address_path(conn, :index) + conn = get(conn, address_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -32,26 +59,30 @@ defmodule EventosWeb.AddressControllerTest do describe "create address" do test "renders address when data is valid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, address_path(conn, :create), address: @create_attrs + conn = post(conn, address_path(conn, :create), address: @create_attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, address_path(conn, :show, id) + conn = get(conn, address_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "addressCountry" => "some addressCountry", - "addressLocality" => "some addressLocality", - "addressRegion" => "some addressRegion", - "description" => "some description", - "floor" => "some floor", - "postalCode" => "some postalCode", - "streetAddress" => "some streetAddress", - "geom" => %{"data" => %{"latitude" => -20.0, "longitude" => 30.0}, "type" => "point"} - } + "id" => id, + "addressCountry" => "some addressCountry", + "addressLocality" => "some addressLocality", + "addressRegion" => "some addressRegion", + "description" => "some description", + "floor" => "some floor", + "postalCode" => "some postalCode", + "streetAddress" => "some streetAddress", + "geom" => %{ + "data" => %{"latitude" => -20.0, "longitude" => 30.0}, + "type" => "point" + } + } end test "renders errors when data is invalid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, address_path(conn, :create), address: @invalid_attrs + conn = post(conn, address_path(conn, :create), address: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -59,28 +90,36 @@ defmodule EventosWeb.AddressControllerTest do describe "update address" do setup [:create_address] - test "renders address when data is valid", %{conn: conn, address: %Address{id: id} = address, user: user} do + test "renders address when data is valid", %{ + conn: conn, + address: %Address{id: id} = address, + user: user + } do conn = auth_conn(conn, user) - conn = put conn, address_path(conn, :update, address), address: @update_attrs + conn = put(conn, address_path(conn, :update, address), address: @update_attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, address_path(conn, :show, id) + conn = get(conn, address_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "addressCountry" => "some updated addressCountry", - "addressLocality" => "some updated addressLocality", - "addressRegion" => "some updated addressRegion", - "description" => "some updated description", - "floor" => "some updated floor", - "postalCode" => "some updated postalCode", - "streetAddress" => "some updated streetAddress", - "geom" => %{"data" => %{"latitude" => -40.0, "longitude" => 40.0}, "type" => "point"} - } + "id" => id, + "addressCountry" => "some updated addressCountry", + "addressLocality" => "some updated addressLocality", + "addressRegion" => "some updated addressRegion", + "description" => "some updated description", + "floor" => "some updated floor", + "postalCode" => "some updated postalCode", + "streetAddress" => "some updated streetAddress", + "geom" => %{ + "data" => %{"latitude" => -40.0, "longitude" => 40.0}, + "type" => "point" + } + } end test "renders errors when data is invalid", %{conn: conn, address: address, user: user} do conn = auth_conn(conn, user) - conn = put conn, address_path(conn, :update, address), address: @invalid_attrs + conn = put(conn, address_path(conn, :update, address), address: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -90,11 +129,12 @@ defmodule EventosWeb.AddressControllerTest do test "deletes chosen address", %{conn: conn, address: address, user: user} do conn = auth_conn(conn, user) - conn = delete conn, address_path(conn, :delete, address) + conn = delete(conn, address_path(conn, :delete, address)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, address_path(conn, :show, address) - end + + assert_error_sent(404, fn -> + get(conn, address_path(conn, :show, address)) + end) end end diff --git a/test/eventos_web/controllers/bot_controller_test.exs b/test/eventos_web/controllers/bot_controller_test.exs index 3a184daff..c6dc88845 100644 --- a/test/eventos_web/controllers/bot_controller_test.exs +++ b/test/eventos_web/controllers/bot_controller_test.exs @@ -7,7 +7,11 @@ defmodule EventosWeb.BotControllerTest do alias Eventos.Actors.Bot @create_attrs %{source: "some source", type: "some type", name: "some name"} - @update_attrs %{source: "some updated source", type: "some updated type", name: "some updated name"} + @update_attrs %{ + source: "some updated source", + type: "some updated type", + name: "some updated name" + } @invalid_attrs %{source: nil, type: nil, name: nil} setup %{conn: conn} do @@ -18,7 +22,7 @@ defmodule EventosWeb.BotControllerTest do describe "index" do test "lists all bots", %{conn: conn} do - conn = get conn, bot_path(conn, :index) + conn = get(conn, bot_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -26,19 +30,21 @@ defmodule EventosWeb.BotControllerTest do describe "create bot" do test "renders bot when data is valid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, bot_path(conn, :create), bot: @create_attrs + conn = post(conn, bot_path(conn, :create), bot: @create_attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, bot_path(conn, :show, id) + conn = get(conn, bot_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "source" => "some source", - "type" => "some type"} + "id" => id, + "source" => "some source", + "type" => "some type" + } end test "renders errors when data is invalid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, bot_path(conn, :create), bot: @invalid_attrs + conn = post(conn, bot_path(conn, :create), bot: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -48,19 +54,21 @@ defmodule EventosWeb.BotControllerTest do test "renders bot when data is valid", %{conn: conn, bot: %Bot{id: id} = bot, user: user} do conn = auth_conn(conn, user) - conn = put conn, bot_path(conn, :update, bot), bot: @update_attrs + conn = put(conn, bot_path(conn, :update, bot), bot: @update_attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, bot_path(conn, :show, id) + conn = get(conn, bot_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "source" => "some updated source", - "type" => "some updated type"} + "id" => id, + "source" => "some updated source", + "type" => "some updated type" + } end test "renders errors when data is invalid", %{conn: conn, bot: bot, user: user} do conn = auth_conn(conn, user) - conn = put conn, bot_path(conn, :update, bot), bot: @invalid_attrs + conn = put(conn, bot_path(conn, :update, bot), bot: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -70,11 +78,12 @@ defmodule EventosWeb.BotControllerTest do test "deletes chosen bot", %{conn: conn, bot: bot, user: user} do conn = auth_conn(conn, user) - conn = delete conn, bot_path(conn, :delete, bot) + conn = delete(conn, bot_path(conn, :delete, bot)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, bot_path(conn, :show, bot) - end + + assert_error_sent(404, fn -> + get(conn, bot_path(conn, :show, bot)) + end) end end diff --git a/test/eventos_web/controllers/category_controller_test.exs b/test/eventos_web/controllers/category_controller_test.exs index 3ce7b559d..b823685db 100644 --- a/test/eventos_web/controllers/category_controller_test.exs +++ b/test/eventos_web/controllers/category_controller_test.exs @@ -7,7 +7,11 @@ defmodule EventosWeb.CategoryControllerTest do alias Eventos.Events.Category @create_attrs %{description: "some description", picture: "some picture", title: "some title"} - @update_attrs %{description: "some updated description", picture: "some updated picture", title: "some updated title"} + @update_attrs %{ + description: "some updated description", + picture: "some updated picture", + title: "some updated title" + } @invalid_attrs %{description: nil, picture: nil, title: nil} def fixture(:category) do @@ -23,7 +27,7 @@ defmodule EventosWeb.CategoryControllerTest do describe "index" do test "lists all categories", %{conn: conn} do - conn = get conn, category_path(conn, :index) + conn = get(conn, category_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -31,20 +35,22 @@ defmodule EventosWeb.CategoryControllerTest do describe "create category" do test "renders category when data is valid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, category_path(conn, :create), category: @create_attrs + conn = post(conn, category_path(conn, :create), category: @create_attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, category_path(conn, :show, id) + conn = get(conn, category_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "description" => "some description", - "picture" => "some picture", - "title" => "some title"} + "id" => id, + "description" => "some description", + "picture" => "some picture", + "title" => "some title" + } end test "renders errors when data is invalid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, category_path(conn, :create), category: @invalid_attrs + conn = post(conn, category_path(conn, :create), category: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -52,22 +58,28 @@ defmodule EventosWeb.CategoryControllerTest do describe "update category" do setup [:create_category] - test "renders category when data is valid", %{conn: conn, category: %Category{id: id} = category, user: user} do + test "renders category when data is valid", %{ + conn: conn, + category: %Category{id: id} = category, + user: user + } do conn = auth_conn(conn, user) - conn = put conn, category_path(conn, :update, category), category: @update_attrs + conn = put(conn, category_path(conn, :update, category), category: @update_attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, category_path(conn, :show, id) + conn = get(conn, category_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "description" => "some updated description", - "picture" => "some updated picture", - "title" => "some updated title"} + "id" => id, + "description" => "some updated description", + "picture" => "some updated picture", + "title" => "some updated title" + } end test "renders errors when data is invalid", %{conn: conn, category: category, user: user} do conn = auth_conn(conn, user) - conn = put conn, category_path(conn, :update, category), category: @invalid_attrs + conn = put(conn, category_path(conn, :update, category), category: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -77,11 +89,12 @@ defmodule EventosWeb.CategoryControllerTest do test "deletes chosen category", %{conn: conn, category: category, user: user} do conn = auth_conn(conn, user) - conn = delete conn, category_path(conn, :delete, category) + conn = delete(conn, category_path(conn, :delete, category)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, category_path(conn, :show, category) - end + + assert_error_sent(404, fn -> + get(conn, category_path(conn, :show, category)) + end) end end diff --git a/test/eventos_web/controllers/comment_controller_test.exs b/test/eventos_web/controllers/comment_controller_test.exs index 1c3def0aa..c0509c08b 100644 --- a/test/eventos_web/controllers/comment_controller_test.exs +++ b/test/eventos_web/controllers/comment_controller_test.exs @@ -20,21 +20,22 @@ defmodule EventosWeb.CommentControllerTest do test "renders comment when data is valid", %{conn: conn, user: user, actor: actor} do conn = auth_conn(conn, user) attrs = Map.merge(@create_attrs, %{actor_id: actor.id}) - conn = post conn, comment_path(conn, :create), comment: attrs + conn = post(conn, comment_path(conn, :create), comment: attrs) assert %{"uuid" => uuid, "id" => id} = json_response(conn, 201)["data"] - conn = get conn, comment_path(conn, :show, uuid) + conn = get(conn, comment_path(conn, :show, uuid)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "text" => "some text", - "uuid" => uuid, - "url" => "#{EventosWeb.Endpoint.url()}/comments/#{uuid}" - } + "id" => id, + "text" => "some text", + "uuid" => uuid, + "url" => "#{EventosWeb.Endpoint.url()}/comments/#{uuid}" + } end test "renders errors when data is invalid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, comment_path(conn, :create), comment: @invalid_attrs + conn = post(conn, comment_path(conn, :create), comment: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -42,24 +43,30 @@ defmodule EventosWeb.CommentControllerTest do describe "update comment" do setup [:create_comment] - test "renders comment when data is valid", %{conn: conn, comment: %Comment{id: id, uuid: uuid} = comment, user: user, actor: actor} do + test "renders comment when data is valid", %{ + conn: conn, + comment: %Comment{id: id, uuid: uuid} = comment, + user: user, + actor: actor + } do conn = auth_conn(conn, user) attrs = Map.merge(@update_attrs, %{actor_id: actor.id}) - conn = put conn, comment_path(conn, :update, uuid), comment: attrs + conn = put(conn, comment_path(conn, :update, uuid), comment: attrs) assert %{"uuid" => uuid, "id" => id} = json_response(conn, 200)["data"] - conn = get conn, comment_path(conn, :show, uuid) + conn = get(conn, comment_path(conn, :show, uuid)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "text" => "some updated text", - "uuid" => uuid, - "url" => "#{EventosWeb.Endpoint.url()}/comments/#{uuid}" - } + "id" => id, + "text" => "some updated text", + "uuid" => uuid, + "url" => "#{EventosWeb.Endpoint.url()}/comments/#{uuid}" + } end test "renders errors when data is invalid", %{conn: conn, comment: comment, user: user} do conn = auth_conn(conn, user) - conn = put conn, comment_path(conn, :update, comment.uuid), comment: @invalid_attrs + conn = put(conn, comment_path(conn, :update, comment.uuid), comment: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -67,13 +74,18 @@ defmodule EventosWeb.CommentControllerTest do describe "delete comment" do setup [:create_comment] - test "deletes chosen comment", %{conn: conn, comment: %Comment{uuid: uuid} = comment, user: user} do + test "deletes chosen comment", %{ + conn: conn, + comment: %Comment{uuid: uuid} = comment, + user: user + } do conn = auth_conn(conn, user) - conn = delete conn, comment_path(conn, :delete, uuid) + conn = delete(conn, comment_path(conn, :delete, uuid)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, comment_path(conn, :show, uuid) - end + + assert_error_sent(404, fn -> + get(conn, comment_path(conn, :show, uuid)) + end) end end diff --git a/test/eventos_web/controllers/event_controller_test.exs b/test/eventos_web/controllers/event_controller_test.exs index 7d98ede83..a4fbc3620 100644 --- a/test/eventos_web/controllers/event_controller_test.exs +++ b/test/eventos_web/controllers/event_controller_test.exs @@ -6,10 +6,29 @@ defmodule EventosWeb.EventControllerTest do alias Eventos.Events.Event alias Eventos.Export.ICalendar - @create_attrs %{begins_on: "2010-04-17 14:00:00.000000Z", description: "some description", ends_on: "2010-04-17 14:00:00.000000Z", title: "some title"} - @update_attrs %{begins_on: "2011-05-18 15:01:01.000000Z", description: "some updated description", ends_on: "2011-05-18 15:01:01.000000Z", title: "some updated title"} + @create_attrs %{ + begins_on: "2010-04-17 14:00:00.000000Z", + description: "some description", + ends_on: "2010-04-17 14:00:00.000000Z", + title: "some title" + } + @update_attrs %{ + begins_on: "2011-05-18 15:01:01.000000Z", + description: "some updated description", + ends_on: "2011-05-18 15:01:01.000000Z", + title: "some updated title" + } @invalid_attrs %{begins_on: nil, description: nil, ends_on: nil, title: nil, address_id: nil} - @create_address_attrs %{"addressCountry" => "some addressCountry", "addressLocality" => "some addressLocality", "addressRegion" => "some addressRegion", "description" => "some description", "floor" => "some floor", "postalCode" => "some postalCode", "streetAddress" => "some streetAddress", "geom" => %{"type" => :point, "data" => %{"latitude" => -20, "longitude" => 30}}} + @create_address_attrs %{ + "addressCountry" => "some addressCountry", + "addressLocality" => "some addressLocality", + "addressRegion" => "some addressRegion", + "description" => "some description", + "floor" => "some floor", + "postalCode" => "some postalCode", + "streetAddress" => "some streetAddress", + "geom" => %{"type" => :point, "data" => %{"latitude" => -20, "longitude" => 30}} + } def fixture(:event) do {:ok, event} = Events.create_event(@create_attrs) @@ -28,7 +47,7 @@ defmodule EventosWeb.EventControllerTest do describe "index" do test "lists all events", %{conn: conn} do - conn = get conn, event_path(conn, :index) + conn = get(conn, event_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -41,25 +60,37 @@ defmodule EventosWeb.EventControllerTest do category = insert(:category) attrs = Map.put(attrs, :category_id, category.id) conn = auth_conn(conn, user) - conn = post conn, event_path(conn, :create), event: attrs + conn = post(conn, event_path(conn, :create), event: attrs) assert %{"uuid" => uuid} = json_response(conn, 201)["data"] - conn = get conn, event_path(conn, :show, uuid) + conn = get(conn, event_path(conn, :show, uuid)) + assert %{ - "begins_on" => "2010-04-17T14:00:00Z", - "description" => "some description", - "ends_on" => "2010-04-17T14:00:00Z", - "title" => "some title", - "participants" => [], - "physical_address" => %{"addressCountry" => "some addressCountry", "addressLocality" => "some addressLocality", "addressRegion" => "some addressRegion", "floor" => "some floor", "geom" => %{"data" => %{"latitude" => -20.0, "longitude" => 30.0}, "type" => "point"}, "postalCode" => "some postalCode", "streetAddress" => "some streetAddress"} - } = json_response(conn, 200)["data"] + "begins_on" => "2010-04-17T14:00:00Z", + "description" => "some description", + "ends_on" => "2010-04-17T14:00:00Z", + "title" => "some title", + "participants" => [], + "physical_address" => %{ + "addressCountry" => "some addressCountry", + "addressLocality" => "some addressLocality", + "addressRegion" => "some addressRegion", + "floor" => "some floor", + "geom" => %{ + "data" => %{"latitude" => -20.0, "longitude" => 30.0}, + "type" => "point" + }, + "postalCode" => "some postalCode", + "streetAddress" => "some streetAddress" + } + } = json_response(conn, 200)["data"] end test "renders errors when data is invalid", %{conn: conn, user: user, actor: actor} do conn = auth_conn(conn, user) attrs = Map.put(@invalid_attrs, :organizer_actor_id, actor.id) attrs = Map.put(attrs, :address, @create_address_attrs) - conn = post conn, event_path(conn, :create), event: attrs + conn = post(conn, event_path(conn, :create), event: attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -67,9 +98,13 @@ defmodule EventosWeb.EventControllerTest do describe "export event" do setup [:create_event] - test "renders ics export of event", %{conn: conn, event: %Event{uuid: uuid} = event, user: user} do + test "renders ics export of event", %{ + conn: conn, + event: %Event{uuid: uuid} = event, + user: user + } do conn = auth_conn(conn, user) - conn = get conn, event_path(conn, :export_to_ics, uuid) + conn = get(conn, event_path(conn, :export_to_ics, uuid)) exported_event = ICalendar.export_event(event) assert exported_event == response(conn, 200) end @@ -78,29 +113,51 @@ defmodule EventosWeb.EventControllerTest do describe "update event" do setup [:create_event] - test "renders event when data is valid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user, actor: actor} do + test "renders event when data is valid", %{ + conn: conn, + event: %Event{uuid: uuid} = event, + user: user, + actor: actor + } do conn = auth_conn(conn, user) address = address_fixture() attrs = Map.put(@update_attrs, :organizer_actor_id, actor.id) attrs = Map.put(attrs, :address_id, address.id) - conn = put conn, event_path(conn, :update, uuid), event: attrs + conn = put(conn, event_path(conn, :update, uuid), event: attrs) assert %{"uuid" => uuid} = json_response(conn, 200)["data"] - conn = get conn, event_path(conn, :show, uuid) + conn = get(conn, event_path(conn, :show, uuid)) + assert %{ "begins_on" => "2011-05-18T15:01:01Z", "description" => "some updated description", "ends_on" => "2011-05-18T15:01:01Z", "title" => "some updated title", "participants" => [], - "physical_address" => %{"addressCountry" => "My Country", "addressLocality" => "My Locality", "addressRegion" => "My Region", "floor" => "Myfloor", "geom" => %{"data" => %{"latitude" => 30.0, "longitude" => -90.0}, "type" => "point"}, "postalCode" => "My Postal Code", "streetAddress" => "My Street Address"} + "physical_address" => %{ + "addressCountry" => "My Country", + "addressLocality" => "My Locality", + "addressRegion" => "My Region", + "floor" => "Myfloor", + "geom" => %{ + "data" => %{"latitude" => 30.0, "longitude" => -90.0}, + "type" => "point" + }, + "postalCode" => "My Postal Code", + "streetAddress" => "My Street Address" + } } = json_response(conn, 200)["data"] end - test "renders errors when data is invalid", %{conn: conn, event: %Event{uuid: uuid} = event, user: user, actor: actor} do + test "renders errors when data is invalid", %{ + conn: conn, + event: %Event{uuid: uuid} = event, + user: user, + actor: actor + } do conn = auth_conn(conn, user) attrs = Map.put(@invalid_attrs, :organizer_actor_id, actor.id) - conn = put conn, event_path(conn, :update, uuid), event: attrs + conn = put(conn, event_path(conn, :update, uuid), event: attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -110,9 +167,9 @@ defmodule EventosWeb.EventControllerTest do test "deletes chosen event", %{conn: conn, event: %Event{uuid: uuid} = event, user: user} do conn = auth_conn(conn, user) - conn = delete conn, event_path(conn, :delete, uuid) + conn = delete(conn, event_path(conn, :delete, uuid)) assert response(conn, 204) - conn = get conn, event_path(conn, :show, uuid) + conn = get(conn, event_path(conn, :show, uuid)) assert response(conn, 404) end end diff --git a/test/eventos_web/controllers/page_controller_test.exs b/test/eventos_web/controllers/page_controller_test.exs index 2f5950590..9662307b1 100644 --- a/test/eventos_web/controllers/page_controller_test.exs +++ b/test/eventos_web/controllers/page_controller_test.exs @@ -2,7 +2,7 @@ defmodule EventosWeb.PageControllerTest do use EventosWeb.ConnCase test "GET /", %{conn: conn} do - conn = get conn, "/" + conn = get(conn, "/") assert html_response(conn, 200) end end diff --git a/test/eventos_web/controllers/session_controller_test.exs b/test/eventos_web/controllers/session_controller_test.exs index 7cbdeaad4..743393d91 100644 --- a/test/eventos_web/controllers/session_controller_test.exs +++ b/test/eventos_web/controllers/session_controller_test.exs @@ -6,9 +6,36 @@ defmodule EventosWeb.SessionControllerTest do alias Eventos.Events alias Eventos.Events.Session - @create_attrs %{audios_urls: "some audios_urls", language: "some language", long_abstract: "some long_abstract", short_abstract: "some short_abstract", slides_url: "some slides_url", subtitle: "some subtitle", title: "some title", videos_urls: "some videos_urls"} - @update_attrs %{audios_urls: "some updated audios_urls", language: "some updated language", long_abstract: "some updated long_abstract", short_abstract: "some updated short_abstract", slides_url: "some updated slides_url", subtitle: "some updated subtitle", title: "some updated title", videos_urls: "some updated videos_urls"} - @invalid_attrs %{audios_urls: nil, language: nil, long_abstract: nil, short_abstract: nil, slides_url: nil, subtitle: nil, title: nil, videos_urls: nil} + @create_attrs %{ + audios_urls: "some audios_urls", + language: "some language", + long_abstract: "some long_abstract", + short_abstract: "some short_abstract", + slides_url: "some slides_url", + subtitle: "some subtitle", + title: "some title", + videos_urls: "some videos_urls" + } + @update_attrs %{ + audios_urls: "some updated audios_urls", + language: "some updated language", + long_abstract: "some updated long_abstract", + short_abstract: "some updated short_abstract", + slides_url: "some updated slides_url", + subtitle: "some updated subtitle", + title: "some updated title", + videos_urls: "some updated videos_urls" + } + @invalid_attrs %{ + audios_urls: nil, + language: nil, + long_abstract: nil, + short_abstract: nil, + slides_url: nil, + subtitle: nil, + title: nil, + videos_urls: nil + } def fixture(:session) do {:ok, session} = Events.create_session(@create_attrs) @@ -24,7 +51,7 @@ defmodule EventosWeb.SessionControllerTest do describe "index" do test "lists all sessions", %{conn: conn} do - conn = get conn, session_path(conn, :index) + conn = get(conn, session_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -34,29 +61,31 @@ defmodule EventosWeb.SessionControllerTest do conn = auth_conn(conn, user) event_id = event.id attrs = Map.put(@create_attrs, :event_id, event_id) - conn = post conn, session_path(conn, :create), session: attrs + conn = post(conn, session_path(conn, :create), session: attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, session_path(conn, :show_sessions_for_event, event.uuid) + conn = get(conn, session_path(conn, :show_sessions_for_event, event.uuid)) assert hd(json_response(conn, 200)["data"])["id"] == id - conn = get conn, session_path(conn, :show, id) + conn = get(conn, session_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "audios_urls" => "some audios_urls", - "language" => "some language", - "long_abstract" => "some long_abstract", - "short_abstract" => "some short_abstract", - "slides_url" => "some slides_url", - "subtitle" => "some subtitle", - "title" => "some title", - "videos_urls" => "some videos_urls"} + "id" => id, + "audios_urls" => "some audios_urls", + "language" => "some language", + "long_abstract" => "some long_abstract", + "short_abstract" => "some short_abstract", + "slides_url" => "some slides_url", + "subtitle" => "some subtitle", + "title" => "some title", + "videos_urls" => "some videos_urls" + } end test "renders errors when data is invalid", %{conn: conn, user: user, event: event} do conn = auth_conn(conn, user) attrs = Map.put(@invalid_attrs, :event_id, event.id) - conn = post conn, session_path(conn, :create), session: attrs + conn = post(conn, session_path(conn, :create), session: attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -64,28 +93,35 @@ defmodule EventosWeb.SessionControllerTest do describe "update session" do setup [:create_session] - test "renders session when data is valid", %{conn: conn, session: %Session{id: id} = session, user: user, event: event} do + test "renders session when data is valid", %{ + conn: conn, + session: %Session{id: id} = session, + user: user, + event: event + } do conn = auth_conn(conn, user) attrs = Map.put(@update_attrs, :event_id, event.id) - conn = patch conn, session_path(conn, :update, session), session: attrs + conn = patch(conn, session_path(conn, :update, session), session: attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, session_path(conn, :show, id) + conn = get(conn, session_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "audios_urls" => "some updated audios_urls", - "language" => "some updated language", - "long_abstract" => "some updated long_abstract", - "short_abstract" => "some updated short_abstract", - "slides_url" => "some updated slides_url", - "subtitle" => "some updated subtitle", - "title" => "some updated title", - "videos_urls" => "some updated videos_urls"} + "id" => id, + "audios_urls" => "some updated audios_urls", + "language" => "some updated language", + "long_abstract" => "some updated long_abstract", + "short_abstract" => "some updated short_abstract", + "slides_url" => "some updated slides_url", + "subtitle" => "some updated subtitle", + "title" => "some updated title", + "videos_urls" => "some updated videos_urls" + } end test "renders errors when data is invalid", %{conn: conn, session: session, user: user} do conn = auth_conn(conn, user) - conn = patch conn, session_path(conn, :update, session), session: @invalid_attrs + conn = patch(conn, session_path(conn, :update, session), session: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -95,11 +131,12 @@ defmodule EventosWeb.SessionControllerTest do test "deletes chosen session", %{conn: conn, session: session, user: user} do conn = auth_conn(conn, user) - conn = delete conn, session_path(conn, :delete, session) + conn = delete(conn, session_path(conn, :delete, session)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, session_path(conn, :show, session) - end + + assert_error_sent(404, fn -> + get(conn, session_path(conn, :show, session)) + end) end end diff --git a/test/eventos_web/controllers/tag_controller_test.exs b/test/eventos_web/controllers/tag_controller_test.exs index fb746762e..8bae81c72 100644 --- a/test/eventos_web/controllers/tag_controller_test.exs +++ b/test/eventos_web/controllers/tag_controller_test.exs @@ -23,7 +23,7 @@ defmodule EventosWeb.TagControllerTest do describe "index" do test "lists all tags", %{conn: conn} do - conn = get conn, tag_path(conn, :index) + conn = get(conn, tag_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -31,18 +31,16 @@ defmodule EventosWeb.TagControllerTest do describe "create tag" do test "renders tag when data is valid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, tag_path(conn, :create), tag: @create_attrs + conn = post(conn, tag_path(conn, :create), tag: @create_attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, tag_path(conn, :show, id) - assert json_response(conn, 200)["data"] == %{ - "id" => id, - "title" => "some title"} + conn = get(conn, tag_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{"id" => id, "title" => "some title"} end test "renders errors when data is invalid", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = post conn, tag_path(conn, :create), tag: @invalid_attrs + conn = post(conn, tag_path(conn, :create), tag: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -52,18 +50,16 @@ defmodule EventosWeb.TagControllerTest do test "renders tag when data is valid", %{conn: conn, tag: %Tag{id: id} = tag, user: user} do conn = auth_conn(conn, user) - conn = put conn, tag_path(conn, :update, tag), tag: @update_attrs + conn = put(conn, tag_path(conn, :update, tag), tag: @update_attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, tag_path(conn, :show, id) - assert json_response(conn, 200)["data"] == %{ - "id" => id, - "title" => "some updated title"} + conn = get(conn, tag_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{"id" => id, "title" => "some updated title"} end test "renders errors when data is invalid", %{conn: conn, tag: tag, user: user} do conn = auth_conn(conn, user) - conn = put conn, tag_path(conn, :update, tag), tag: @invalid_attrs + conn = put(conn, tag_path(conn, :update, tag), tag: @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -73,11 +69,12 @@ defmodule EventosWeb.TagControllerTest do test "deletes chosen tag", %{conn: conn, tag: tag, user: user} do conn = auth_conn(conn, user) - conn = delete conn, tag_path(conn, :delete, tag) + conn = delete(conn, tag_path(conn, :delete, tag)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, tag_path(conn, :show, tag) - end + + assert_error_sent(404, fn -> + get(conn, tag_path(conn, :show, tag)) + end) end end diff --git a/test/eventos_web/controllers/track_controller_test.exs b/test/eventos_web/controllers/track_controller_test.exs index aeb011d78..d79426547 100644 --- a/test/eventos_web/controllers/track_controller_test.exs +++ b/test/eventos_web/controllers/track_controller_test.exs @@ -7,7 +7,11 @@ defmodule EventosWeb.TrackControllerTest do alias Eventos.Events.Track @create_attrs %{color: "some color", description: "some description", name: "some name"} - @update_attrs %{color: "some updated color", description: "some updated description", name: "some updated name"} + @update_attrs %{ + color: "some updated color", + description: "some updated description", + name: "some updated name" + } @invalid_attrs %{color: nil, description: nil, name: nil} def fixture(:track) do @@ -24,7 +28,7 @@ defmodule EventosWeb.TrackControllerTest do describe "index" do test "lists all tracks", %{conn: conn} do - conn = get conn, track_path(conn, :index) + conn = get(conn, track_path(conn, :index)) assert json_response(conn, 200)["data"] == [] end end @@ -33,21 +37,23 @@ defmodule EventosWeb.TrackControllerTest do test "renders track when data is valid", %{conn: conn, user: user, event: event} do conn = auth_conn(conn, user) attrs = Map.put(@create_attrs, :event_id, event.id) - conn = post conn, track_path(conn, :create), track: attrs + conn = post(conn, track_path(conn, :create), track: attrs) assert %{"id" => id} = json_response(conn, 201)["data"] - conn = get conn, track_path(conn, :show, id) + conn = get(conn, track_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "color" => "some color", - "description" => "some description", - "name" => "some name"} + "id" => id, + "color" => "some color", + "description" => "some description", + "name" => "some name" + } end test "renders errors when data is invalid", %{conn: conn, user: user, event: event} do conn = auth_conn(conn, user) attrs = Map.put(@invalid_attrs, :event_id, event.id) - conn = post conn, track_path(conn, :create), track: attrs + conn = post(conn, track_path(conn, :create), track: attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -55,24 +61,36 @@ defmodule EventosWeb.TrackControllerTest do describe "update track" do setup [:create_track] - test "renders track when data is valid", %{conn: conn, track: %Track{id: id} = track, user: user, event: event} do + test "renders track when data is valid", %{ + conn: conn, + track: %Track{id: id} = track, + user: user, + event: event + } do conn = auth_conn(conn, user) attrs = Map.put(@update_attrs, :event_id, event.id) - conn = put conn, track_path(conn, :update, track), track: attrs + conn = put(conn, track_path(conn, :update, track), track: attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] - conn = get conn, track_path(conn, :show, id) + conn = get(conn, track_path(conn, :show, id)) + assert json_response(conn, 200)["data"] == %{ - "id" => id, - "color" => "some updated color", - "description" => "some updated description", - "name" => "some updated name"} + "id" => id, + "color" => "some updated color", + "description" => "some updated description", + "name" => "some updated name" + } end - test "renders errors when data is invalid", %{conn: conn, track: track, user: user, event: event} do + test "renders errors when data is invalid", %{ + conn: conn, + track: track, + user: user, + event: event + } do conn = auth_conn(conn, user) attrs = Map.put(@invalid_attrs, :event_id, event.id) - conn = put conn, track_path(conn, :update, track), track: attrs + conn = put(conn, track_path(conn, :update, track), track: attrs) assert json_response(conn, 422)["errors"] != %{} end end @@ -82,11 +100,12 @@ defmodule EventosWeb.TrackControllerTest do test "deletes chosen track", %{conn: conn, track: track, user: user} do conn = auth_conn(conn, user) - conn = delete conn, track_path(conn, :delete, track) + conn = delete(conn, track_path(conn, :delete, track)) assert response(conn, 204) - assert_error_sent 404, fn -> - get conn, track_path(conn, :show, track) - end + + assert_error_sent(404, fn -> + get(conn, track_path(conn, :show, track)) + end) end end diff --git a/test/eventos_web/controllers/user_controller_test.exs b/test/eventos_web/controllers/user_controller_test.exs index 0886ecf3c..be75411f9 100644 --- a/test/eventos_web/controllers/user_controller_test.exs +++ b/test/eventos_web/controllers/user_controller_test.exs @@ -24,58 +24,63 @@ defmodule EventosWeb.UserControllerTest do describe "index" do test "lists all users", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = get conn, user_path(conn, :index) + conn = get(conn, user_path(conn, :index)) assert hd(json_response(conn, 200)["data"])["id"] == user.id end end describe "create user" do test "renders user when data is valid", %{conn: conn} do - conn = post conn, user_path(conn, :create), @create_attrs + conn = post(conn, user_path(conn, :create), @create_attrs) assert %{"email" => "foo@bar.tld"} = json_response(conn, 201) end test "renders errors when data is invalid", %{conn: conn} do - conn = post conn, user_path(conn, :create), @invalid_attrs + conn = post(conn, user_path(conn, :create), @invalid_attrs) assert json_response(conn, 422)["errors"] != %{} end test "renders user with avatar when email is valid", %{conn: conn} do - attrs = %{email: "contact@framasoft.org", password: "some password_hash", username: "framasoft"} - conn = post conn, user_path(conn, :create), attrs + attrs = %{ + email: "contact@framasoft.org", + password: "some password_hash", + username: "framasoft" + } + + conn = post(conn, user_path(conn, :create), attrs) assert %{"email" => "contact@framasoft.org"} = json_response(conn, 201) end end -# describe "update user" do -# setup [:create_user] -# -# test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user} do -# conn = auth_conn(conn, user) -# conn = put conn, user_path(conn, :update, user), user: @update_attrs -# assert %{"id" => ^id} = json_response(conn, 200)["data"] -# -# conn = get conn, user_path(conn, :show, id) -# assert json_response(conn, 200)["data"] == %{ -# "id" => id, -# "email" => "some updated email", -# "password_hash" => "some updated password_hash", -# "role" => 43} -# end -# -# test "renders errors when data is invalid", %{conn: conn, user: user} do -# conn = auth_conn(conn, user) -# conn = put conn, user_path(conn, :update, user), user: @invalid_attrs -# assert json_response(conn, 422)["errors"] != %{} -# end -# end + # describe "update user" do + # setup [:create_user] + # + # test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user} do + # conn = auth_conn(conn, user) + # conn = put conn, user_path(conn, :update, user), user: @update_attrs + # assert %{"id" => ^id} = json_response(conn, 200)["data"] + # + # conn = get conn, user_path(conn, :show, id) + # assert json_response(conn, 200)["data"] == %{ + # "id" => id, + # "email" => "some updated email", + # "password_hash" => "some updated password_hash", + # "role" => 43} + # end + # + # test "renders errors when data is invalid", %{conn: conn, user: user} do + # conn = auth_conn(conn, user) + # conn = put conn, user_path(conn, :update, user), user: @invalid_attrs + # assert json_response(conn, 422)["errors"] != %{} + # end + # end describe "delete user" do setup [:create_user] test "deletes chosen user", %{conn: conn, user: user} do conn = auth_conn(conn, user) - conn = delete conn, user_path(conn, :delete, user) + conn = delete(conn, user_path(conn, :delete, user)) assert response(conn, 204) end end diff --git a/test/eventos_web/views/error_view_test.exs b/test/eventos_web/views/error_view_test.exs index c0c60c238..78a4fe7b1 100644 --- a/test/eventos_web/views/error_view_test.exs +++ b/test/eventos_web/views/error_view_test.exs @@ -5,17 +5,14 @@ defmodule EventosWeb.ErrorViewTest do import Phoenix.View test "renders 404.html" do - assert render_to_string(EventosWeb.ErrorView, "404.html", []) == - "Page not found" + assert render_to_string(EventosWeb.ErrorView, "404.html", []) == "Page not found" end test "render 500.html" do - assert render_to_string(EventosWeb.ErrorView, "500.html", []) == - "Internal server error" + assert render_to_string(EventosWeb.ErrorView, "500.html", []) == "Internal server error" end test "render any other" do - assert render_to_string(EventosWeb.ErrorView, "505.html", []) == - "Internal server error" + assert render_to_string(EventosWeb.ErrorView, "505.html", []) == "Internal server error" end end diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex index 6de21cbf6..0508a0e7a 100644 --- a/test/support/channel_case.ex +++ b/test/support/channel_case.ex @@ -25,13 +25,13 @@ defmodule EventosWeb.ChannelCase do end end - setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(Eventos.Repo) + unless tags[:async] do Ecto.Adapters.SQL.Sandbox.mode(Eventos.Repo, {:shared, self()}) end + :ok end - end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 0723cb3da..8faa5c440 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -26,6 +26,7 @@ defmodule EventosWeb.ConnCase do def auth_conn(%Plug.Conn{} = conn, %Eventos.Actors.User{} = user) do {:ok, token, _claims} = EventosWeb.Guardian.encode_and_sign(user) + conn |> Plug.Conn.put_req_header("authorization", "Bearer #{token}") |> Plug.Conn.put_req_header("accept", "application/json") @@ -33,13 +34,13 @@ defmodule EventosWeb.ConnCase do end end - setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(Eventos.Repo) + unless tags[:async] do Ecto.Adapters.SQL.Sandbox.mode(Eventos.Repo, {:shared, self()}) end + {:ok, conn: Phoenix.ConnTest.build_conn()} end - end diff --git a/test/support/factory.ex b/test/support/factory.ex index d707ecac4..1cce9cd09 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -9,7 +9,7 @@ defmodule Eventos.Factory do %Eventos.Actors.User{ password_hash: "Jane Smith", email: sequence(:email, &"email-#{&1}@example.com"), - role: 0, + role: 0 } end @@ -18,14 +18,14 @@ defmodule Eventos.Factory do entry = :public_key.pem_entry_encode(:RSAPrivateKey, key) pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing() - preferred_username = sequence("thomas") + %Eventos.Actors.Actor{ preferred_username: preferred_username, domain: nil, keys: pem, url: EventosWeb.Endpoint.url() <> "/@#{preferred_username}", - user: nil, + user: nil } end @@ -54,7 +54,7 @@ defmodule Eventos.Factory do text: "My Comment", actor: build(:actor), event: build(:event), - uuid: Ecto.UUID.generate(), + uuid: Ecto.UUID.generate() } end @@ -75,9 +75,9 @@ defmodule Eventos.Factory do def session_factory do %Eventos.Events.Session{ - title: sequence("MySession"), - event: build(:event), - track: build(:track) + title: sequence("MySession"), + event: build(:event), + track: build(:track) } end @@ -93,7 +93,14 @@ defmodule Eventos.Factory do source: "https://mysource.tld/feed.ics", type: "ics", user: build(:user), - actor: build(:actor), + actor: build(:actor) + } + end + + def member_factory do + %Eventos.Actors.Member{ + parent: build(:actor), + actor: build(:actor) } end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 998eeef5b..e37ba04e2 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,5 +1,5 @@ {:ok, _} = Application.ensure_all_started(:ex_machina) -ExUnit.configure formatters: [ExUnit.CLIFormatter, ExUnitNotifier] +ExUnit.configure(formatters: [ExUnit.CLIFormatter, ExUnitNotifier]) ExUnit.start()