diff --git a/config/dev.exs b/config/dev.exs index 3c90c9d3..824b6e88 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -57,7 +57,6 @@ config :mobilizon, Mobilizon.Mailer, adapter: Bamboo.LocalAdapter # Configure your database config :mobilizon, Mobilizon.Repo, - adapter: Ecto.Adapters.Postgres, types: Mobilizon.PostgresTypes, username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon", password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon", diff --git a/config/prod.exs b/config/prod.exs index 5820f0f7..3cea69df 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -28,7 +28,6 @@ config :mobilizon, MobilizonWeb.Endpoint, # Configure your database config :mobilizon, Mobilizon.Repo, - adapter: Ecto.Adapters.Postgres, types: Mobilizon.PostgresTypes, username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon", password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon", diff --git a/config/test.exs b/config/test.exs index c6aee32d..c906f42e 100644 --- a/config/test.exs +++ b/config/test.exs @@ -20,7 +20,6 @@ config :logger, # Configure your database config :mobilizon, Mobilizon.Repo, - adapter: Ecto.Adapters.Postgres, types: Mobilizon.PostgresTypes, username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon", password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon", diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 084f4be6..9118899c 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -579,7 +579,7 @@ defmodule Mobilizon.Actors do """ def authenticate(%{user: user, password: password}) do # Does password match the one stored in the database? - case Comeonin.Argon2.checkpw(password, user.password_hash) do + case Argon2.verify_pass(password, user.password_hash) do true -> # Yes, create and return the token MobilizonWeb.Guardian.encode_and_sign(user) diff --git a/lib/mobilizon/actors/service/activation.ex b/lib/mobilizon/actors/service/activation.ex index b94e6501..250d1634 100644 --- a/lib/mobilizon/actors/service/activation.ex +++ b/lib/mobilizon/actors/service/activation.ex @@ -12,7 +12,7 @@ defmodule Mobilizon.Actors.Service.Activation do with %User{} = user <- Actors.get_user_by_activation_token(token), {:ok, %User{} = user} <- Actors.update_user(user, %{ - "confirmed_at" => DateTime.utc_now(), + "confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second), "confirmation_sent_at" => nil, "confirmation_token" => nil }) do @@ -26,7 +26,10 @@ defmodule Mobilizon.Actors.Service.Activation do def resend_confirmation_email(%User{} = user, locale \\ "en") do with :ok <- Tools.we_can_send_email(user, :confirmation_sent_at), - {:ok, user} <- Actors.update_user(user, %{"confirmation_sent_at" => DateTime.utc_now()}) do + {:ok, user} <- + Actors.update_user(user, %{ + "confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second) + }) do send_confirmation_email(user, locale) Logger.info("Sent confirmation email again to #{user.email}") {:ok, user.email} diff --git a/lib/mobilizon/actors/service/reset_password.ex b/lib/mobilizon/actors/service/reset_password.ex index cd5fe478..f6604fba 100644 --- a/lib/mobilizon/actors/service/reset_password.ex +++ b/lib/mobilizon/actors/service/reset_password.ex @@ -43,7 +43,7 @@ defmodule Mobilizon.Actors.Service.ResetPassword do Repo.update( User.send_password_reset_changeset(user, %{ "reset_password_token" => Tools.random_string(30), - "reset_password_sent_at" => DateTime.utc_now() + "reset_password_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second) }) ) do mail = diff --git a/lib/mobilizon/actors/service/tools.ex b/lib/mobilizon/actors/service/tools.ex index 39ff2a0f..2383cd7e 100644 --- a/lib/mobilizon/actors/service/tools.ex +++ b/lib/mobilizon/actors/service/tools.ex @@ -11,7 +11,10 @@ defmodule Mobilizon.Actors.Service.Tools do :ok _ -> - case Timex.before?(Timex.shift(Map.get(user, key), hours: 1), DateTime.utc_now()) do + case Timex.before?( + Timex.shift(Map.get(user, key), hours: 1), + DateTime.utc_now() |> DateTime.truncate(:second) + ) do true -> :ok diff --git a/lib/mobilizon/actors/user.ex b/lib/mobilizon/actors/user.ex index da36a354..78058169 100644 --- a/lib/mobilizon/actors/user.ex +++ b/lib/mobilizon/actors/user.ex @@ -89,7 +89,12 @@ defmodule Mobilizon.Actors.User 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()) + + put_change( + changeset, + :confirmation_sent_at, + DateTime.utc_now() |> DateTime.truncate(:second) + ) _ -> changeset @@ -122,7 +127,7 @@ defmodule Mobilizon.Actors.User do put_change( changeset, :password_hash, - Comeonin.Argon2.hashpwsalt(password) + Argon2.hash_pwd_salt(password) ) _ -> diff --git a/lib/mobilizon/events/event.ex b/lib/mobilizon/events/event.ex index d795f40c..98a82876 100644 --- a/lib/mobilizon/events/event.ex +++ b/lib/mobilizon/events/event.ex @@ -32,16 +32,16 @@ defmodule Mobilizon.Events.Event do schema "events" do field(:url, :string) field(:local, :boolean, default: true) - field(:begins_on, Timex.Ecto.DateTimeWithTimezone) + field(:begins_on, :utc_datetime) field(:description, :string) - field(:ends_on, Timex.Ecto.DateTimeWithTimezone) + field(:ends_on, :utc_datetime) field(:title, :string) field(:status, Mobilizon.Events.EventStatusEnum, default: :confirmed) field(:visibility, Mobilizon.Events.EventVisibilityEnum, default: :public) field(:join_options, Mobilizon.Events.JoinOptionsEnum, default: :free) field(:thumbnail, :string) field(:large_image, :string) - field(:publish_at, Timex.Ecto.DateTimeWithTimezone) + field(:publish_at, :utc_datetime) field(:uuid, Ecto.UUID, default: Ecto.UUID.generate()) field(:online_address, :string) field(:phone_address, :string) diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index e0c9bc13..ae81caf7 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -458,8 +458,32 @@ defmodule Mobilizon.Events do [%Tag{}, ...] """ - def list_tags do - Repo.all(Tag) + def list_tags(page \\ nil, limit \\ nil) do + Repo.all( + Tag + |> paginate(page, limit) + ) + end + + @doc """ + Returns the list of tags for an event. + + ## Examples + + iex> list_tags_for_event(id) + [%Participant{}, ...] + + """ + def list_tags_for_event(id, page \\ nil, limit \\ nil) do + Repo.all( + from( + t in Tag, + join: e in "events_tags", + on: t.id == e.tag_id, + where: e.event_id == ^id + ) + |> paginate(page, limit) + ) end @doc """ @@ -543,6 +567,85 @@ defmodule Mobilizon.Events do Tag.changeset(tag, %{}) end + alias Mobilizon.Events.TagRelation + + @doc """ + Create a relation between two tags + """ + def create_tag_relation(attrs \\ {}) do + %TagRelation{} + |> TagRelation.changeset(attrs) + |> Repo.insert(conflict_target: [:tag_id, :link_id], on_conflict: [inc: [weight: 1]]) + end + + @doc """ + Remove a tag relation + """ + def delete_tag_relation(%TagRelation{} = tag_relation) do + Repo.delete(tag_relation) + end + + @doc """ + Returns whether two tags are linked or not + """ + def are_tags_linked(%Tag{id: tag1_id}, %Tag{id: tag2_id}) do + case from(tr in TagRelation, + where: tr.tag_id == ^min(tag1_id, tag2_id) and tr.link_id == ^max(tag1_id, tag2_id) + ) + |> Repo.one() do + %TagRelation{} -> true + _ -> false + end + end + + @doc """ + Returns the tags neighbors for a given tag + + We can't rely on the single many_to_many relation since we also want tags that link to our tag, not just tags linked by this one + + The SQL query looks like this: + ```sql + SELECT * FROM tags t + RIGHT JOIN ( + SELECT weight, link_id AS id + FROM tag_relations t2 + WHERE tag_id = 1 + UNION ALL + SELECT tag_id AS id, weight + FROM tag_relations t2 + WHERE link_id = 1 + ) tr + ON t.id = tr.id + ORDER BY tr.weight + DESC; + ``` + """ + def tag_neighbors(%Tag{id: id}, relation_minimum \\ 1, limit \\ 10) do + query2 = + from(tr in TagRelation, + select: %{id: tr.tag_id, weight: tr.weight}, + where: tr.link_id == ^id + ) + + query = + from(tr in TagRelation, + select: %{id: tr.link_id, weight: tr.weight}, + union_all: ^query2, + where: tr.tag_id == ^id + ) + + final_query = + from(t in Tag, + right_join: q in subquery(query), + on: [id: t.id], + where: q.weight >= ^relation_minimum, + limit: ^limit, + order_by: [desc: q.weight] + ) + + Repo.all(final_query) + end + alias Mobilizon.Events.Participant @doc """ diff --git a/lib/mobilizon/events/session.ex b/lib/mobilizon/events/session.ex index 178670f2..5f03ec00 100644 --- a/lib/mobilizon/events/session.ex +++ b/lib/mobilizon/events/session.ex @@ -15,8 +15,8 @@ defmodule Mobilizon.Events.Session do field(:subtitle, :string) field(:title, :string) field(:videos_urls, :string) - field(:begins_on, Timex.Ecto.DateTimeWithTimezone) - field(:ends_on, Timex.Ecto.DateTimeWithTimezone) + field(:begins_on, :utc_datetime) + field(:ends_on, :utc_datetime) belongs_to(:event, Event) belongs_to(:track, Track) diff --git a/lib/mobilizon/events/tag.ex b/lib/mobilizon/events/tag.ex index 79ac2b52..fafcfe15 100644 --- a/lib/mobilizon/events/tag.ex +++ b/lib/mobilizon/events/tag.ex @@ -39,10 +39,12 @@ defmodule Mobilizon.Events.Tag do import Ecto.Changeset alias Mobilizon.Events.Tag alias Mobilizon.Events.Tag.TitleSlug + alias Mobilizon.Events.TagRelation schema "tags" do field(:title, :string) field(:slug, TitleSlug.Type) + many_to_many(:related_tags, Tag, join_through: TagRelation) timestamps() end diff --git a/lib/mobilizon/events/tag_relations.ex b/lib/mobilizon/events/tag_relations.ex new file mode 100644 index 00000000..65618cb1 --- /dev/null +++ b/lib/mobilizon/events/tag_relations.ex @@ -0,0 +1,41 @@ +defmodule Mobilizon.Events.TagRelation do + @moduledoc """ + Represents a tag for events + """ + use Ecto.Schema + import Ecto.Changeset + alias Mobilizon.Events.Tag + alias Mobilizon.Events.TagRelation + + @primary_key false + schema "tag_relations" do + belongs_to(:tag, Tag, primary_key: true) + belongs_to(:link, Tag, primary_key: true) + field(:weight, :integer, default: 1) + end + + @doc false + def changeset(%TagRelation{} = tag, attrs) do + changeset = + tag + |> cast(attrs, [:tag_id, :link_id, :weight]) + |> validate_required([:tag_id, :link_id]) + + # Return if tag_id or link_id are not set because it will fail later otherwise + with %Ecto.Changeset{errors: []} <- changeset do + changes = changeset.changes + + changeset = + changeset + |> put_change(:tag_id, min(changes.tag_id, changes.link_id)) + |> put_change(:link_id, max(changes.tag_id, changes.link_id)) + + changeset + |> unique_constraint(:tag_id, name: :tag_relations_pkey) + |> check_constraint(:tag_id, + name: :no_self_loops_check, + message: "Can't add a relation on self" + ) + end + end +end diff --git a/lib/mobilizon/postgrex_types.ex b/lib/mobilizon/postgrex_types.ex index 0ff90663..d0680557 100644 --- a/lib/mobilizon/postgrex_types.ex +++ b/lib/mobilizon/postgrex_types.ex @@ -1,5 +1,5 @@ Postgrex.Types.define( Mobilizon.PostgresTypes, [Geo.PostGIS.Extension] ++ Ecto.Adapters.Postgres.extensions(), - json: Poison + json: Jason ) diff --git a/lib/mobilizon/repo.ex b/lib/mobilizon/repo.ex index 1ce8c576..d25e5b21 100644 --- a/lib/mobilizon/repo.ex +++ b/lib/mobilizon/repo.ex @@ -2,7 +2,9 @@ defmodule Mobilizon.Repo do @moduledoc """ Mobilizon Repo """ - use Ecto.Repo, otp_app: :mobilizon + use Ecto.Repo, + otp_app: :mobilizon, + adapter: Ecto.Adapters.Postgres @doc """ Dynamically loads the repository url from the diff --git a/lib/mobilizon_web/auth_error_handler.ex b/lib/mobilizon_web/auth_error_handler.ex index fea3e650..853ff92b 100644 --- a/lib/mobilizon_web/auth_error_handler.ex +++ b/lib/mobilizon_web/auth_error_handler.ex @@ -5,7 +5,7 @@ defmodule MobilizonWeb.AuthErrorHandler do import Plug.Conn def auth_error(conn, {type, _reason}, _opts) do - body = Poison.encode!(%{message: to_string(type)}) + body = Jason.encode!(%{message: to_string(type)}) send_resp(conn, 401, body) end end diff --git a/lib/mobilizon_web/endpoint.ex b/lib/mobilizon_web/endpoint.ex index 2b85a3d7..6717ee50 100644 --- a/lib/mobilizon_web/endpoint.ex +++ b/lib/mobilizon_web/endpoint.ex @@ -40,7 +40,7 @@ defmodule MobilizonWeb.Endpoint do Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], - json_decoder: Poison + json_decoder: Jason ) plug(Plug.MethodOverride) diff --git a/lib/mobilizon_web/resolvers/tag.ex b/lib/mobilizon_web/resolvers/tag.ex new file mode 100644 index 00000000..abc3861d --- /dev/null +++ b/lib/mobilizon_web/resolvers/tag.ex @@ -0,0 +1,40 @@ +defmodule MobilizonWeb.Resolvers.Tag do + @moduledoc """ + Handles the tag-related GraphQL calls + """ + require Logger + alias Mobilizon.Events.Event + alias Mobilizon.Events.Tag + + def list_tags(_parent, %{page: page, limit: limit}, _resolution) do + tags = Mobilizon.Events.list_tags(page, limit) + + {:ok, tags} + end + + @doc """ + Retrieve the list of tags for an event + """ + def list_tags_for_event(%Event{id: id}, _args, _resolution) do + {:ok, Mobilizon.Events.list_tags_for_event(id)} + end + + @doc """ + Retrieve the list of related tags for a given tag ID + """ + def get_related_tags(_parent, %{tag_id: tag_id}, _resolution) do + with %Tag{} = tag <- Mobilizon.Events.get_tag!(tag_id), + tags <- Mobilizon.Events.tag_neighbors(tag) do + {:ok, tags} + end + end + + @doc """ + Retrieve the list of related tags for a parent tag + """ + def get_related_tags(%Tag{} = tag, _args, _resolution) do + with tags <- Mobilizon.Events.tag_neighbors(tag) do + {:ok, tags} + end + end +end diff --git a/lib/mobilizon_web/schema/event.ex b/lib/mobilizon_web/schema/event.ex index 70230463..1214bf3a 100644 --- a/lib/mobilizon_web/schema/event.ex +++ b/lib/mobilizon_web/schema/event.ex @@ -8,6 +8,7 @@ defmodule MobilizonWeb.Schema.EventType do import_types(MobilizonWeb.Schema.AddressType) import_types(MobilizonWeb.Schema.Events.ParticipantType) import_types(MobilizonWeb.Schema.Events.CategoryType) + import_types(MobilizonWeb.Schema.TagType) alias MobilizonWeb.Resolvers @desc "An event" @@ -37,7 +38,12 @@ defmodule MobilizonWeb.Schema.EventType do ) field(:attributed_to, :actor, description: "Who the event is attributed to (often a group)") - # field(:tags, list_of(:tag)) + + field(:tags, list_of(:tag), + resolve: &MobilizonWeb.Resolvers.Tag.list_tags_for_event/3, + description: "The event's tags" + ) + field(:category, :category, description: "The event's category") field(:participants, list_of(:participant), diff --git a/lib/mobilizon_web/schema/tag.ex b/lib/mobilizon_web/schema/tag.ex new file mode 100644 index 00000000..7c4237cc --- /dev/null +++ b/lib/mobilizon_web/schema/tag.ex @@ -0,0 +1,30 @@ +defmodule MobilizonWeb.Schema.TagType do + @moduledoc """ + Schema representation for Tags + """ + use Absinthe.Schema.Notation + alias MobilizonWeb.Resolvers + + @desc "A tag" + object :tag do + field(:id, :id, description: "The tag's ID") + field(:slug, :string, description: "The tags's slug") + field(:title, :string, description: "The tag's title") + + field( + :related, + list_of(:tag), + resolve: &Resolvers.Tag.get_related_tags/3, + description: "Related tags to this tag" + ) + end + + object :tag_queries do + @desc "Get the list of tags" + field :tags, non_null(list_of(:tag)) do + arg(:page, :integer, default_value: 1) + arg(:limit, :integer, default_value: 10) + resolve(&Resolvers.Tag.list_tags/3) + end + end +end diff --git a/lib/service/activity_pub/activity_pub.ex b/lib/service/activity_pub/activity_pub.ex index 662096ab..d94701cb 100644 --- a/lib/service/activity_pub/activity_pub.ex +++ b/lib/service/activity_pub/activity_pub.ex @@ -495,7 +495,10 @@ defmodule Mobilizon.Service.ActivityPub do ical_events = body |> ExIcal.parse() - |> ExIcal.by_range(DateTime.utc_now(), DateTime.utc_now() |> Timex.shift(years: 1)) + |> ExIcal.by_range( + DateTime.utc_now(), + DateTime.utc_now() |> DateTime.truncate(:second) |> Timex.shift(years: 1) + ) activities = ical_events diff --git a/lib/service/activity_pub/utils.ex b/lib/service/activity_pub/utils.ex index a24ceff0..0c243054 100644 --- a/lib/service/activity_pub/utils.ex +++ b/lib/service/activity_pub/utils.ex @@ -46,7 +46,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do end def make_date do - DateTime.utc_now() |> DateTime.to_iso8601() + DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601() end @doc """ diff --git a/lib/service/federator.ex b/lib/service/federator.ex index 968a3755..161d3670 100644 --- a/lib/service/federator.ex +++ b/lib/service/federator.ex @@ -59,7 +59,7 @@ defmodule Mobilizon.Service.Federator do _e -> # Just drop those for now Logger.error("Unhandled activity") - Logger.error(Poison.encode!(params, pretty: 2)) + Logger.error(Jason.encode!(params)) end end diff --git a/mix.exs b/mix.exs index 5a746e2d..8fe67fe9 100644 --- a/mix.exs +++ b/mix.exs @@ -51,28 +51,26 @@ defmodule Mobilizon.Mixfile do [ {:phoenix, "~> 1.4.0"}, {:phoenix_pubsub, "~> 1.0"}, - {:phoenix_ecto, "~> 3.2"}, + {:phoenix_ecto, "~> 4.0"}, {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.10"}, {:gettext, "~> 0.11"}, - {:cowboy, "~> 1.0"}, + {:cowboy, "~> 2.6"}, {:guardian, "~> 1.2"}, - {:guardian_db, "~> 1.1"}, - {:comeonin, "~> 4.0"}, - {:argon2_elixir, "~> 1.2"}, + {:guardian_db, "~> 2.0"}, + {:argon2_elixir, "~> 2.0"}, {:cors_plug, "~> 2.0"}, {:ecto_autoslug_field, "~> 1.0"}, {:rsa_ex, "~> 0.1"}, {:geo, "~> 3.0"}, - {:geo_postgis, "~> 2.0"}, + {:geo_postgis, "~> 3.1"}, {:timex, "~> 3.0"}, - {:timex_ecto, "~> 3.0"}, {:icalendar, "~> 0.6"}, {:exgravatar, "~> 2.0.1"}, {:httpoison, "~> 1.0"}, {:json_ld, "~> 0.3"}, - {:jason, "~> 1.0"}, - {:ex_crypto, "~> 0.9.0"}, + {:jason, "~> 1.1"}, + {:ex_crypto, "~> 0.10.0"}, {:http_sign, "~> 0.1.1"}, {:ecto_enum, "~> 1.0"}, {:ex_ical, "~> 0.2"}, @@ -82,12 +80,11 @@ defmodule Mobilizon.Mixfile do {:absinthe, "~> 1.4.0"}, {:absinthe_phoenix, "~> 1.4.0"}, {:absinthe_plug, "~> 1.4.0"}, - {:poison, "~> 3.1"}, {:absinthe_ecto, "~> 0.1.3"}, {:dataloader, "~> 1.0"}, {:arc, "~> 0.11.0"}, {:arc_ecto, "~> 0.11.0"}, - {:plug_cowboy, "~> 1.0"}, + {:plug_cowboy, "~> 2.0"}, # Dev and test dependencies {:phoenix_live_reload, "~> 1.2", only: :dev}, {:ex_machina, "~> 2.2", only: [:dev, :test]}, diff --git a/mix.lock b/mix.lock index 60cfd13e..230d1557 100644 --- a/mix.lock +++ b/mix.lock @@ -5,31 +5,31 @@ "absinthe_plug": {:hex, :absinthe_plug, "1.4.6", "ac5d2d3d02acf52fda0f151b294017ab06e2ed1c6c15334e06aac82c94e36e08", [:mix], [{:absinthe, "~> 1.4.11", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "arc": {:hex, :arc, "0.11.0", "ac7a0cc03035317b6fef9fe94c97d7d9bd183a3e7ce1606aa0c175cfa8d1ba6d", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"}, "arc_ecto": {:hex, :arc_ecto, "0.11.1", "27aedf8c236b2097eed09d96f4ae73b43eb4c042a0e2ae42d44bf644cf16115c", [:mix], [{:arc, "~> 0.11.0", [hex: :arc, repo: "hexpm", optional: false]}, {:ecto, "~> 2.1 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm"}, - "argon2_elixir": {:hex, :argon2_elixir, "1.3.3", "487ffa071ef78c51d9b16e50ff3cf30cf8204e0aa4bdc8afd3765fdd8195e213", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, + "argon2_elixir": {:hex, :argon2_elixir, "2.0.0", "e3539f441930d4c8296e36024168526626351c1f2c2df97cfd50f4e90b15386a", [:make, :mix], [{:comeonin, "~> 5.0", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"}, "bamboo": {:hex, :bamboo, "1.2.0", "8aebd24f7c606c32d0163c398004a11608ca1028182a169b2e527793bfab7561", [:mix], [{:hackney, ">= 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "bamboo_smtp": {:hex, :bamboo_smtp, "1.6.0", "0a3607b77f22554af58c547350c1c73ebba6f4fb2c4bd0b11713ab5b4081588f", [:mix], [{:bamboo, "~> 1.0", [hex: :bamboo, repo: "hexpm", optional: false]}, {:gen_smtp, "~> 0.12.0", [hex: :gen_smtp, repo: "hexpm", optional: false]}], "hexpm"}, "base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"}, - "comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"}, + "comeonin": {:hex, :comeonin, "5.0.0", "e87716d3b1c31e56312f6a1545a5548cdc80376cff5025fe3b12be2046934837", [:mix], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "cors_plug": {:hex, :cors_plug, "2.0.0", "238ddb479f92b38f6dc1ae44b8d81f0387f9519101a6da442d543ab70ee0e482", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, - "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"}, + "cowboy": {:hex, :cowboy, "2.6.1", "f2e06f757c337b3b311f9437e6e072b678fcd71545a7b2865bdaa154d078593f", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"}, "credo": {:hex, :credo, "1.0.2", "88bc918f215168bf6ce7070610a6173c45c82f32baa08bdfc80bf58df2d103b6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "dataloader": {:hex, :dataloader, "1.0.6", "fb724d6d3fb6acb87d27e3b32dea3a307936ad2d245faf9cf5221d1323d6a4ba", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, - "db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, - "decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], [], "hexpm"}, + "db_connection": {:hex, :db_connection, "2.0.5", "ddb2ba6761a08b2bb9ca0e7d260e8f4dd39067426d835c24491a321b7f92a4da", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "1.0.0-rc.4", "71b42f5ee1b7628f3e3a6565f4617dfb02d127a0499ab3e72750455e986df001", [:mix], [{:erlex, "~> 0.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"}, - "ecto": {:hex, :ecto, "2.2.11", "4bb8f11718b72ba97a2696f65d247a379e739a0ecabf6a13ad1face79844791c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "ecto": {:hex, :ecto, "3.0.7", "44dda84ac6b17bbbdeb8ac5dfef08b7da253b37a453c34ab1a98de7f7e5fec7f", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "ecto_autoslug_field": {:hex, :ecto_autoslug_field, "1.0.0", "577eed25e6d045b8d783f82c9872f97c3a84017a4feae50eaf3cf4e1334a19e2", [:mix], [{:ecto, ">= 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:slugger, ">= 0.2.0", [hex: :slugger, repo: "hexpm", optional: false]}], "hexpm"}, "ecto_enum": {:hex, :ecto_enum, "1.2.0", "9ead3ee04efc4cb68a50560a9d9ebb665dd697f957f1c3df8e81bf863cf7a4e9", [:mix], [{:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm"}, - "elixir_make": {:hex, :elixir_make, "0.5.0", "3d65ce6d537d2ce164c0311551a607b90ea7f91d85242a67f3c5e59693c3aa50", [:mix], [], "hexpm"}, - "email_checker": {:hex, :email_checker, "0.1.2", "05b3121c71b69f1ab5df7d8b4844046898bf218031998ef53f20c6b8bfd219e9", [:mix], [{:socket, "~> 0.3.1", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"}, - "erlex": {:hex, :erlex, "0.2.0", "80349ebd58553dbd63489937380bfa7d906be3266b91bbd9d2bd6b71f1e8c07d", [:mix], [], "hexpm"}, - "ex_crypto": {:hex, :ex_crypto, "0.9.0", "e04a831034c4d0a43fb2858f696d6b5ae0f87f07dedca3452912fd3cb5ee3ca2", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "ecto_sql": {:hex, :ecto_sql, "3.0.5", "7e44172b4f7aca4469f38d7f6a3da394dbf43a1bcf0ca975e958cb957becd74e", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.6", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, + "elixir_make": {:hex, :elixir_make, "0.5.2", "96a28c79f5b8d34879cd95ebc04d2a0d678cfbbd3e74c43cb63a76adf0ee8054", [:mix], [], "hexpm"}, + "erlex": {:hex, :erlex, "0.2.1", "cee02918660807cbba9a7229cae9b42d1c6143b768c781fa6cee1eaf03ad860b", [:mix], [], "hexpm"}, + "ex_crypto": {:hex, :ex_crypto, "0.10.0", "af600a89b784b36613a989da6e998c1b200ff1214c3cfbaf8deca4aa2f0a1739", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_ical": {:hex, :ex_ical, "0.2.0", "4b928b554614704016cc0c9ee226eb854da9327a1cc460457621ceacb1ac29a6", [:mix], [{:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"}, "ex_machina": {:hex, :ex_machina, "2.2.2", "d84217a6fb7840ff771d2561b8aa6d74a0d8968e4b10ecc0d7e9890dc8fb1c6a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"}, @@ -42,11 +42,11 @@ "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, "gen_smtp": {:hex, :gen_smtp, "0.12.0", "97d44903f5ca18ca85cb39aee7d9c77e98d79804bbdef56078adcf905cb2ef00", [:rebar3], [], "hexpm"}, "geo": {:hex, :geo, "3.1.0", "727e005262430d037e870ff364e65d80ca5ca21d5ac8eddd57a1ada72c3f83b0", [:mix], [], "hexpm"}, - "geo_postgis": {:hex, :geo_postgis, "2.1.0", "e0640d18276cb1dd58aeae3f5eed9a61641a5110901e1e35d0d662031d936b33", [:mix], [{:geo, "~> 3.0", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm"}, + "geo_postgis": {:hex, :geo_postgis, "3.1.0", "d06c8fa5fd140a52a5c9dab4ad6623a696dd7d99dd791bb361d3f94942442ff9", [:mix], [{:geo, "~> 3.1", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0 or ~> 4.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm"}, "geolix": {:hex, :geolix, "0.17.0", "8f3f4068be08599912de67ae24372a6c148794a0152f9f83ffd5a2ffcb21d29a", [:mix], [{:mmdb2_decoder, "~> 0.3.0", [hex: :mmdb2_decoder, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.0", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"}, "gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"}, "guardian": {:hex, :guardian, "1.2.1", "bdc8dd3dbf0fb7216cb6f91c11831faa1a64d39cdaed9a611e37f2413e584983", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"}, - "guardian_db": {:hex, :guardian_db, "1.1.0", "45ab94206cce38f7443dc27de6dc52966ccbdeff65ca1b1f11a6d8f3daceb556", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm"}, + "guardian_db": {:hex, :guardian_db, "2.0.0", "65019ee9e09e1cfc157c0ec7840747bc54959ed4b985da80fecae9ff19b0f5df", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.0", "287a5d2304d516f63e56c469511c42b016423bcb167e61b611f6bad47e3ca60e", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "http_sign": {:hex, :http_sign, "0.1.1", "b16edb83aa282892f3271f9a048c155e772bf36e15700ab93901484c55f8dd10", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "1.5.0", "71ae9f304bdf7f00e9cd1823f275c955bdfc68282bc5eb5c85c3a9ade865d68e", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, @@ -56,8 +56,6 @@ "jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"}, "json_ld": {:hex, :json_ld, "0.3.0", "92f508ca831b9e4530e3e6c950976fdafcf26323e6817c325b3e1ee78affc4bd", [:mix], [{:jason, "~> 1.1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:rdf, "~> 0.5", [hex: :rdf, repo: "hexpm", optional: false]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, - "kronky": {:hex, :kronky, "0.5.0", "b2038c267f02b297044cb574f542fa96763278a88b32a97d0c37bde95c63c13b", [:mix], [{:absinthe, "~> 1.3", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, ">= 2.1.4", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm"}, - "littlefinger": {:hex, :littlefinger, "0.1.0", "5d3720bebd65d6a2051c31ca45f28b2d452d25aeeb8adb0a8f87013868bb0e7e", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm"}, @@ -68,26 +66,24 @@ "mmdb2_decoder": {:hex, :mmdb2_decoder, "0.3.0", "03a159a52342d3328cf2b774f1036e56719f7edc7f919180588a7764854c3318", [:mix], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, - "phoenix": {:hex, :phoenix, "1.4.0", "56fe9a809e0e735f3e3b9b31c1b749d4b436e466d8da627b8d82f90eaae714d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "3.6.0", "d65dbcedd6af568d8582dcd7da516c3051016bad51f9953e5337fea40bcd8a9d", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "phoenix": {:hex, :phoenix, "1.4.1", "801f9d632808657f1f7c657c8bbe624caaf2ba91429123ebe3801598aea4c3d9", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.13.1", "fa8f034b5328e2dfa0e4131b5569379003f34bc1fafdaa84985b0b9d2f12e68b", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.0", "3bb31a9fbd40ffe8652e60c8660dffd72dd231efcdf49b744fb75b9ef7db5dd2", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.1", "6668d787e602981f24f17a5fbb69cc98f8ab085114ebfac6cc36e10a90c8e93c", [:mix], [], "hexpm"}, - "plug": {:hex, :plug, "1.7.1", "8516d565fb84a6a8b2ca722e74e2cd25ca0fc9d64f364ec9dbec09d33eb78ccd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"}, - "plug_cowboy": {:hex, :plug_cowboy, "1.0.0", "2e2a7d3409746d335f451218b8bb0858301c3de6d668c3052716c909936eb57a", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "plug": {:hex, :plug, "1.7.2", "d7b7db7fbd755e8283b6c0a50be71ec0a3d67d9213d74422d9372effc8e87fd1", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.0.1", "d798f8ee5acc86b7d42dbe4450b8b0dadf665ce588236eb0a751a132417a980e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"}, - "postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, - "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, + "postgrex": {:hex, :postgrex, "0.14.1", "63247d4a5ad6b9de57a0bac5d807e1c32d41e39c04b8a4156a26c63bcd8a2e49", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, + "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, "rdf": {:hex, :rdf, "0.5.4", "57e09d4adfe7646fe0c3514b703b76eaf29d537b250b36abae75e66d7e5920cf", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, "rsa_ex": {:hex, :rsa_ex, "0.4.0", "e28dd7dc5236e156df434af0e4aa822384c8866c928e17b785d4edb7c253b558", [:mix], [], "hexpm"}, "slugger": {:hex, :slugger, "0.3.0", "efc667ab99eee19a48913ccf3d038b1fb9f165fa4fbf093be898b8099e61b6ed", [:mix], [], "hexpm"}, - "socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, + "telemetry": {:hex, :telemetry, "0.3.0", "099a7f3ce31e4780f971b4630a3c22ec66d22208bc090fe33a2a3a6a67754a73", [:rebar3], [], "hexpm"}, "timex": {:hex, :timex, "3.5.0", "b0a23167da02d0fe4f1a4e104d1f929a00d348502b52432c05de875d0b9cffa5", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, - "timex_ecto": {:hex, :timex_ecto, "3.3.0", "d5bdef09928e7a60f10a0baa47ce653f29b43d6fee87b30b236b216d0e36b98d", [:mix], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, - "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm"}, } diff --git a/priv/repo/migrations/20190208141700_tags_relations.exs b/priv/repo/migrations/20190208141700_tags_relations.exs new file mode 100644 index 00000000..e9d74571 --- /dev/null +++ b/priv/repo/migrations/20190208141700_tags_relations.exs @@ -0,0 +1,22 @@ +defmodule Mobilizon.Repo.Migrations.TagsRelations do + use Ecto.Migration + + def up do + create table(:tag_relations, primary_key: false) do + add :tag_id, references(:tags, on_delete: :delete_all), null: false, primary_key: true + add :link_id, references(:tags, on_delete: :delete_all), null: false, primary_key: true + add :weight, :integer, null: false, default: 1 + end + create constraint(:tag_relations, :no_self_loops_check, check: "tag_id <> link_id") + create index(:tag_relations, [:tag_id], name: :index_tag_relations_tag_id) + create index(:tag_relations, [:link_id], name: :index_tag_relations_link_id) + end + + def down do + drop constraint(:tag_relations, :no_self_loops_check) + + drop index(:tag_relations, [:tags_id]) + drop index(:tag_relations, [:link_id]) + drop table(:tag_relations) + end +end diff --git a/priv/repo/migrations/20190214100858_drop_datetimetz.exs b/priv/repo/migrations/20190214100858_drop_datetimetz.exs new file mode 100644 index 00000000..8515375b --- /dev/null +++ b/priv/repo/migrations/20190214100858_drop_datetimetz.exs @@ -0,0 +1,48 @@ +defmodule Mobilizon.Repo.Migrations.DropDatetimetz do + use Ecto.Migration + + def up do + alter table(:events) do + remove(:begins_on) + remove(:ends_on) + remove(:publish_at) + add(:begins_on, :utc_datetime) + add(:ends_on, :utc_datetime) + add(:publish_at, :utc_datetime) + end + + alter table(:sessions) do + remove(:begins_on) + remove(:ends_on) + add(:begins_on, :utc_datetime) + add(:ends_on, :utc_datetime) + end + + execute "DROP TYPE datetimetz" + end + + def down do + execute(""" + CREATE TYPE datetimetz AS ( + dt timestamptz, + tz varchar + ); + """) + + alter table(:events) do + remove(:begins_on) + remove(:ends_on) + remove(:publish_at) + add(:begins_on, :datetimetz) + add(:ends_on, :datetimetz) + add(:publish_at, :datetimetz) + end + + alter table(:sessions) do + remove(:begins_on) + remove(:ends_on) + add(:begins_on, :datetimetz) + add(:ends_on, :datetimetz) + end + end +end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index b1ccb7bb..62d3f430 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -21,17 +21,21 @@ actor = insert(:actor, user: user) # Insert a second actor account for the same user actor2 = insert(:actor, user: user) -# Make actor organize a few events -event = insert(:event, organizer_actor: actor) -event2 = insert(:event, organizer_actor: actor) -event3 = insert(:event, organizer_actor: actor) -event4 = insert(:event, organizer_actor: actor2) +tag1 = insert(:tag) +tag2 = insert(:tag) +tag3 = insert(:tag) -participant = insert(:participant, actor: actor, event: event, role: 4) -participant = insert(:participant, actor: actor, event: event2, role: 4) -participant = insert(:participant, actor: actor, event: event3, role: 4) -participant = insert(:participant, actor: actor2, event: event4, role: 4) -participant = insert(:participant, actor: actor, event: event4, role: 1) +# Make actor organize a few events +event = insert(:event, organizer_actor: actor, tags: [tag1, tag2]) +event2 = insert(:event, organizer_actor: actor, tags: [tag1, tag2]) +event3 = insert(:event, organizer_actor: actor, tags: [tag1]) +event4 = insert(:event, organizer_actor: actor2, tags: [tag3, tag2]) + +insert(:participant, actor: actor, event: event, role: :creator) +insert(:participant, actor: actor, event: event2, role: :creator) +insert(:participant, actor: actor, event: event3, role: :creator) +insert(:participant, actor: actor2, event: event4, role: :creator) +insert(:participant, actor: actor, event: event4, role: :participant) # Insert a group group = insert(:actor, type: :Group) diff --git a/test/fixtures/mastodon-delete.json b/test/fixtures/mastodon-delete.json index 87a58200..ab6265b5 100644 --- a/test/fixtures/mastodon-delete.json +++ b/test/fixtures/mastodon-delete.json @@ -2,12 +2,9 @@ "type": "Delete", "signature": { "type": "RsaSignature2017", - "signatureValue": "cw0RlfNREf+5VdsOYcCBDrv521eiLsDTAYNHKffjF0bozhCnOh+wHkFik7WamUk$ -uEiN4L2H6vPlGRprAZGRhEwgy+A7rIFQNmLrpW5qV5UNVI/2F7kngEHqZQgbQYj9hW+5GMYmPkHdv3D72ZefGw$ -4Xa2NBLGFpAjQllfzt7kzZLKKY2DM99FdUa64I2Wj3iD04Hs23SbrUdAeuGk/c1Cg6bwGNG4vxoiwn1jikgJLA$ -NAlSGjsRGdR7LfbC7GqWWsW3cSNsLFPoU6FyALjgTrrYoHiXe0QHggw+L3yMLfzB2S/L46/VRbyb+WDKMBIXUL$ -5owmzHSi6e/ZtCI3w==", - "creator": "http://mastodon.example.org/users/gargron#main-key", "created": "2018-03-03T16:24:11Z" + "signatureValue": "cw0RlfNREf+5VdsOYcCBDrv521eiLsDTAYNHKffjF0bozhCnOh+wHkFik7WamUkuEiN4L2H6vPlGRprAZGRhEwgy+A7rIFQNmLrpW5qV5UNVI/2F7kngEHqZQgbQYj9hW+5GMYmPkHdv3D72ZefGw4Xa2NBLGFpAjQllfzt7kzZLKKY2DM99FdUa64I2Wj3iD04Hs23SbrUdAeuGk/c1Cg6bwGNG4vxoiwn1jikgJLANAlSGjsRGdR7LfbC7GqWWsW3cSNsLFPoU6FyALjgTrrYoHiXe0QHggw+L3yMLfzB2S/L46/VRbyb+WDKMBIXUL5owmzHSi6e/ZtCI3w==", + "creator": "http://mastodon.example.org/users/gargron#main-key", + "created": "2018-03-03T16:24:11Z" }, "object": { "type": "Tombstone", diff --git a/test/mobilizon/actors/actors_test.exs b/test/mobilizon/actors/actors_test.exs index 7e67d79d..aa15715b 100644 --- a/test/mobilizon/actors/actors_test.exs +++ b/test/mobilizon/actors/actors_test.exs @@ -373,7 +373,7 @@ defmodule Mobilizon.ActorsTest do assert {:error, :user_not_found} = Actors.get_user_by_email(@email, true) Actors.update_user(user, %{ - "confirmed_at" => DateTime.utc_now(), + "confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second), "confirmation_sent_at" => nil, "confirmation_token" => nil }) diff --git a/test/mobilizon/events/events_test.exs b/test/mobilizon/events/events_test.exs index d326da56..0ecd530f 100644 --- a/test/mobilizon/events/events_test.exs +++ b/test/mobilizon/events/events_test.exs @@ -6,9 +6,9 @@ defmodule Mobilizon.EventsTest do alias Mobilizon.Events @event_valid_attrs %{ - begins_on: "2010-04-17 14:00:00.000000Z", + begins_on: "2010-04-17 14:00:00Z", description: "some description", - ends_on: "2010-04-17 14:00:00.000000Z", + ends_on: "2010-04-17 14:00:00Z", title: "some title", url: "some url", uuid: "b5126423-f1af-43e4-a923-002a03003ba4" @@ -24,15 +24,15 @@ defmodule Mobilizon.EventsTest do end @valid_attrs %{ - begins_on: "2010-04-17 14:00:00.000000Z", + begins_on: "2010-04-17 14:00:00Z", description: "some description", - ends_on: "2010-04-17 14:00:00.000000Z", + ends_on: "2010-04-17 14:00:00Z", title: "some title" } @update_attrs %{ - begins_on: "2011-05-18 15:01:01.000000Z", + begins_on: "2011-05-18 15:01:01Z", description: "some updated description", - ends_on: "2011-05-18 15:01:01.000000Z", + ends_on: "2011-05-18 15:01:01Z", title: "some updated title" } @invalid_attrs %{begins_on: nil, description: nil, ends_on: nil, title: nil} @@ -90,9 +90,9 @@ defmodule Mobilizon.EventsTest do |> Map.put(:address_id, address.id) with {:ok, %Event{} = event} <- Events.create_event(valid_attrs) do - assert event.begins_on == DateTime.from_naive!(~N[2010-04-17 14:00:00.000000Z], "Etc/UTC") + assert event.begins_on == DateTime.from_naive!(~N[2010-04-17 14:00:00Z], "Etc/UTC") assert event.description == "some description" - assert event.ends_on == DateTime.from_naive!(~N[2010-04-17 14:00:00.000000Z], "Etc/UTC") + assert event.ends_on == DateTime.from_naive!(~N[2010-04-17 14:00:00Z], "Etc/UTC") assert event.title == "some title" else err -> @@ -107,9 +107,9 @@ defmodule Mobilizon.EventsTest do test "update_event/2 with valid data updates the event", %{event: event} do assert {:ok, event} = Events.update_event(event, @update_attrs) assert %Event{} = event - assert event.begins_on == DateTime.from_naive!(~N[2011-05-18 15:01:01.000000Z], "Etc/UTC") + assert event.begins_on == DateTime.from_naive!(~N[2011-05-18 15:01:01Z], "Etc/UTC") assert event.description == "some updated description" - assert event.ends_on == DateTime.from_naive!(~N[2011-05-18 15:01:01.000000Z], "Etc/UTC") + assert event.ends_on == DateTime.from_naive!(~N[2011-05-18 15:01:01Z], "Etc/UTC") assert event.title == "some updated title" end @@ -302,6 +302,81 @@ defmodule Mobilizon.EventsTest do end end + describe "tags_relations" do + alias Mobilizon.Events.TagRelation + alias Mobilizon.Events.Tag + + setup do + tag1 = insert(:tag) + tag2 = insert(:tag) + {:ok, tag1: tag1, tag2: tag2} + end + + test "create_tag_relation/1 with valid data creates a tag relation", %{ + tag1: %Tag{id: tag1_id} = tag1, + tag2: %Tag{id: tag2_id} = tag2 + } do + assert {:ok, %TagRelation{} = tag_relation} = + Events.create_tag_relation(%{tag_id: tag1_id, link_id: tag2_id}) + + assert Events.are_tags_linked(tag1, tag2) + assert Events.are_tags_linked(tag2, tag1) + end + + test "create_tag_relation/1 with invalid data returns error changeset", %{ + tag1: %Tag{} = tag1, + tag2: %Tag{} = tag2 + } do + assert {:error, %Ecto.Changeset{}} = + Events.create_tag_relation(%{tag_id: nil, link_id: nil}) + + refute Events.are_tags_linked(tag1, tag2) + end + + test "delete_tag_relation/1 deletes the tag relation" do + tag_relation = insert(:tag_relation) + assert {:ok, %TagRelation{}} = Events.delete_tag_relation(tag_relation) + end + + test "tag_neighbors/2 return the connected tags for a given tag", %{ + tag1: %Tag{} = tag1, + tag2: %Tag{} = tag2 + } do + tag3 = insert(:tag) + tag4 = insert(:tag) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag1.id, link_id: tag2.id}) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag2.id, link_id: tag1.id}) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag3.id, link_id: tag2.id}) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag4.id, link_id: tag1.id}) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag4.id, link_id: tag1.id}) + + assert {:ok, %TagRelation{}} = + Events.create_tag_relation(%{tag_id: tag4.id, link_id: tag1.id}) + + assert {:error, + %Ecto.Changeset{ + errors: [ + tag_id: + {"Can't add a relation on self", + [constraint: :check, constraint_name: "no_self_loops_check"]} + ] + }} = Events.create_tag_relation(%{tag_id: tag1.id, link_id: tag1.id}) + + # The order is preserved, since tag4 has one more relation than tag2 + assert [tag4, tag2] == Events.tag_neighbors(tag1) + end + end + describe "participants" do alias Mobilizon.Events.{Participant, Event} alias Mobilizon.Actors.Actor diff --git a/test/mobilizon/service/activity_pub/transmogrifier_test.exs b/test/mobilizon/service/activity_pub/transmogrifier_test.exs index 450321cf..a7dde374 100644 --- a/test/mobilizon/service/activity_pub/transmogrifier_test.exs +++ b/test/mobilizon/service/activity_pub/transmogrifier_test.exs @@ -34,7 +34,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-post-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", activity["object"]) # {:ok, returned_activity} = Transmogrifier.handle_incoming(data) @@ -45,7 +45,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # test "it fetches replied-to activities if we don't have them" do # data = # File.read!("test/fixtures/mastodon-post-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # object = # data["object"] @@ -69,7 +69,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end test "it works for incoming notices" do - data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() {:ok, %Mobilizon.Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -103,7 +103,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do end test "it works for incoming notices with hashtags" do - data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!() + data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Jason.decode!() {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) assert Enum.at(data["object"]["tag"], 2) == "moo" @@ -111,7 +111,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # test "it works for incoming notices with contentMap" do # data = - # File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!() + # File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -120,7 +120,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end # test "it works for incoming notices with to/cc not being an array (kroeg)" do - # data = File.read!("test/fixtures/kroeg-post-activity.json") |> Poison.decode!() + # data = File.read!("test/fixtures/kroeg-post-activity.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -129,7 +129,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end # test "it works for incoming announces with actor being inlined (kroeg)" do - # data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Poison.decode!() + # data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -137,7 +137,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end # test "it works for incoming notices with tag not being an array (kroeg)" do - # data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!() + # data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -145,7 +145,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # "icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png" # } - # data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!() + # data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -153,7 +153,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end test "it works for incoming notices with url not being a string (prismo)" do - data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!() + data = File.read!("test/fixtures/prismo-url-map.json") |> Jason.decode!() assert {:error, :not_supported} == Transmogrifier.handle_incoming(data) # Pages are not supported @@ -167,7 +167,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do data = File.read!("test/fixtures/mastodon-follow-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("object", actor.url) {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -185,7 +185,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/hubzilla-follow-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", user.ap_id) # |> Utils.normalize_params() @@ -202,7 +202,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-like.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", url) # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -218,7 +218,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-undo-like.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", url) # assert Transmogrifier.handle_incoming(data) == {:error, :not_supported} @@ -229,14 +229,14 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # like_data = # File.read!("test/fixtures/mastodon-like.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", comment.url) # {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data) # data = # File.read!("test/fixtures/mastodon-undo-like.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", like_data) # |> Map.put("actor", like_data["actor"]) @@ -249,7 +249,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end # test "it works for incoming announces" do - # data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!() + # data = File.read!("test/fixtures/mastodon-announce.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -270,7 +270,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-announce.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", comment.url) # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -287,10 +287,10 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # end test "it works for incoming update activities" do - data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) - update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!() + update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!() object = update_data["object"] @@ -317,10 +317,10 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do end # test "it works for incoming update activities which lock the account" do - # data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + # data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) - # update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!() + # update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!() # object = # update_data["object"] @@ -345,7 +345,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do data = File.read!("test/fixtures/mastodon-delete.json") - |> Poison.decode!() + |> Jason.decode!() object = data["object"] @@ -369,7 +369,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-delete.json") - # |> Poison.decode!() + # |> Jason.decode!() # object = # data["object"] @@ -389,7 +389,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # announce_data = # File.read!("test/fixtures/mastodon-announce.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", comment.url) # {:ok, %Activity{data: announce_data, local: false}} = @@ -397,7 +397,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-undo-announce.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", announce_data) # |> Map.put("actor", announce_data["actor"]) @@ -416,14 +416,14 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do follow_data = File.read!("test/fixtures/mastodon-follow-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("object", actor.url) {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data) data = File.read!("test/fixtures/mastodon-unfollow-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("object", follow_data) {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -442,7 +442,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-block-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", user.ap_id) # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -462,7 +462,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-block-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", blocked.ap_id) # |> Map.put("actor", blocker.ap_id) @@ -492,14 +492,14 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # block_data = # File.read!("test/fixtures/mastodon-block-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", user.ap_id) # {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(block_data) # data = # File.read!("test/fixtures/mastodon-unblock-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", block_data) # {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) @@ -524,7 +524,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # accept_data = # File.read!("test/fixtures/mastodon-accept-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # object = @@ -552,7 +552,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # accept_data = # File.read!("test/fixtures/mastodon-accept-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # accept_data = @@ -574,7 +574,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # accept_data = # File.read!("test/fixtures/mastodon-accept-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # |> Map.put("object", follow_activity.data["id"]) @@ -592,7 +592,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # accept_data = # File.read!("test/fixtures/mastodon-accept-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # accept_data = @@ -611,7 +611,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # accept_data = # File.read!("test/fixtures/mastodon-reject-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # accept_data = @@ -635,7 +635,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # reject_data = # File.read!("test/fixtures/mastodon-reject-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # reject_data = @@ -660,7 +660,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # reject_data = # File.read!("test/fixtures/mastodon-reject-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("actor", followed.ap_id) # |> Map.put("object", follow_activity.data["id"]) @@ -676,7 +676,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do # data = # File.read!("test/fixtures/mastodon-follow-activity.json") - # |> Poison.decode!() + # |> Jason.decode!() # |> Map.put("object", user.ap_id) # |> Map.put("id", "") diff --git a/test/mobilizon_web/controllers/activity_pub_controller_test.exs b/test/mobilizon_web/controllers/activity_pub_controller_test.exs index 3dfa42d9..0fe234fb 100644 --- a/test/mobilizon_web/controllers/activity_pub_controller_test.exs +++ b/test/mobilizon_web/controllers/activity_pub_controller_test.exs @@ -82,7 +82,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do describe "/@:preferred_username/inbox" do test "it inserts an incoming event into the database", %{conn: conn} do use_cassette "activity_pub_controller/mastodon-post-activity_actor_call" do - data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() conn = conn diff --git a/test/mobilizon_web/resolvers/event_resolver_test.exs b/test/mobilizon_web/resolvers/event_resolver_test.exs index 2c1ee0b0..d43b1fca 100644 --- a/test/mobilizon_web/resolvers/event_resolver_test.exs +++ b/test/mobilizon_web/resolvers/event_resolver_test.exs @@ -7,7 +7,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do @event %{ description: "some body", title: "some title", - begins_on: Ecto.DateTime.utc(), + begins_on: DateTime.utc_now() |> DateTime.truncate(:second), uuid: "b5126423-f1af-43e4-a923-002a03003ba4", url: "some url" } @@ -68,7 +68,9 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do createEvent( title: "come to my event", description: "it will be fine", - begins_on: "#{DateTime.utc_now() |> DateTime.to_iso8601()}", + begins_on: "#{ + DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601() + }", organizer_actor_id: "#{actor.id}", category: "#{category.title}" ) { diff --git a/test/mobilizon_web/resolvers/participant_resolver_test.exs b/test/mobilizon_web/resolvers/participant_resolver_test.exs index ca5d0dda..070d6c0c 100644 --- a/test/mobilizon_web/resolvers/participant_resolver_test.exs +++ b/test/mobilizon_web/resolvers/participant_resolver_test.exs @@ -7,7 +7,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do @event %{ description: "some body", title: "some title", - begins_on: Ecto.DateTime.utc(), + begins_on: DateTime.utc_now() |> DateTime.truncate(:second), uuid: "b5126423-f1af-43e4-a923-002a03003ba4", url: "some url" } diff --git a/test/mobilizon_web/resolvers/user_resolver_test.exs b/test/mobilizon_web/resolvers/user_resolver_test.exs index 96c1f4cb..e0cbd452 100644 --- a/test/mobilizon_web/resolvers/user_resolver_test.exs +++ b/test/mobilizon_web/resolvers/user_resolver_test.exs @@ -477,7 +477,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do {:ok, %User{} = _user} = Actors.update_user(user, %{ - "confirmed_at" => DateTime.utc_now(), + "confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second), "confirmation_sent_at" => nil, "confirmation_token" => nil }) @@ -509,7 +509,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do {:ok, %User{} = _user} = Actors.update_user(user, %{ - "confirmed_at" => DateTime.utc_now(), + "confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second), "confirmation_sent_at" => nil, "confirmation_token" => nil }) diff --git a/test/support/factory.ex b/test/support/factory.ex index 74537fff..33075e4d 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -10,7 +10,7 @@ defmodule Mobilizon.Factory do password_hash: "Jane Smith", email: sequence(:email, &"email-#{&1}@example.com"), role: 0, - confirmed_at: DateTime.utc_now(), + confirmed_at: DateTime.utc_now() |> DateTime.truncate(:second), confirmation_sent_at: nil, confirmation_token: nil } @@ -67,6 +67,13 @@ defmodule Mobilizon.Factory do } end + def tag_relation_factory do + %Mobilizon.Events.TagRelation{ + tag: build(:tag), + link: build(:tag) + } + end + def address_factory do %Mobilizon.Addresses.Address{ description: sequence("MyAddress"),