forked from potsda.mn/mobilizon
More tests
This commit is contained in:
parent
a3852f26c1
commit
686cf04787
|
@ -3,5 +3,5 @@ defmodule Eventos.Activity do
|
||||||
Represents an activity
|
Represents an activity
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct [:id, :data, :local, :actor, :recipients, :notifications]
|
defstruct [:id, :data, :local, :actor, :recipients, :notifications, :type]
|
||||||
end
|
end
|
||||||
|
|
|
@ -173,23 +173,9 @@ defmodule Eventos.Actors.Actor do
|
||||||
|> put_change(:local, true)
|
|> put_change(:local, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_or_fetch_by_url(url) do
|
|
||||||
if user = Actors.get_actor_by_url(url) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
case ActivityPub.make_actor_from_url(url) do
|
|
||||||
{:ok, user} ->
|
|
||||||
user
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
{:error, "Could not fetch by AP id"}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec get_public_key_for_url(String.t()) :: {:ok, String.t()}
|
@spec get_public_key_for_url(String.t()) :: {:ok, String.t()}
|
||||||
def get_public_key_for_url(url) do
|
def get_public_key_for_url(url) do
|
||||||
with %Actor{} = actor <- get_or_fetch_by_url(url) do
|
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(url) do
|
||||||
actor.keys
|
actor.keys
|
||||||
|> Eventos.Service.ActivityPub.Utils.pem_to_public_key()
|
|> Eventos.Service.ActivityPub.Utils.pem_to_public_key()
|
||||||
else
|
else
|
||||||
|
@ -228,4 +214,44 @@ defmodule Eventos.Actors.Actor do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_groups_member_of(%Actor{id: actor_id}) do
|
||||||
|
Repo.all(
|
||||||
|
from(
|
||||||
|
a in Actor,
|
||||||
|
join: m in Member,
|
||||||
|
on: a.id == m.parent_id,
|
||||||
|
where: m.actor_id == ^actor_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_members_for_group(%Actor{id: actor_id}) do
|
||||||
|
Repo.all(
|
||||||
|
from(
|
||||||
|
a in Actor,
|
||||||
|
join: m in Member,
|
||||||
|
on: a.id == m.actor_id,
|
||||||
|
where: m.parent_id == ^actor_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def follow(%Actor{} = follower, %Actor{} = followed) do
|
||||||
|
# Check if actor is locked
|
||||||
|
# Check if followed has blocked follower
|
||||||
|
# Check if follower already follows followed
|
||||||
|
cond do
|
||||||
|
following?(follower, followed) ->
|
||||||
|
{:error,
|
||||||
|
"Could not follow actor: you are already following #{followed.preferred_username}"}
|
||||||
|
|
||||||
|
# true -> nil
|
||||||
|
# Follow the person
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def following?(%Actor{} = follower, %Actor{followers: followers}) do
|
||||||
|
Enum.member?(followers, follower)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -265,13 +265,11 @@ defmodule Eventos.Actors do
|
||||||
|
|
||||||
def get_or_fetch_by_url(url) do
|
def get_or_fetch_by_url(url) do
|
||||||
if actor = get_actor_by_url(url) do
|
if actor = get_actor_by_url(url) do
|
||||||
actor
|
{:ok, actor}
|
||||||
else
|
else
|
||||||
ap_try = ActivityPub.make_actor_from_url(url)
|
case ActivityPub.make_actor_from_url(url) do
|
||||||
|
|
||||||
case ap_try do
|
|
||||||
{:ok, actor} ->
|
{:ok, actor} ->
|
||||||
actor
|
{:ok, actor}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{:error, "Could not fetch by AP id"}
|
{:error, "Could not fetch by AP id"}
|
||||||
|
@ -299,7 +297,7 @@ defmodule Eventos.Actors do
|
||||||
@doc """
|
@doc """
|
||||||
Find actors by their name or displayed name
|
Find actors by their name or displayed name
|
||||||
"""
|
"""
|
||||||
def find_actors_by_username(username) do
|
def find_actors_by_username_or_name(username) do
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from(
|
from(
|
||||||
a in Actor,
|
a in Actor,
|
||||||
|
@ -320,7 +318,7 @@ 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])?)*$/
|
@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
|
def search(name) do
|
||||||
# find already saved accounts
|
# find already saved accounts
|
||||||
case find_actors_by_username(name) do
|
case find_actors_by_username_or_name(name) do
|
||||||
[] ->
|
[] ->
|
||||||
# no accounts found, let's test if it's an username@domain.tld
|
# no accounts found, let's test if it's an username@domain.tld
|
||||||
with true <- Regex.match?(@email_regex, name),
|
with true <- Regex.match?(@email_regex, name),
|
||||||
|
@ -457,6 +455,24 @@ defmodule Eventos.Actors do
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets an user by it's email
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> get_user_by_email(user, email)
|
||||||
|
{:ok, %User{}}
|
||||||
|
|
||||||
|
iex> get_user_by_email(user, wrong_email)
|
||||||
|
{:error, nil}
|
||||||
|
"""
|
||||||
|
def get_user_by_email(email) do
|
||||||
|
case Repo.get_by(User, email: email) do
|
||||||
|
nil -> {:error, nil}
|
||||||
|
user -> {:ok, user}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Updates a user.
|
Updates a user.
|
||||||
|
|
||||||
|
@ -548,10 +564,12 @@ defmodule Eventos.Actors do
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def create_member(attrs \\ %{}) do
|
def create_member(attrs \\ %{}) do
|
||||||
|
with {:ok, %Member{} = member} <-
|
||||||
%Member{}
|
%Member{}
|
||||||
|> Member.changeset(attrs)
|
|> Member.changeset(attrs)
|
||||||
|> Repo.insert!()
|
|> Repo.insert() do
|
||||||
|> Repo.preload([:actor, :parent])
|
{:ok, Repo.preload(member, [:actor, :parent])}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -7,7 +7,6 @@ defmodule Eventos.Actors.Member do
|
||||||
alias Eventos.Actors.Member
|
alias Eventos.Actors.Member
|
||||||
alias Eventos.Actors.Actor
|
alias Eventos.Actors.Actor
|
||||||
|
|
||||||
@primary_key false
|
|
||||||
schema "members" do
|
schema "members" do
|
||||||
field(:approved, :boolean, default: true)
|
field(:approved, :boolean, default: true)
|
||||||
# 0 : Member, 1 : Moderator, 2 : Admin
|
# 0 : Member, 1 : Moderator, 2 : Admin
|
||||||
|
@ -23,5 +22,6 @@ defmodule Eventos.Actors.Member do
|
||||||
member
|
member
|
||||||
|> cast(attrs, [:role, :approved, :parent_id, :actor_id])
|
|> cast(attrs, [:role, :approved, :parent_id, :actor_id])
|
||||||
|> validate_required([:parent_id, :actor_id])
|
|> validate_required([:parent_id, :actor_id])
|
||||||
|
|> unique_constraint(:parent_id, name: :members_actor_parent_unique_index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,16 +11,18 @@ defmodule Eventos.Actors.Service.ResetPassword do
|
||||||
"""
|
"""
|
||||||
@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
|
def check_reset_password_token(password, token) do
|
||||||
with %User{} = user <- Repo.get_by(User, reset_password_token: token) do
|
with %User{} = user <- Repo.get_by(User, reset_password_token: token),
|
||||||
|
{:ok, %User{} = user} <-
|
||||||
Repo.update(
|
Repo.update(
|
||||||
User.password_reset_changeset(user, %{
|
User.password_reset_changeset(user, %{
|
||||||
"password" => password,
|
"password" => password,
|
||||||
"reset_password_sent_at" => nil,
|
"reset_password_sent_at" => nil,
|
||||||
"reset_password_token" => nil
|
"reset_password_token" => nil
|
||||||
})
|
})
|
||||||
)
|
) do
|
||||||
|
{:ok, Repo.preload(user, :actors)}
|
||||||
else
|
else
|
||||||
_err ->
|
err ->
|
||||||
{:error, :invalid_token}
|
{:error, :invalid_token}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,17 +21,23 @@ defmodule Eventos.Events.Comment do
|
||||||
belongs_to(:in_reply_to_comment, Comment, foreign_key: :in_reply_to_comment_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)
|
belongs_to(:origin_comment, Comment, foreign_key: :origin_comment_id)
|
||||||
|
|
||||||
timestamps()
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(comment, attrs) do
|
def changeset(comment, attrs) do
|
||||||
uuid = Ecto.UUID.generate()
|
uuid = Ecto.UUID.generate()
|
||||||
|
|
||||||
|
# TODO : really change me right away
|
||||||
|
url =
|
||||||
|
if Map.has_key?(attrs, "url"),
|
||||||
|
do: attrs["url"],
|
||||||
|
else: "#{EventosWeb.Endpoint.url()}/comments/#{uuid}"
|
||||||
|
|
||||||
comment
|
comment
|
||||||
|> cast(attrs, [:url, :text, :actor_id, :event_id, :in_reply_to_comment_id, :attributed_to_id])
|
|> cast(attrs, [:url, :text, :actor_id, :event_id, :in_reply_to_comment_id, :attributed_to_id])
|
||||||
|> validate_required([:text, :actor_id])
|
|
||||||
|> put_change(:uuid, uuid)
|
|> put_change(:uuid, uuid)
|
||||||
|> put_change(:url, "#{EventosWeb.Endpoint.url()}/comments/#{uuid}")
|
|> put_change(:url, url)
|
||||||
|
|> validate_required([:text, :actor_id, :url])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,8 +18,11 @@ defmodule Eventos.Events.Event do
|
||||||
field(:description, :string)
|
field(:description, :string)
|
||||||
field(:ends_on, Timex.Ecto.DateTimeWithTimezone)
|
field(:ends_on, Timex.Ecto.DateTimeWithTimezone)
|
||||||
field(:title, :string)
|
field(:title, :string)
|
||||||
|
# ???
|
||||||
field(:state, :integer, default: 0)
|
field(:state, :integer, default: 0)
|
||||||
|
# Event status: TENTATIVE 1, CONFIRMED 2, CANCELLED 3
|
||||||
field(:status, :integer, default: 0)
|
field(:status, :integer, default: 0)
|
||||||
|
# If the event is public or private
|
||||||
field(:public, :boolean, default: true)
|
field(:public, :boolean, default: true)
|
||||||
field(:thumbnail, :string)
|
field(:thumbnail, :string)
|
||||||
field(:large_image, :string)
|
field(:large_image, :string)
|
||||||
|
@ -42,9 +45,7 @@ defmodule Eventos.Events.Event do
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(%Event{} = event, attrs) do
|
def changeset(%Event{} = event, attrs) do
|
||||||
uuid = Ecto.UUID.generate()
|
# TODO : Change all of this
|
||||||
|
|
||||||
# TODO : check what's the use here. Tests ?
|
|
||||||
actor_url =
|
actor_url =
|
||||||
if Map.has_key?(attrs, :organizer_actor) do
|
if Map.has_key?(attrs, :organizer_actor) do
|
||||||
attrs.organizer_actor.preferred_username
|
attrs.organizer_actor.preferred_username
|
||||||
|
@ -52,6 +53,13 @@ defmodule Eventos.Events.Event do
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
uuid = Ecto.UUID.generate()
|
||||||
|
|
||||||
|
url =
|
||||||
|
if Map.has_key?(attrs, "url"),
|
||||||
|
do: attrs["url"],
|
||||||
|
else: "#{EventosWeb.Endpoint.url()}/@#{actor_url}/#{uuid}"
|
||||||
|
|
||||||
event
|
event
|
||||||
|> Ecto.Changeset.cast(attrs, [
|
|> Ecto.Changeset.cast(attrs, [
|
||||||
:title,
|
:title,
|
||||||
|
@ -74,7 +82,7 @@ defmodule Eventos.Events.Event do
|
||||||
|> cast_assoc(:tags)
|
|> cast_assoc(:tags)
|
||||||
|> cast_assoc(:physical_address)
|
|> cast_assoc(:physical_address)
|
||||||
|> put_change(:uuid, uuid)
|
|> put_change(:uuid, uuid)
|
||||||
|> put_change(:url, "#{EventosWeb.Endpoint.url()}/@#{actor_url}/#{uuid}")
|
|> put_change(:url, url)
|
||||||
|> validate_required([
|
|> validate_required([
|
||||||
:title,
|
:title,
|
||||||
:begins_on,
|
:begins_on,
|
||||||
|
|
|
@ -110,10 +110,17 @@ defmodule Eventos.Events do
|
||||||
@doc """
|
@doc """
|
||||||
Gets an event by it's URL
|
Gets an event by it's URL
|
||||||
"""
|
"""
|
||||||
def get_event_by_url!(url) do
|
def get_event_by_url(url) do
|
||||||
Repo.get_by(Event, url: url)
|
Repo.get_by(Event, url: url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets an event by it's URL
|
||||||
|
"""
|
||||||
|
def get_event_by_url!(url) do
|
||||||
|
Repo.get_by!(Event, url: url)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets an event by it's UUID
|
Gets an event by it's UUID
|
||||||
"""
|
"""
|
||||||
|
@ -175,7 +182,10 @@ defmodule Eventos.Events do
|
||||||
@doc """
|
@doc """
|
||||||
Find events by name
|
Find events by name
|
||||||
"""
|
"""
|
||||||
|
def find_events_by_name(name) when name == "", do: []
|
||||||
|
|
||||||
def find_events_by_name(name) do
|
def find_events_by_name(name) do
|
||||||
|
name = String.trim(name)
|
||||||
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])
|
Repo.preload(events, [:organizer_actor])
|
||||||
end
|
end
|
||||||
|
@ -780,6 +790,32 @@ defmodule Eventos.Events do
|
||||||
Repo.all(Comment)
|
Repo.all(Comment)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_comments_for_actor(%Actor{id: actor_id}, page \\ 1, limit \\ 10) do
|
||||||
|
start = (page - 1) * limit
|
||||||
|
|
||||||
|
query =
|
||||||
|
from(
|
||||||
|
c in Comment,
|
||||||
|
where: c.actor_id == ^actor_id,
|
||||||
|
limit: ^limit,
|
||||||
|
order_by: [desc: :id],
|
||||||
|
offset: ^start,
|
||||||
|
preload: [
|
||||||
|
:actor,
|
||||||
|
:in_reply_to_comment,
|
||||||
|
:origin_comment,
|
||||||
|
:event
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
comments = Repo.all(query)
|
||||||
|
|
||||||
|
count_comments =
|
||||||
|
Repo.one(from(c in Comment, select: count(c.id), where: c.actor_id == ^actor_id))
|
||||||
|
|
||||||
|
{:ok, comments, count_comments}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single comment.
|
Gets a single comment.
|
||||||
|
|
||||||
|
@ -798,6 +834,16 @@ defmodule Eventos.Events do
|
||||||
|
|
||||||
def get_comment_with_uuid!(uuid), do: Repo.get_by!(Comment, uuid: uuid)
|
def get_comment_with_uuid!(uuid), do: Repo.get_by!(Comment, uuid: uuid)
|
||||||
|
|
||||||
|
def get_comment_from_url(url), do: Repo.get_by(Comment, url: url)
|
||||||
|
|
||||||
|
def get_comment_from_url!(url), do: Repo.get_by!(Comment, url: url)
|
||||||
|
|
||||||
|
def get_comment_full_from_url!(url) do
|
||||||
|
with %Comment{} = comment <- Repo.get_by!(Comment, url: url) do
|
||||||
|
Repo.preload(comment, :actor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a comment.
|
Creates a comment.
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,16 @@ defmodule EventosWeb.ActivityPubController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def event(conn, %{"uuid" => uuid}) do
|
def event(conn, %{"uuid" => uuid}) do
|
||||||
with %Event{} = event <- Events.get_event_full_by_uuid(uuid) do
|
with %Event{} = event <- Events.get_event_full_by_uuid(uuid),
|
||||||
|
true <- event.public do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(ObjectView.render("event.json", %{event: event}))
|
|> json(ObjectView.render("event.json", %{event: event}))
|
||||||
|
else
|
||||||
|
false ->
|
||||||
|
conn
|
||||||
|
|> put_status(404)
|
||||||
|
|> json("Not found")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,12 @@ defmodule EventosWeb.ActorController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def show(conn, %{"name" => name}) do
|
def show(conn, %{"name" => name}) do
|
||||||
actor = Actors.get_actor_by_name_with_everything(name)
|
with %Actor{} = actor <- Actors.get_actor_by_name_with_everything(name) do
|
||||||
render(conn, "show.json", actor: actor)
|
render(conn, "show.json", actor: actor)
|
||||||
|
else
|
||||||
|
nil ->
|
||||||
|
send_resp(conn, :not_found, "")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@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])?)*$/
|
@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])?)*$/
|
||||||
|
@ -57,7 +61,7 @@ defmodule EventosWeb.ActorController do
|
||||||
actor = Actors.get_local_actor_by_name(name)
|
actor = Actors.get_local_actor_by_name(name)
|
||||||
|
|
||||||
with {:ok, %Actor{} = actor} <- Actors.update_actor(actor, actor_params) do
|
with {:ok, %Actor{} = actor} <- Actors.update_actor(actor, actor_params) do
|
||||||
render(conn, "show.json", actor: actor)
|
render(conn, "show_basic.json", actor: actor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,13 @@ defmodule EventosWeb.GroupController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"group" => group_params}) do
|
def create(conn, %{"group" => group_params}) do
|
||||||
with {:ok, %Actor{} = group} <- Actors.create_group(group_params) do
|
with {:ok, %Actor{} = group} <- Actors.create_group(group_params),
|
||||||
%Member{} =
|
{:ok, %Member{} = member} <-
|
||||||
_member =
|
|
||||||
Actors.create_member(%{
|
Actors.create_member(%{
|
||||||
"parent_id" => group.id,
|
"parent_id" => group.id,
|
||||||
"actor_id" => Actors.get_local_actor_by_name(group_params["actor_admin"]).id,
|
"actor_id" => Actors.get_local_actor_by_name(group_params["actor_admin"]).id,
|
||||||
"role" => 2
|
"role" => 2
|
||||||
})
|
}) do
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_status(:created)
|
|> put_status(:created)
|
||||||
|> put_resp_header("location", actor_path(conn, :show, group))
|
|> put_resp_header("location", actor_path(conn, :show, group))
|
||||||
|
@ -34,7 +32,7 @@ defmodule EventosWeb.GroupController do
|
||||||
def join(conn, %{"name" => group_name, "actor_name" => actor_name}) do
|
def join(conn, %{"name" => group_name, "actor_name" => actor_name}) do
|
||||||
with %Actor{} = group <- Actors.get_group_by_name(group_name),
|
with %Actor{} = group <- Actors.get_group_by_name(group_name),
|
||||||
%Actor{} = actor <- Actors.get_local_actor_by_name(actor_name),
|
%Actor{} = actor <- Actors.get_local_actor_by_name(actor_name),
|
||||||
%Member{} = member <-
|
{:ok, %Member{} = member} <-
|
||||||
Actors.create_member(%{"parent_id" => group.id, "actor_id" => actor.id}) do
|
Actors.create_member(%{"parent_id" => group.id, "actor_id" => actor.id}) do
|
||||||
conn
|
conn
|
||||||
|> put_status(:created)
|
|> put_status(:created)
|
||||||
|
|
|
@ -42,11 +42,15 @@ defmodule EventosWeb.UserController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@time_before_resend 3600
|
||||||
def resend_confirmation(conn, %{"email" => email}) do
|
def resend_confirmation(conn, %{"email" => email}) do
|
||||||
with {:ok, %User{} = user} <- Actors.find_by_email(email),
|
with {:ok, %User{} = user} <- Actors.find_by_email(email),
|
||||||
false <- is_nil(user.confirmation_token),
|
false <- is_nil(user.confirmation_token),
|
||||||
true <-
|
true <-
|
||||||
Timex.before?(Timex.shift(user.confirmation_sent_at, hours: 1), DateTime.utc_now()) do
|
Timex.before?(
|
||||||
|
Timex.shift(user.confirmation_sent_at, seconds: @time_before_resend),
|
||||||
|
DateTime.utc_now()
|
||||||
|
) do
|
||||||
Activation.resend_confirmation_email(user)
|
Activation.resend_confirmation_email(user)
|
||||||
render(conn, "confirmation.json", %{user: user})
|
render(conn, "confirmation.json", %{user: user})
|
||||||
else
|
else
|
||||||
|
@ -58,7 +62,10 @@ defmodule EventosWeb.UserController do
|
||||||
_ ->
|
_ ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{"error" => "Unable to resend the validation token"})
|
|> json(%{
|
||||||
|
"error" =>
|
||||||
|
"Unable to resend the validation token. Please wait a while before you can ask for resending token"
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -67,7 +74,7 @@ defmodule EventosWeb.UserController do
|
||||||
{:ok, _} <- ResetPassword.send_password_reset_email(user) do
|
{:ok, _} <- ResetPassword.send_password_reset_email(user) do
|
||||||
render(conn, "password_reset.json", %{user: user})
|
render(conn, "password_reset.json", %{user: user})
|
||||||
else
|
else
|
||||||
{:error, :not_found} ->
|
{:error, nil} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{"errors" => "Unable to find an user with this email"})
|
|> json(%{"errors" => "Unable to find an user with this email"})
|
||||||
|
@ -105,23 +112,23 @@ defmodule EventosWeb.UserController do
|
||||||
render(conn, "show_simple.json", user: user)
|
render(conn, "show_simple.json", user: user)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp handle_changeset_errors(errors) do
|
# defp handle_changeset_errors(errors) do
|
||||||
errors
|
# errors
|
||||||
|> Enum.map(fn {field, detail} ->
|
# |> Enum.map(fn {field, detail} ->
|
||||||
"#{field} " <> render_detail(detail)
|
# "#{field} " <> render_detail(detail)
|
||||||
end)
|
# end)
|
||||||
|> Enum.join()
|
# |> Enum.join()
|
||||||
end
|
# end
|
||||||
|
|
||||||
defp render_detail({message, values}) do
|
# 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))
|
# String.replace(acc, "%{#{k}}", to_string(v))
|
||||||
end)
|
# end)
|
||||||
end
|
# end
|
||||||
|
|
||||||
defp render_detail(message) do
|
# defp render_detail(message) do
|
||||||
message
|
# message
|
||||||
end
|
# end
|
||||||
|
|
||||||
def update(conn, %{"id" => id, "user" => user_params}) do
|
def update(conn, %{"id" => id, "user" => user_params}) do
|
||||||
user = Actors.get_user!(id)
|
user = Actors.get_user!(id)
|
||||||
|
|
|
@ -122,6 +122,7 @@ defmodule EventosWeb.Router do
|
||||||
get("/@:name/following", ActivityPubController, :following)
|
get("/@:name/following", ActivityPubController, :following)
|
||||||
get("/@:name/followers", ActivityPubController, :followers)
|
get("/@:name/followers", ActivityPubController, :followers)
|
||||||
get("/events/:uuid", ActivityPubController, :event)
|
get("/events/:uuid", ActivityPubController, :event)
|
||||||
|
get("/comments/:uuid", ActivityPubController, :event)
|
||||||
post("/@:name/inbox", ActivityPubController, :inbox)
|
post("/@:name/inbox", ActivityPubController, :inbox)
|
||||||
post("/inbox", ActivityPubController, :inbox)
|
post("/inbox", ActivityPubController, :inbox)
|
||||||
end
|
end
|
||||||
|
|
|
@ -134,10 +134,17 @@ defmodule EventosWeb.ActivityPub.ActorView do
|
||||||
else
|
else
|
||||||
"Announce"
|
"Announce"
|
||||||
end,
|
end,
|
||||||
"actor" => activity.data.organizer_actor.url,
|
"actor" => activity.actor,
|
||||||
"published" => Timex.now(),
|
"published" => Timex.now(),
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||||
"object" => render_one(activity.data, ObjectView, "event.json", as: :event)
|
"object" =>
|
||||||
|
case activity.type do
|
||||||
|
:Event ->
|
||||||
|
render_one(activity.data, ObjectView, "event.json", as: :event)
|
||||||
|
|
||||||
|
:Comment ->
|
||||||
|
render_one(activity.data, ObjectView, "note.json", as: :note)
|
||||||
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,19 @@ defmodule EventosWeb.ActivityPub.ObjectView do
|
||||||
Map.merge(event, @base)
|
Map.merge(event, @base)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render("note.json", %{note: note}) do
|
||||||
|
event = %{
|
||||||
|
"type" => "Note",
|
||||||
|
"id" => note.url,
|
||||||
|
"content" => note.text,
|
||||||
|
"mediaType" => "text/markdown",
|
||||||
|
"published" => Timex.format!(note.inserted_at, "{ISO:Extended}"),
|
||||||
|
"updated" => Timex.format!(note.updated_at, "{ISO:Extended}")
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.merge(event, @base)
|
||||||
|
end
|
||||||
|
|
||||||
def render("category.json", %{category: category}) do
|
def render("category.json", %{category: category}) do
|
||||||
%{"title" => category.title}
|
%{"title" => category.title}
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Eventos.Events
|
alias Eventos.Events
|
||||||
alias Eventos.Events.{Event, Category}
|
alias Eventos.Events.{Event, Category, Comment}
|
||||||
alias Eventos.Service.ActivityPub.Transmogrifier
|
alias Eventos.Service.ActivityPub.Transmogrifier
|
||||||
alias Eventos.Service.WebFinger
|
alias Eventos.Service.WebFinger
|
||||||
alias Eventos.Activity
|
alias Eventos.Activity
|
||||||
|
@ -44,12 +44,11 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_event_from_url(url) do
|
def fetch_object_from_url(url, :event), do: fetch_event_from_url(url)
|
||||||
if object = Events.get_event_by_url!(url) do
|
def fetch_object_from_url(url, :note), do: fetch_note_from_url(url)
|
||||||
{:ok, object}
|
|
||||||
else
|
|
||||||
Logger.info("Fetching #{url} via AP")
|
|
||||||
|
|
||||||
|
@spec fetch_object_from_url(String.t()) :: tuple()
|
||||||
|
def fetch_object_from_url(url) do
|
||||||
with true <- String.starts_with?(url, "http"),
|
with true <- String.starts_with?(url, "http"),
|
||||||
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
|
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
|
||||||
HTTPoison.get(
|
HTTPoison.get(
|
||||||
|
@ -60,7 +59,8 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
recv_timeout: 20_000
|
recv_timeout: 20_000
|
||||||
),
|
),
|
||||||
{:ok, data} <- Jason.decode(body),
|
{:ok, data} <- Jason.decode(body),
|
||||||
nil <- Events.get_event_by_url!(data["id"]),
|
nil <- Events.get_event_by_url(data["id"]),
|
||||||
|
nil <- Events.get_comment_from_url(data["id"]),
|
||||||
params <- %{
|
params <- %{
|
||||||
"type" => "Create",
|
"type" => "Create",
|
||||||
"to" => data["to"],
|
"to" => data["to"],
|
||||||
|
@ -69,12 +69,41 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
"object" => data
|
"object" => data
|
||||||
},
|
},
|
||||||
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
|
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
|
||||||
|
case data["type"] do
|
||||||
|
"Event" ->
|
||||||
{:ok, Events.get_event_by_url!(activity.data["object"]["id"])}
|
{:ok, Events.get_event_by_url!(activity.data["object"]["id"])}
|
||||||
|
|
||||||
|
"Note" ->
|
||||||
|
{:ok, Events.get_comment_from_url!(activity.data["object"]["id"])}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
object = %Event{} -> {:ok, object}
|
object = %Event{} -> {:ok, object}
|
||||||
e -> e
|
object = %Comment{} -> {:ok, object}
|
||||||
|
e -> {:error, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec fetch_object_from_url(String.t()) :: tuple()
|
||||||
|
def fetch_event_from_url(url) do
|
||||||
|
with nil <- Events.get_event_by_url(url) do
|
||||||
|
Logger.info("Fetching #{url} via AP")
|
||||||
|
fetch_object_from_url(url)
|
||||||
|
else
|
||||||
|
%Event{} = comment ->
|
||||||
|
{:ok, comment}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec fetch_object_from_url(String.t()) :: tuple()
|
||||||
|
def fetch_note_from_url(url) do
|
||||||
|
with nil <- Events.get_comment_from_url(url) do
|
||||||
|
Logger.info("Fetching #{url} via AP")
|
||||||
|
|
||||||
|
fetch_object_from_url(url)
|
||||||
|
else
|
||||||
|
%Comment{} = comment ->
|
||||||
|
{:ok, comment}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(%{to: to, actor: actor, context: context, object: object} = params) do
|
def create(%{to: to, actor: actor, context: context, object: object} = params) do
|
||||||
|
@ -127,7 +156,7 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
def follow(%Actor{} = follower, %Actor{} = followed, activity_id \\ nil, local \\ true) do
|
||||||
with data <- make_follow_data(follower, followed, activity_id),
|
with data <- make_follow_data(follower, followed, activity_id),
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
|
@ -135,7 +164,9 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(%Event{url: url, organizer_actor: actor} = event, local \\ true) do
|
def delete(object, local \\ true)
|
||||||
|
|
||||||
|
def delete(%Event{url: url, organizer_actor: actor} = event, local) do
|
||||||
data = %{
|
data = %{
|
||||||
"type" => "Delete",
|
"type" => "Delete",
|
||||||
"actor" => actor.url,
|
"actor" => actor.url,
|
||||||
|
@ -150,6 +181,21 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete(%Comment{url: url, actor: actor} = comment, local) do
|
||||||
|
data = %{
|
||||||
|
"type" => "Delete",
|
||||||
|
"actor" => actor.url,
|
||||||
|
"object" => url,
|
||||||
|
"to" => [actor.url <> "/followers", "https://www.w3.org/ns/activitystreams#Public"]
|
||||||
|
}
|
||||||
|
|
||||||
|
with Events.delete_comment(comment),
|
||||||
|
{:ok, activity} <- insert(data, local),
|
||||||
|
:ok <- maybe_federate(activity) do
|
||||||
|
{:ok, activity}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create_public_activities(%Actor{} = actor) do
|
def create_public_activities(%Actor{} = actor) do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -285,13 +331,22 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
case actor.type do
|
case actor.type do
|
||||||
:Person ->
|
:Person ->
|
||||||
{:ok, events, total} = Events.get_events_for_actor(actor, page, limit)
|
{:ok, events, total} = Events.get_events_for_actor(actor, page, limit)
|
||||||
|
{:ok, comments, total} = Events.get_comments_for_actor(actor, page, limit)
|
||||||
|
|
||||||
activities =
|
event_activities =
|
||||||
Enum.map(events, fn event ->
|
Enum.map(events, fn event ->
|
||||||
{:ok, activity} = event_to_activity(event)
|
{:ok, activity} = event_to_activity(event)
|
||||||
activity
|
activity
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
comment_activities =
|
||||||
|
Enum.map(comments, fn comment ->
|
||||||
|
{:ok, activity} = comment_to_activity(comment)
|
||||||
|
activity
|
||||||
|
end)
|
||||||
|
|
||||||
|
activities = event_activities ++ comment_activities
|
||||||
|
|
||||||
{activities, total}
|
{activities, total}
|
||||||
|
|
||||||
:Service ->
|
:Service ->
|
||||||
|
@ -322,6 +377,7 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
|
|
||||||
defp event_to_activity(%Event{} = event, local \\ true) do
|
defp event_to_activity(%Event{} = event, local \\ true) do
|
||||||
activity = %Activity{
|
activity = %Activity{
|
||||||
|
type: :Event,
|
||||||
data: event,
|
data: event,
|
||||||
local: local,
|
local: local,
|
||||||
actor: event.organizer_actor.url,
|
actor: event.organizer_actor.url,
|
||||||
|
@ -333,6 +389,20 @@ defmodule Eventos.Service.ActivityPub do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp comment_to_activity(%Comment{} = comment, local \\ true) do
|
||||||
|
activity = %Activity{
|
||||||
|
type: :Comment,
|
||||||
|
data: comment,
|
||||||
|
local: local,
|
||||||
|
actor: comment.actor.url,
|
||||||
|
recipients: ["https://www.w3.org/ns/activitystreams#Public"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Notification.create_notifications(activity)
|
||||||
|
# stream_out(activity)
|
||||||
|
{:ok, activity}
|
||||||
|
end
|
||||||
|
|
||||||
defp ical_event_to_activity(%ExIcal.Event{} = ical_event, %Actor{} = actor, source) do
|
defp ical_event_to_activity(%ExIcal.Event{} = ical_event, %Actor{} = actor, source) do
|
||||||
# Logger.debug(inspect ical_event)
|
# Logger.debug(inspect ical_event)
|
||||||
# TODO : refactor me !
|
# TODO : refactor me !
|
||||||
|
|
|
@ -4,7 +4,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
|
||||||
"""
|
"""
|
||||||
alias Eventos.Actors.Actor
|
alias Eventos.Actors.Actor
|
||||||
alias Eventos.Actors
|
alias Eventos.Actors
|
||||||
alias Eventos.Events.Event
|
alias Eventos.Events.{Event, Comment}
|
||||||
alias Eventos.Service.ActivityPub
|
alias Eventos.Service.ActivityPub
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
@ -77,9 +77,9 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
|
||||||
# - tags
|
# - tags
|
||||||
# - emoji
|
# - emoji
|
||||||
def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do
|
def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do
|
||||||
Logger.debug("Handle incoming to create notes")
|
Logger.info("Handle incoming to create notes")
|
||||||
|
|
||||||
with %Actor{} = actor <- Actor.get_or_fetch_by_url(data["actor"]) do
|
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(data["actor"]) do
|
||||||
Logger.debug("found actor")
|
Logger.debug("found actor")
|
||||||
object = fix_object(data["object"])
|
object = fix_object(data["object"])
|
||||||
|
|
||||||
|
@ -104,8 +104,8 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data
|
%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data
|
||||||
) do
|
) do
|
||||||
with %Actor{} = followed <- Actors.get_actor_by_url(followed),
|
with {:ok, %Actor{} = followed} <- Actors.get_or_fetch_by_url(followed),
|
||||||
%Actor{} = follower <- Actors.get_or_fetch_by_url(follower),
|
{:ok, %Actor{} = follower} <- Actors.get_or_fetch_by_url(follower),
|
||||||
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
|
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
|
||||||
ActivityPub.accept(%{to: [follower.url], actor: followed.url, object: data, local: true})
|
ActivityPub.accept(%{to: [follower.url], actor: followed.url, object: data, local: true})
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data
|
%{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data
|
||||||
) do
|
) do
|
||||||
with %Actor{} = actor <- Actors.get_or_fetch_by_url(actor),
|
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(actor),
|
||||||
{:ok, object} <-
|
{:ok, object} <-
|
||||||
get_obj_helper(object_id) || ActivityPub.fetch_event_from_url(object_id),
|
get_obj_helper(object_id) || ActivityPub.fetch_event_from_url(object_id),
|
||||||
{:ok, activity, object} <- ActivityPub.announce(actor, object, id, false) do
|
{:ok, activity, object} <- ActivityPub.announce(actor, object, id, false) do
|
||||||
|
@ -268,6 +268,17 @@ defmodule Eventos.Service.ActivityPub.Transmogrifier do
|
||||||
{:ok, event}
|
{:ok, event}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def prepare_outgoing(%Comment{} = comment) do
|
||||||
|
comment =
|
||||||
|
comment
|
||||||
|
|> Map.from_struct()
|
||||||
|
|> Map.drop([:__meta__])
|
||||||
|
|> Map.put(:"@context", "https://www.w3.org/ns/activitystreams")
|
||||||
|
|> prepare_object
|
||||||
|
|
||||||
|
{:ok, comment}
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# def maybe_fix_object_url(data) do
|
# def maybe_fix_object_url(data) do
|
||||||
# if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do
|
# if is_binary(data["object"]) and not String.starts_with?(data["object"], "http") do
|
||||||
|
|
|
@ -132,22 +132,25 @@ defmodule Eventos.Service.ActivityPub.Utils do
|
||||||
"""
|
"""
|
||||||
def insert_full_object(%{"object" => %{"type" => type} = object_data})
|
def insert_full_object(%{"object" => %{"type" => type} = object_data})
|
||||||
when is_map(object_data) and type == "Note" do
|
when is_map(object_data) and type == "Note" do
|
||||||
import Logger
|
with {:ok, %Actor{id: actor_id}} <- Actors.get_or_fetch_by_url(object_data["actor"]) do
|
||||||
Logger.debug("insert full object")
|
|
||||||
Logger.debug(inspect(object_data))
|
|
||||||
actor = Actors.get_actor_by_url(object_data["actor"])
|
|
||||||
|
|
||||||
data = %{
|
data = %{
|
||||||
"text" => object_data["content"],
|
"text" => object_data["content"],
|
||||||
"url" => object_data["id"],
|
"url" => object_data["id"],
|
||||||
"actor_id" => actor.id,
|
"actor_id" => actor_id,
|
||||||
"in_reply_to_comment_id" => object_data["inReplyTo"]
|
"in_reply_to_comment_id" => object_data["inReplyTo"]
|
||||||
}
|
}
|
||||||
|
|
||||||
with {:ok, _} <- Events.create_comment(data) do
|
require Logger
|
||||||
|
Logger.info("comment data ready to be inserted")
|
||||||
|
Logger.info(inspect(data))
|
||||||
|
|
||||||
|
with {:ok, comm} <- Events.create_comment(data) do
|
||||||
|
Logger.info("comment inserted")
|
||||||
|
Logger.info(inspect(comm))
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def insert_full_object(_), do: :ok
|
def insert_full_object(_), do: :ok
|
||||||
|
|
||||||
|
|
1
mix.exs
1
mix.exs
|
@ -65,7 +65,6 @@ defmodule Eventos.Mixfile do
|
||||||
{:timex_ecto, "~> 3.0"},
|
{:timex_ecto, "~> 3.0"},
|
||||||
{:icalendar, "~> 0.6"},
|
{:icalendar, "~> 0.6"},
|
||||||
{:exgravatar, "~> 2.0.1"},
|
{:exgravatar, "~> 2.0.1"},
|
||||||
{:littlefinger, "~> 0.1"},
|
|
||||||
{:httpoison, "~> 1.0"},
|
{:httpoison, "~> 1.0"},
|
||||||
{:json_ld, "~> 0.2"},
|
{:json_ld, "~> 0.2"},
|
||||||
{:jason, "~> 1.0"},
|
{:jason, "~> 1.0"},
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
defmodule Eventos.Repo.Migrations.AddPrimaryKeyToMember do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
execute("ALTER TABLE members DROP CONSTRAINT IF EXISTS members_pkey")
|
||||||
|
drop_if_exists index(:members, ["members_account_id_index"])
|
||||||
|
create unique_index(:members, [:actor_id, :parent_id], name: :members_actor_parent_unique_index)
|
||||||
|
alter table(:members) do
|
||||||
|
add :id, :serial, primary_key: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
drop index(:members, [:actor_id, :parent_id], name: :members_actor_parent_unique_index)
|
||||||
|
alter table(:members) do
|
||||||
|
remove :id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,7 +9,7 @@ defmodule Eventos.ActorsTest do
|
||||||
|
|
||||||
@valid_attrs %{
|
@valid_attrs %{
|
||||||
summary: "some description",
|
summary: "some description",
|
||||||
name: "some name",
|
name: "Bobby Blank",
|
||||||
domain: "some domain",
|
domain: "some domain",
|
||||||
keys: "some keypair",
|
keys: "some keypair",
|
||||||
suspended: true,
|
suspended: true,
|
||||||
|
@ -74,7 +74,7 @@ defmodule Eventos.ActorsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_actor_by_name/1 returns a remote actor" do
|
test "get_actor_by_name/1 returns a remote actor" do
|
||||||
assert %Actor{} = actor = Actors.get_or_fetch_by_url(@remote_account_url)
|
assert {:ok, %Actor{} = actor} = Actors.get_or_fetch_by_url(@remote_account_url)
|
||||||
actor_found = Actors.get_actor_by_name("#{actor.preferred_username}@#{actor.domain}")
|
actor_found = Actors.get_actor_by_name("#{actor.preferred_username}@#{actor.domain}")
|
||||||
assert actor_found = actor
|
assert actor_found = actor
|
||||||
end
|
end
|
||||||
|
@ -107,7 +107,7 @@ defmodule Eventos.ActorsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_actor_by_name_with_everything!/1 returns the remote actor with it's organized events" do
|
test "get_actor_by_name_with_everything!/1 returns the remote actor with it's organized events" do
|
||||||
assert %Actor{} = actor = Actors.get_or_fetch_by_url(@remote_account_url)
|
assert {:ok, %Actor{} = actor} = Actors.get_or_fetch_by_url(@remote_account_url)
|
||||||
|
|
||||||
assert Actors.get_actor_by_name_with_everything(
|
assert Actors.get_actor_by_name_with_everything(
|
||||||
"#{actor.preferred_username}@#{actor.domain}"
|
"#{actor.preferred_username}@#{actor.domain}"
|
||||||
|
@ -124,12 +124,15 @@ defmodule Eventos.ActorsTest do
|
||||||
test "get_or_fetch_by_url/1 returns the local actor for the url", %{
|
test "get_or_fetch_by_url/1 returns the local actor for the url", %{
|
||||||
actor: actor
|
actor: actor
|
||||||
} do
|
} do
|
||||||
assert Actors.get_or_fetch_by_url(actor.url).preferred_username == actor.preferred_username
|
preferred_username = actor.preferred_username
|
||||||
assert Actors.get_or_fetch_by_url(actor.url).domain == nil
|
|
||||||
|
assert {:ok, %Actor{preferred_username: preferred_username, domain: nil} = actor_found} =
|
||||||
|
Actors.get_or_fetch_by_url(actor.url)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_or_fetch_by_url/1 returns the remote actor for the url" do
|
test "get_or_fetch_by_url/1 returns the remote actor for the url" do
|
||||||
assert %Actor{preferred_username: @remote_account_username, domain: @remote_account_domain} =
|
assert {:ok,
|
||||||
|
%Actor{preferred_username: @remote_account_username, domain: @remote_account_domain}} =
|
||||||
Actors.get_or_fetch_by_url(@remote_account_url)
|
Actors.get_or_fetch_by_url(@remote_account_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -141,12 +144,21 @@ defmodule Eventos.ActorsTest do
|
||||||
assert actors = [actor, actor2]
|
assert actors = [actor, actor2]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "test find_actors_by_username/1 returns actors with similar usernames", %{actor: actor} do
|
test "test find_actors_by_username_or_name/1 returns actors with similar usernames", %{
|
||||||
%Actor{} = actor2 = Actors.get_or_fetch_by_url(@remote_account_url)
|
actor: actor
|
||||||
actors = Actors.find_actors_by_username("t")
|
} do
|
||||||
|
{:ok, %Actor{} = actor2} = Actors.get_or_fetch_by_url(@remote_account_url)
|
||||||
|
actors = Actors.find_actors_by_username_or_name("t")
|
||||||
assert actors = [actor, actor2]
|
assert actors = [actor, actor2]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "test find_actors_by_username_or_name/1 returns actors with similar names", %{
|
||||||
|
actor: actor
|
||||||
|
} do
|
||||||
|
actors = Actors.find_actors_by_username_or_name("ohno")
|
||||||
|
assert actors == []
|
||||||
|
end
|
||||||
|
|
||||||
test "test search/1 returns accounts for search with existing accounts", %{actor: actor} do
|
test "test search/1 returns accounts for search with existing accounts", %{actor: actor} do
|
||||||
assert {:ok, [actor]} = Actors.search("t")
|
assert {:ok, [actor]} = Actors.search("t")
|
||||||
end
|
end
|
||||||
|
@ -180,7 +192,7 @@ defmodule Eventos.ActorsTest do
|
||||||
test "create_actor/1 with valid data creates a actor" do
|
test "create_actor/1 with valid data creates a actor" do
|
||||||
assert {:ok, %Actor{} = actor} = Actors.create_actor(@valid_attrs)
|
assert {:ok, %Actor{} = actor} = Actors.create_actor(@valid_attrs)
|
||||||
assert actor.summary == "some description"
|
assert actor.summary == "some description"
|
||||||
assert actor.name == "some name"
|
assert actor.name == "Bobby Blank"
|
||||||
assert actor.domain == "some domain"
|
assert actor.domain == "some domain"
|
||||||
assert actor.keys == "some keypair"
|
assert actor.keys == "some keypair"
|
||||||
assert actor.suspended
|
assert actor.suspended
|
||||||
|
@ -484,4 +496,97 @@ defmodule Eventos.ActorsTest do
|
||||||
assert %Ecto.Changeset{} = Actors.change_follower(follower)
|
assert %Ecto.Changeset{} = Actors.change_follower(follower)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "members" do
|
||||||
|
alias Eventos.Actors.Member
|
||||||
|
alias Eventos.Actors.Actor
|
||||||
|
|
||||||
|
@valid_attrs %{approved: true, role: 0}
|
||||||
|
@update_attrs %{approved: false, role: 1}
|
||||||
|
@invalid_attrs %{approved: nil, role: nil}
|
||||||
|
|
||||||
|
setup do
|
||||||
|
actor = insert(:actor)
|
||||||
|
group = insert(:group)
|
||||||
|
{:ok, actor: actor, group: group}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp create_member(%{actor: actor, group: group}) do
|
||||||
|
insert(:member, actor: actor, parent: group)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_member!/1 returns the member with given id", context do
|
||||||
|
member = create_member(context)
|
||||||
|
assert member = Actors.get_member!(member.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_member/1 with valid data creates a member", %{
|
||||||
|
actor: actor,
|
||||||
|
group: group
|
||||||
|
} do
|
||||||
|
valid_attrs =
|
||||||
|
@valid_attrs
|
||||||
|
|> Map.put(:actor_id, actor.id)
|
||||||
|
|> Map.put(:parent_id, group.id)
|
||||||
|
|
||||||
|
assert {:ok, %Member{} = member} = Actors.create_member(valid_attrs)
|
||||||
|
assert member.approved == true
|
||||||
|
assert member.role == 0
|
||||||
|
|
||||||
|
assert [group] = Actor.get_groups_member_of(actor)
|
||||||
|
assert [actor] = Actor.get_members_for_group(group)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_member/1 with valid data but same actors fails to create a member", %{
|
||||||
|
actor: actor,
|
||||||
|
group: group
|
||||||
|
} do
|
||||||
|
create_member(%{actor: actor, group: group})
|
||||||
|
|
||||||
|
valid_attrs =
|
||||||
|
@valid_attrs
|
||||||
|
|> Map.put(:actor_id, actor.id)
|
||||||
|
|> Map.put(:parent_id, group.id)
|
||||||
|
|
||||||
|
assert {:error, _member} = Actors.create_member(valid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_member/1 with invalid data returns error changeset", %{
|
||||||
|
actor: actor,
|
||||||
|
group: group
|
||||||
|
} do
|
||||||
|
invalid_attrs =
|
||||||
|
@invalid_attrs
|
||||||
|
|> Map.put(:actor_id, nil)
|
||||||
|
|> Map.put(:parent_id, nil)
|
||||||
|
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Actors.create_member(invalid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_member/2 with valid data updates the member", context do
|
||||||
|
member = create_member(context)
|
||||||
|
assert {:ok, member} = Actors.update_member(member, @update_attrs)
|
||||||
|
assert %Member{} = member
|
||||||
|
assert member.approved == false
|
||||||
|
assert member.role == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# This can't happen, since attrs are optional
|
||||||
|
# test "update_member/2 with invalid data returns error changeset", context do
|
||||||
|
# member = create_member(context)
|
||||||
|
# assert {:error, %Ecto.Changeset{}} = Actors.update_member(member, @invalid_attrs)
|
||||||
|
# assert member = Actors.get_member!(member.id)
|
||||||
|
# end
|
||||||
|
|
||||||
|
test "delete_member/1 deletes the member", context do
|
||||||
|
member = create_member(context)
|
||||||
|
assert {:ok, %Member{}} = Actors.delete_member(member)
|
||||||
|
assert_raise Ecto.NoResultsError, fn -> Actors.get_member!(member.id) end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "change_member/1 returns a member changeset", context do
|
||||||
|
member = create_member(context)
|
||||||
|
assert %Ecto.Changeset{} = Actors.change_member(member)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,12 @@ defmodule Eventos.EventsTest do
|
||||||
describe "events" do
|
describe "events" do
|
||||||
alias Eventos.Events.Event
|
alias Eventos.Events.Event
|
||||||
|
|
||||||
|
setup do
|
||||||
|
actor = insert(:actor)
|
||||||
|
event = insert(:event, organizer_actor: actor)
|
||||||
|
{:ok, actor: actor, event: event}
|
||||||
|
end
|
||||||
|
|
||||||
@valid_attrs %{
|
@valid_attrs %{
|
||||||
begins_on: "2010-04-17 14:00:00.000000Z",
|
begins_on: "2010-04-17 14:00:00.000000Z",
|
||||||
description: "some description",
|
description: "some description",
|
||||||
|
@ -46,14 +52,32 @@ defmodule Eventos.EventsTest do
|
||||||
}
|
}
|
||||||
@invalid_attrs %{begins_on: nil, description: nil, ends_on: nil, title: nil}
|
@invalid_attrs %{begins_on: nil, description: nil, ends_on: nil, title: nil}
|
||||||
|
|
||||||
test "list_events/0 returns all events" do
|
test "list_events/0 returns all events", %{event: event} do
|
||||||
event = event_fixture()
|
assert event.title == hd(Events.list_events()).title
|
||||||
assert hd(Events.list_events()).title == event.title
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_event!/1 returns the event with given id" do
|
test "get_event!/1 returns the event with given id", %{event: event} do
|
||||||
event = event_fixture()
|
|
||||||
assert Events.get_event!(event.id).title == event.title
|
assert Events.get_event!(event.id).title == event.title
|
||||||
|
refute Ecto.assoc_loaded?(Events.get_event!(event.id).organizer_actor)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_event_full!/1 returns the event with given id", %{event: event} do
|
||||||
|
assert Events.get_event_full!(event.id).organizer_actor.preferred_username ==
|
||||||
|
event.organizer_actor.preferred_username
|
||||||
|
|
||||||
|
assert Events.get_event_full!(event.id).participants == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "find_events_by_name/1 returns events for a given name", %{event: event} do
|
||||||
|
assert event.title == hd(Events.find_events_by_name(event.title)).title
|
||||||
|
|
||||||
|
event2 = insert(:event, title: "Special event")
|
||||||
|
assert event2.title == hd(Events.find_events_by_name("Special")).title
|
||||||
|
|
||||||
|
event2 = insert(:event, title: "Special event")
|
||||||
|
assert event2.title == hd(Events.find_events_by_name(" Special ")).title
|
||||||
|
|
||||||
|
assert [] == Events.find_events_by_name("")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_event/1 with valid data creates a event" do
|
test "create_event/1 with valid data creates a event" do
|
||||||
|
@ -79,8 +103,7 @@ defmodule Eventos.EventsTest do
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.create_event(@invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.create_event(@invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_event/2 with valid data updates the event" do
|
test "update_event/2 with valid data updates the event", %{event: event} do
|
||||||
event = event_fixture()
|
|
||||||
assert {:ok, event} = Events.update_event(event, @update_attrs)
|
assert {:ok, event} = Events.update_event(event, @update_attrs)
|
||||||
assert %Event{} = event
|
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:01.000000Z], "Etc/UTC")
|
||||||
|
@ -89,27 +112,44 @@ defmodule Eventos.EventsTest do
|
||||||
assert event.title == "some updated title"
|
assert event.title == "some updated title"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_event/2 with invalid data returns error changeset" do
|
test "update_event/2 with invalid data returns error changeset", %{event: event} do
|
||||||
event = event_fixture()
|
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.update_event(event, @invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.update_event(event, @invalid_attrs)
|
||||||
assert event.title == Events.get_event!(event.id).title
|
assert event.title == Events.get_event!(event.id).title
|
||||||
end
|
end
|
||||||
|
|
||||||
test "delete_event/1 deletes the event" do
|
test "delete_event/1 deletes the event", %{event: event} do
|
||||||
event = event_fixture()
|
|
||||||
assert {:ok, %Event{}} = Events.delete_event(event)
|
assert {:ok, %Event{}} = Events.delete_event(event)
|
||||||
assert_raise Ecto.NoResultsError, fn -> Events.get_event!(event.id) end
|
assert_raise Ecto.NoResultsError, fn -> Events.get_event!(event.id) end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "change_event/1 returns a event changeset" do
|
test "change_event/1 returns a event changeset", %{event: event} do
|
||||||
event = event_fixture()
|
|
||||||
assert %Ecto.Changeset{} = Events.change_event(event)
|
assert %Ecto.Changeset{} = Events.change_event(event)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "get_events_for_actor/1", %{actor: actor, event: event} do
|
||||||
|
assert {:ok, [event_found], 1} = Events.get_events_for_actor(actor)
|
||||||
|
assert event_found.title == event.title
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_events_for_actor/3", %{actor: actor, event: event} do
|
||||||
|
event1 = insert(:event, organizer_actor: actor)
|
||||||
|
assert {:ok, [event_found, event1_found], 2} = Events.get_events_for_actor(actor, 1, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_events_for_actor/3 with limited results", %{actor: actor, event: event} do
|
||||||
|
event1 = insert(:event, organizer_actor: actor)
|
||||||
|
assert {:ok, [event_found], 2} = Events.get_events_for_actor(actor, 1, 1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "categories" do
|
describe "categories" do
|
||||||
alias Eventos.Events.Category
|
alias Eventos.Events.Category
|
||||||
|
|
||||||
|
setup do
|
||||||
|
category = insert(:category)
|
||||||
|
{:ok, category: category}
|
||||||
|
end
|
||||||
|
|
||||||
@valid_attrs %{description: "some description", picture: "some picture", title: "some title"}
|
@valid_attrs %{description: "some description", picture: "some picture", title: "some title"}
|
||||||
@update_attrs %{
|
@update_attrs %{
|
||||||
description: "some updated description",
|
description: "some updated description",
|
||||||
|
@ -118,16 +158,18 @@ defmodule Eventos.EventsTest do
|
||||||
}
|
}
|
||||||
@invalid_attrs %{description: nil, picture: nil, title: nil}
|
@invalid_attrs %{description: nil, picture: nil, title: nil}
|
||||||
|
|
||||||
test "list_categories/0 returns all categories" do
|
test "list_categories/0 returns all categories", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert Events.list_categories() == [category]
|
assert Events.list_categories() == [category]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_category!/1 returns the category with given id" do
|
test "get_category!/1 returns the category with given id", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert Events.get_category!(category.id) == category
|
assert Events.get_category!(category.id) == category
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "get_category_by_title/1 return the category with given title", %{category: category} do
|
||||||
|
assert Events.get_category_by_title(category.title) == category
|
||||||
|
end
|
||||||
|
|
||||||
test "create_category/1 with valid data creates a category" do
|
test "create_category/1 with valid data creates a category" do
|
||||||
assert {:ok, %Category{} = category} = Events.create_category(@valid_attrs)
|
assert {:ok, %Category{} = category} = Events.create_category(@valid_attrs)
|
||||||
assert category.description == "some description"
|
assert category.description == "some description"
|
||||||
|
@ -139,8 +181,7 @@ defmodule Eventos.EventsTest do
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.create_category(@invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.create_category(@invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_category/2 with valid data updates the category" do
|
test "update_category/2 with valid data updates the category", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert {:ok, category} = Events.update_category(category, @update_attrs)
|
assert {:ok, category} = Events.update_category(category, @update_attrs)
|
||||||
assert %Category{} = category
|
assert %Category{} = category
|
||||||
assert category.description == "some updated description"
|
assert category.description == "some updated description"
|
||||||
|
@ -148,20 +189,17 @@ defmodule Eventos.EventsTest do
|
||||||
assert category.title == "some updated title"
|
assert category.title == "some updated title"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_category/2 with invalid data returns error changeset" do
|
test "update_category/2 with invalid data returns error changeset", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.update_category(category, @invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.update_category(category, @invalid_attrs)
|
||||||
assert category == Events.get_category!(category.id)
|
assert category == Events.get_category!(category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "delete_category/1 deletes the category" do
|
test "delete_category/1 deletes the category", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert {:ok, %Category{}} = Events.delete_category(category)
|
assert {:ok, %Category{}} = Events.delete_category(category)
|
||||||
assert_raise Ecto.NoResultsError, fn -> Events.get_category!(category.id) end
|
assert_raise Ecto.NoResultsError, fn -> Events.get_category!(category.id) end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "change_category/1 returns a category changeset" do
|
test "change_category/1 returns a category changeset", %{category: category} do
|
||||||
category = category_fixture()
|
|
||||||
assert %Ecto.Changeset{} = Events.change_category(category)
|
assert %Ecto.Changeset{} = Events.change_category(category)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -227,35 +265,31 @@ defmodule Eventos.EventsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "participants" do
|
describe "participants" do
|
||||||
alias Eventos.Events.Participant
|
alias Eventos.Events.{Participant, Event}
|
||||||
|
alias Eventos.Actors.Actor
|
||||||
|
|
||||||
@valid_attrs %{role: 42}
|
@valid_attrs %{role: 42}
|
||||||
@update_attrs %{role: 43}
|
@update_attrs %{role: 43}
|
||||||
@invalid_attrs %{role: nil}
|
@invalid_attrs %{role: nil}
|
||||||
|
|
||||||
def participant_fixture(attrs \\ %{}) do
|
setup do
|
||||||
event = event_fixture()
|
actor = insert(:actor)
|
||||||
actor = actor_fixture()
|
event = insert(:event, organizer_actor: actor)
|
||||||
valid_attrs = Map.put(@valid_attrs, :event_id, event.id)
|
participant = insert(:participant, actor: actor, event: event)
|
||||||
valid_attrs = Map.put(valid_attrs, :actor_id, actor.id)
|
{:ok, participant: participant, event: event, actor: actor}
|
||||||
|
|
||||||
{:ok, participant} =
|
|
||||||
attrs
|
|
||||||
|> Enum.into(valid_attrs)
|
|
||||||
|> Events.create_participant()
|
|
||||||
|
|
||||||
participant
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "list_participants/0 returns all participants" do
|
test "list_participants/0 returns all participants", %{participant: participant} do
|
||||||
participant = participant_fixture()
|
assert [%Participant{} = participant] = Events.list_participants()
|
||||||
assert Events.list_participants() == [participant]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# test "get_participant!/1 returns the participant with given id" do
|
test "get_participant!/1 returns the participant for a given event and given actor", %{
|
||||||
# participant = participant_fixture()
|
event: %Event{id: event_id} = _event,
|
||||||
# assert Events.get_participant!(participant.id) == participant
|
actor: %Actor{id: actor_id} = _actor
|
||||||
# end
|
} do
|
||||||
|
assert %Participant{event_id: event_id, actor_id: actor_id} =
|
||||||
|
_participant = Events.get_participant!(event_id, actor_id)
|
||||||
|
end
|
||||||
|
|
||||||
test "create_participant/1 with valid data creates a participant" do
|
test "create_participant/1 with valid data creates a participant" do
|
||||||
actor = actor_fixture()
|
actor = actor_fixture()
|
||||||
|
@ -270,25 +304,25 @@ defmodule Eventos.EventsTest do
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.create_participant(@invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.create_participant(@invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_participant/2 with valid data updates the participant" do
|
test "update_participant/2 with valid data updates the participant", %{
|
||||||
participant = participant_fixture()
|
participant: participant
|
||||||
|
} do
|
||||||
assert {:ok, participant} = Events.update_participant(participant, @update_attrs)
|
assert {:ok, participant} = Events.update_participant(participant, @update_attrs)
|
||||||
assert %Participant{} = participant
|
assert %Participant{} = participant
|
||||||
assert participant.role == 43
|
assert participant.role == 43
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_participant/2 with invalid data returns error changeset" do
|
test "update_participant/2 with invalid data returns error changeset", %{
|
||||||
participant = participant_fixture()
|
participant: participant
|
||||||
|
} do
|
||||||
assert {:error, %Ecto.Changeset{}} = Events.update_participant(participant, @invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Events.update_participant(participant, @invalid_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "delete_participant/1 deletes the participant" do
|
test "delete_participant/1 deletes the participant", %{participant: participant} do
|
||||||
participant = participant_fixture()
|
|
||||||
assert {:ok, %Participant{}} = Events.delete_participant(participant)
|
assert {:ok, %Participant{}} = Events.delete_participant(participant)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "change_participant/1 returns a participant changeset" do
|
test "change_participant/1 returns a participant changeset", %{participant: participant} do
|
||||||
participant = participant_fixture()
|
|
||||||
assert %Ecto.Changeset{} = Events.change_participant(participant)
|
assert %Ecto.Changeset{} = Events.change_participant(participant)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,14 +5,20 @@ defmodule Eventos.Service.Activitypub.ActivitypubTest do
|
||||||
|
|
||||||
alias Eventos.Events
|
alias Eventos.Events
|
||||||
alias Eventos.Actors.Actor
|
alias Eventos.Actors.Actor
|
||||||
|
alias Eventos.Actors
|
||||||
alias Eventos.Service.ActivityPub
|
alias Eventos.Service.ActivityPub
|
||||||
alias Eventos.Activity
|
alias Eventos.Activity
|
||||||
|
|
||||||
describe "fetching actor from it's url" do
|
describe "fetching actor from it's url" do
|
||||||
test "returns an actor" do
|
test "returns an actor from nickname" do
|
||||||
assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"} = actor} =
|
assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"} = actor} =
|
||||||
ActivityPub.make_actor_from_nickname("tcit@framapiaf.org")
|
ActivityPub.make_actor_from_nickname("tcit@framapiaf.org")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns an actor from url" do
|
||||||
|
assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} =
|
||||||
|
Actors.get_or_fetch_by_url("https://framapiaf.org/users/tcit")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create activities" do
|
describe "create activities" do
|
||||||
|
@ -33,8 +39,8 @@ defmodule Eventos.Service.Activitypub.ActivitypubTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "fetching an object" do
|
describe "fetching an" do
|
||||||
test "it fetches an object" do
|
test "event by url" do
|
||||||
{:ok, object} =
|
{:ok, object} =
|
||||||
ActivityPub.fetch_event_from_url("https://social.tcit.fr/@tcit/99908779444618462")
|
ActivityPub.fetch_event_from_url("https://social.tcit.fr/@tcit/99908779444618462")
|
||||||
|
|
||||||
|
@ -55,7 +61,19 @@ defmodule Eventos.Service.Activitypub.ActivitypubTest do
|
||||||
assert delete.data["actor"] == event.organizer_actor.url
|
assert delete.data["actor"] == event.organizer_actor.url
|
||||||
assert delete.data["object"] == event.url
|
assert delete.data["object"] == event.url
|
||||||
|
|
||||||
assert Events.get_event_by_url!(event.url) == nil
|
assert Events.get_event_by_url(event.url) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it creates a delete activity and deletes the original comment" do
|
||||||
|
comment = insert(:comment)
|
||||||
|
comment = Events.get_comment_full_from_url!(comment.url)
|
||||||
|
{:ok, delete} = ActivityPub.delete(comment)
|
||||||
|
|
||||||
|
assert delete.data["type"] == "Delete"
|
||||||
|
assert delete.data["actor"] == comment.actor.url
|
||||||
|
assert delete.data["object"] == comment.url
|
||||||
|
|
||||||
|
assert Events.get_comment_from_url(comment.url) == nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ defmodule EventosWeb.ActivityPubControllerTest do
|
||||||
import Eventos.Factory
|
import Eventos.Factory
|
||||||
alias EventosWeb.ActivityPub.{ActorView, ObjectView}
|
alias EventosWeb.ActivityPub.{ActorView, ObjectView}
|
||||||
alias Eventos.{Repo, Actors, Actors.Actor}
|
alias Eventos.{Repo, Actors, Actors.Actor}
|
||||||
|
alias Eventos.Service.ActivityPub
|
||||||
alias Eventos.Activity
|
alias Eventos.Activity
|
||||||
import Logger
|
import Logger
|
||||||
|
|
||||||
describe "/@:username" do
|
describe "/@:preferred_username" do
|
||||||
test "it returns a json representation of the actor", %{conn: conn} do
|
test "it returns a json representation of the actor", %{conn: conn} do
|
||||||
actor = insert(:actor)
|
actor = insert(:actor)
|
||||||
|
|
||||||
|
@ -22,8 +23,8 @@ defmodule EventosWeb.ActivityPubControllerTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "/events/uuid" do
|
describe "/events/:uuid" do
|
||||||
test "it returns a json representation of the object", %{conn: conn} do
|
test "it returns a json representation of the event", %{conn: conn} do
|
||||||
event = insert(:event)
|
event = insert(:event)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -34,23 +35,60 @@ defmodule EventosWeb.ActivityPubControllerTest do
|
||||||
assert json_response(conn, 200) == ObjectView.render("event.json", %{event: event})
|
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
|
||||||
|
|
||||||
|
test "it returns 404 for non-public events", %{conn: conn} do
|
||||||
|
event = insert(:event, public: false)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/activity+json")
|
||||||
|
|> get("/events/#{event.uuid}")
|
||||||
|
|
||||||
|
assert json_response(conn, 404)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# describe "/actors/:username/inbox" do
|
describe "/@:preferred_username/inbox" do
|
||||||
# test "it inserts an incoming activity into the database", %{conn: conn} do
|
test "it inserts an incoming event into the database", %{conn: conn} do
|
||||||
# data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
||||||
#
|
|
||||||
# conn =
|
conn =
|
||||||
# conn
|
conn
|
||||||
# |> assign(:valid_signature, true)
|
|> assign(:valid_signature, true)
|
||||||
# |> put_req_header("content-type", "application/activity+json")
|
|> put_req_header("content-type", "application/activity+json")
|
||||||
# |> post("/inbox", data)
|
|> post("/inbox", data)
|
||||||
#
|
|
||||||
# assert "ok" == json_response(conn, 200)
|
assert "ok" == json_response(conn, 200)
|
||||||
# :timer.sleep(500)
|
:timer.sleep(500)
|
||||||
# assert Activity.get_by_ap_id(data["id"])
|
assert ActivityPub.fetch_object_from_url(data["object"]["id"], :note)
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
|
|
||||||
|
describe "/@:preferred_username/outbox" do
|
||||||
|
test "it returns a note activity in a collection", %{conn: conn} do
|
||||||
|
actor = insert(:actor)
|
||||||
|
comment = insert(:comment, actor: actor)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/activity+json")
|
||||||
|
|> get("/@#{actor.preferred_username}/outbox")
|
||||||
|
|
||||||
|
assert response(conn, 200) =~ comment.text
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns an event activity in a collection", %{conn: conn} do
|
||||||
|
actor = insert(:actor)
|
||||||
|
event = insert(:event, organizer_actor: actor)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/activity+json")
|
||||||
|
|> get("/@#{actor.preferred_username}/outbox")
|
||||||
|
|
||||||
|
assert response(conn, 200) =~ event.title
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# describe "/actors/:nickname/followers" do
|
# describe "/actors/:nickname/followers" do
|
||||||
# test "it returns the followers in a collection", %{conn: conn} do
|
# test "it returns the followers in a collection", %{conn: conn} do
|
||||||
|
@ -93,43 +131,43 @@ defmodule EventosWeb.ActivityPubControllerTest do
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# describe "/users/:nickname/following" do
|
# describe "/@:preferred_username/following" do
|
||||||
# test "it returns the following in a collection", %{conn: conn} do
|
# test "it returns the following in a collection", %{conn: conn} do
|
||||||
# user = insert(:user)
|
# actor = insert(:actor)
|
||||||
# user_two = insert(:user)
|
# actor2 = insert(:actor)
|
||||||
# User.follow(user, user_two)
|
# Eventos.Service.ActivityPub.follow(actor, actor2)
|
||||||
#
|
|
||||||
# result =
|
# result =
|
||||||
# conn
|
# conn
|
||||||
# |> get("/users/#{user.nickname}/following")
|
# |> get("/@#{actor.preferred_username}/following")
|
||||||
# |> json_response(200)
|
# |> json_response(200)
|
||||||
#
|
|
||||||
# assert result["first"]["orderedItems"] == [user_two.ap_id]
|
# assert result["first"]["orderedItems"] == [actor2.url]
|
||||||
# end
|
# end
|
||||||
#
|
|
||||||
# test "it works for more than 10 users", %{conn: conn} do
|
# test "it works for more than 10 actors", %{conn: conn} do
|
||||||
# user = insert(:user)
|
# actor = insert(:actor)
|
||||||
#
|
|
||||||
# Enum.each(1..15, fn _ ->
|
# Enum.each(1..15, fn _ ->
|
||||||
# user = Repo.get(User, user.id)
|
# actor = Repo.get(Actor, actor.id)
|
||||||
# other_user = insert(:user)
|
# other_actor = insert(:actor)
|
||||||
# User.follow(user, other_user)
|
# Actor.follow(actor, other_actor)
|
||||||
# end)
|
# end)
|
||||||
#
|
|
||||||
# result =
|
# result =
|
||||||
# conn
|
# conn
|
||||||
# |> get("/users/#{user.nickname}/following")
|
# |> get("/@#{actor.preferred_username}/following")
|
||||||
# |> json_response(200)
|
# |> json_response(200)
|
||||||
#
|
|
||||||
# assert length(result["first"]["orderedItems"]) == 10
|
# assert length(result["first"]["orderedItems"]) == 10
|
||||||
# assert result["first"]["totalItems"] == 15
|
# assert result["first"]["totalItems"] == 15
|
||||||
# assert result["totalItems"] == 15
|
# assert result["totalItems"] == 15
|
||||||
#
|
|
||||||
# result =
|
# result =
|
||||||
# conn
|
# conn
|
||||||
# |> get("/users/#{user.nickname}/following?page=2")
|
# |> get("/@#{actor.preferred_username}/following?page=2")
|
||||||
# |> json_response(200)
|
# |> json_response(200)
|
||||||
#
|
|
||||||
# assert length(result["orderedItems"]) == 5
|
# assert length(result["orderedItems"]) == 5
|
||||||
# assert result["totalItems"] == 15
|
# assert result["totalItems"] == 15
|
||||||
# end
|
# end
|
||||||
|
|
|
@ -31,6 +31,64 @@ defmodule EventosWeb.ActorControllerTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "show actor" do
|
||||||
|
test "show existing actor", %{conn: conn, actor: actor} do
|
||||||
|
actor_id = actor.id
|
||||||
|
conn = get(conn, actor_path(conn, :show, actor.preferred_username))
|
||||||
|
assert %{"data" => %{"id" => actor_id}} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "show non-existing actor", %{conn: conn, actor: actor} do
|
||||||
|
actor_id = actor.id
|
||||||
|
conn = get(conn, actor_path(conn, :show, "nonexisting"))
|
||||||
|
assert "" == response(conn, 404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "search for actors" do
|
||||||
|
test "search for existing actors", %{conn: conn, actor: actor} do
|
||||||
|
actor_username = actor.preferred_username
|
||||||
|
conn = get(conn, actor_path(conn, :search, actor_username))
|
||||||
|
assert %{"data" => [%{"username" => actor_username}]} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "search for existing actors with similar username", %{conn: conn, actor: actor} do
|
||||||
|
actor_username = actor.preferred_username
|
||||||
|
conn = get(conn, actor_path(conn, :search, "thom"))
|
||||||
|
assert %{"data" => [%{"username" => actor_username}]} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "search for nothing", %{conn: conn, actor: actor} do
|
||||||
|
actor_username = actor.preferred_username
|
||||||
|
conn = get(conn, actor_path(conn, :search, "nothing"))
|
||||||
|
assert %{"data" => []} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "update actor" do
|
||||||
|
test "update actor with valid attrs", %{conn: conn, user: user, actor: actor} do
|
||||||
|
conn = auth_conn(conn, user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
patch(conn, actor_path(conn, :update, actor.preferred_username), %{
|
||||||
|
"actor" => %{"name" => "glouglou"}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert %{"data" => %{"display_name" => "glouglou"}} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update actor with invalid attrs", %{conn: conn, user: user, actor: actor} do
|
||||||
|
conn = auth_conn(conn, user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
patch(conn, actor_path(conn, :update, actor.preferred_username), %{
|
||||||
|
"actor" => %{"preferred_username" => nil}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert json_response(conn, 422)["errors"] != %{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
###
|
###
|
||||||
# Not possible atm
|
# Not possible atm
|
||||||
###
|
###
|
||||||
|
|
|
@ -34,7 +34,7 @@ defmodule EventosWeb.AddressControllerTest do
|
||||||
floor: nil,
|
floor: nil,
|
||||||
postalCode: nil,
|
postalCode: nil,
|
||||||
streetAddress: nil,
|
streetAddress: nil,
|
||||||
geom: %{type: nil, data: %{latitude: nil, longitude: nil}}
|
geom: %{type: "oh no", data: %{latitude: nil, longitude: nil}}
|
||||||
}
|
}
|
||||||
|
|
||||||
def fixture(:address) do
|
def fixture(:address) do
|
||||||
|
|
|
@ -5,6 +5,7 @@ defmodule EventosWeb.UserControllerTest do
|
||||||
|
|
||||||
alias Eventos.Actors
|
alias Eventos.Actors
|
||||||
alias Eventos.Actors.User
|
alias Eventos.Actors.User
|
||||||
|
use Bamboo.Test
|
||||||
|
|
||||||
@create_attrs %{email: "foo@bar.tld", password: "some password_hash", username: "some username"}
|
@create_attrs %{email: "foo@bar.tld", password: "some password_hash", username: "some username"}
|
||||||
# @update_attrs %{email: "foo@fighters.tld", password: "some updated password_hash", username: "some updated username"}
|
# @update_attrs %{email: "foo@fighters.tld", password: "some updated password_hash", username: "some updated username"}
|
||||||
|
@ -18,7 +19,7 @@ defmodule EventosWeb.UserControllerTest do
|
||||||
setup %{conn: conn} do
|
setup %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
actor = insert(:actor, user: user)
|
actor = insert(:actor, user: user)
|
||||||
{:ok, conn: conn, user: user}
|
{:ok, conn: conn, user: user, actor: actor}
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "index" do
|
describe "index" do
|
||||||
|
@ -31,12 +32,14 @@ defmodule EventosWeb.UserControllerTest do
|
||||||
|
|
||||||
describe "create user" do
|
describe "create user" do
|
||||||
test "renders user when data is valid", %{conn: conn} 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, :register), @create_attrs)
|
||||||
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(@create_attrs.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
end
|
end
|
||||||
|
|
||||||
test "renders errors when data is invalid", %{conn: conn} do
|
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, :register), @invalid_attrs)
|
||||||
assert json_response(conn, 422)["errors"] != %{}
|
assert json_response(conn, 422)["errors"] != %{}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,11 +50,139 @@ defmodule EventosWeb.UserControllerTest do
|
||||||
username: "framasoft"
|
username: "framasoft"
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = post(conn, user_path(conn, :create), attrs)
|
conn = post(conn, user_path(conn, :register), attrs)
|
||||||
assert %{"email" => "contact@framasoft.org"} = json_response(conn, 201)
|
assert %{"email" => "contact@framasoft.org"} = json_response(conn, 201)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "validating user" do
|
||||||
|
test "validate user when token is valid", %{conn: conn} do
|
||||||
|
conn = post(conn, user_path(conn, :create), @create_attrs)
|
||||||
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(@create_attrs.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
|
|
||||||
|
conn = get(conn, user_path(conn, :validate, user.confirmation_token))
|
||||||
|
assert %{"user" => _, "token" => _} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "validate user when token is invalid", %{conn: conn} do
|
||||||
|
conn = post(conn, user_path(conn, :create), @create_attrs)
|
||||||
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(@create_attrs.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
|
|
||||||
|
conn = get(conn, user_path(conn, :validate, "toto"))
|
||||||
|
assert %{"error" => _} = json_response(conn, 404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "revalidating user" do
|
||||||
|
test "ask to resend token to user when too soon", %{conn: conn} do
|
||||||
|
conn = post(conn, user_path(conn, :create), @create_attrs)
|
||||||
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(@create_attrs.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
|
|
||||||
|
conn = post(conn, user_path(conn, :resend_confirmation), %{"email" => @create_attrs.email})
|
||||||
|
assert %{"error" => _} = json_response(conn, 404)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ask to resend token to user when the time is right", %{conn: conn} do
|
||||||
|
conn = post(conn, user_path(conn, :create), @create_attrs)
|
||||||
|
|
||||||
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 201)
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(@create_attrs.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
|
|
||||||
|
# Hammer time !
|
||||||
|
{:ok, %User{} = user} =
|
||||||
|
Eventos.Actors.update_user(user, %{
|
||||||
|
confirmation_sent_at: Timex.shift(user.confirmation_sent_at, hours: -3)
|
||||||
|
})
|
||||||
|
|
||||||
|
conn = post(conn, user_path(conn, :resend_confirmation), %{"email" => @create_attrs.email})
|
||||||
|
assert_delivered_email(Eventos.Email.User.confirmation_email(user))
|
||||||
|
assert %{"email" => "foo@bar.tld"} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "resetting user's password" do
|
||||||
|
test "ask for reset", %{conn: conn, user: user} do
|
||||||
|
user_email = user.email
|
||||||
|
|
||||||
|
# Send reset email
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => user_email})
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(user.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.reset_password_email(user))
|
||||||
|
assert %{"email" => user_email} = json_response(conn, 200)
|
||||||
|
|
||||||
|
# Call reset route
|
||||||
|
conn =
|
||||||
|
post(conn, user_path(conn, :reset_password), %{
|
||||||
|
"password" => "new password",
|
||||||
|
"token" => user.reset_password_token
|
||||||
|
})
|
||||||
|
|
||||||
|
user_id = user.id
|
||||||
|
assert %{"user" => %{"id" => user_id}} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ask twice for reset too soon", %{conn: conn, user: user} do
|
||||||
|
user_email = user.email
|
||||||
|
|
||||||
|
# Send reset email
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => user.email})
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(user.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.reset_password_email(user))
|
||||||
|
assert %{"email" => user_email} = json_response(conn, 200)
|
||||||
|
|
||||||
|
# Send reset email again
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => user.email})
|
||||||
|
|
||||||
|
assert %{"errors" => "You requested a new reset password too early"} =
|
||||||
|
json_response(conn, 404)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ask twice for reset after a while", %{conn: conn, user: user} do
|
||||||
|
user_email = user.email
|
||||||
|
|
||||||
|
# Send reset email
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => user.email})
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(user.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.reset_password_email(user))
|
||||||
|
assert %{"email" => user_email} = json_response(conn, 200)
|
||||||
|
|
||||||
|
# Hammer time !
|
||||||
|
{:ok, %User{} = user} =
|
||||||
|
Eventos.Actors.update_user(user, %{
|
||||||
|
reset_password_sent_at: Timex.shift(user.reset_password_sent_at, hours: -3)
|
||||||
|
})
|
||||||
|
|
||||||
|
# Send reset email again
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => user.email})
|
||||||
|
assert {:ok, %User{} = user} = Eventos.Actors.get_user_by_email(user.email)
|
||||||
|
assert_delivered_email(Eventos.Email.User.reset_password_email(user))
|
||||||
|
assert %{"email" => user_email} = json_response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "ask for reset with wrong address", %{conn: conn} do
|
||||||
|
conn = post(conn, user_path(conn, :send_reset_password), %{"email" => "yolo@coucou"})
|
||||||
|
assert %{"errors" => "Unable to find an user with this email"} = json_response(conn, 404)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "calling reset route with wrong token", %{conn: conn} do
|
||||||
|
conn =
|
||||||
|
post(conn, user_path(conn, :reset_password), %{
|
||||||
|
"password" => "new password",
|
||||||
|
"token" => "just wrong"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert %{"errors" => %{"token" => ["Wrong token for password reset"]}} =
|
||||||
|
json_response(conn, 404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# describe "update user" do
|
# describe "update user" do
|
||||||
# setup [:create_user]
|
# setup [:create_user]
|
||||||
#
|
#
|
||||||
|
|
65
test/fixtures/mastodon-post-activity.json
vendored
Normal file
65
test/fixtures/mastodon-post-activity.json
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
|
"Emoji": "toot:Emoji",
|
||||||
|
"Hashtag": "as:Hashtag",
|
||||||
|
"atomUri": "ostatus:atomUri",
|
||||||
|
"conversation": "ostatus:conversation",
|
||||||
|
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||||
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
|
"movedTo": "as:movedTo",
|
||||||
|
"ostatus": "http://ostatus.org#",
|
||||||
|
"sensitive": "as:sensitive",
|
||||||
|
"toot": "http://joinmastodon.org/ns#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actor": "http://framapiaf.org/users/admin",
|
||||||
|
"cc": [
|
||||||
|
"http://framapiaf.org/users/admin/followers",
|
||||||
|
"http://eventos.com/@tcit"
|
||||||
|
],
|
||||||
|
"id": "http://framapiaf.org/users/admin/statuses/99512778738411822/activity",
|
||||||
|
"nickname": "lain",
|
||||||
|
"object": {
|
||||||
|
"atomUri": "http://framapiaf.org/users/admin/statuses/99512778738411822",
|
||||||
|
"attachment": [],
|
||||||
|
"attributedTo": "http://framapiaf.org/users/admin",
|
||||||
|
"cc": [
|
||||||
|
"http://framapiaf.org/users/admin/followers",
|
||||||
|
"http://localtesting.pleroma.lol/users/lain"
|
||||||
|
],
|
||||||
|
"content": "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>",
|
||||||
|
"conversation": "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation",
|
||||||
|
"id": "http://framapiaf.org/users/admin/statuses/99512778738411822",
|
||||||
|
"inReplyTo": null,
|
||||||
|
"inReplyToAtomUri": null,
|
||||||
|
"published": "2018-02-12T14:08:20Z",
|
||||||
|
"sensitive": true,
|
||||||
|
"summary": "cw",
|
||||||
|
"tag": [
|
||||||
|
{
|
||||||
|
"href": "http://localtesting.pleroma.lol/users/lain",
|
||||||
|
"name": "@lain@localtesting.pleroma.lol",
|
||||||
|
"type": "Mention"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"type": "Note",
|
||||||
|
"url": "http://framapiaf.org/@admin/99512778738411822"
|
||||||
|
},
|
||||||
|
"published": "2018-02-12T14:08:20Z",
|
||||||
|
"signature": {
|
||||||
|
"created": "2018-02-12T14:08:20Z",
|
||||||
|
"creator": "http://framapiaf.org/users/admin#main-key",
|
||||||
|
"signatureValue": "rnNfcopkc6+Ju73P806popcfwrK9wGYHaJVG1/ZvrlEbWVDzaHjkXqj9Q3/xju5l8CSn9tvSgCCtPFqZsFQwn/pFIFUcw7ZWB2xi4bDm3NZ3S4XQ8JRaaX7og5hFxAhWkGhJhAkfxVnOg2hG+w2d/7d7vRVSC1vo5ip4erUaA/PkWusZvPIpxnRWoXaxJsFmVx0gJgjpJkYDyjaXUlp+jmaoseeZ4EPQUWqHLKJ59PRG0mg8j2xAjYH9nQaN14qMRmTGPxY8gfv/CUFcatA+8VJU9KEsJkDAwLVvglydNTLGrxpAJU78a2eaht0foV43XUIZGe3DKiJPgE+UOKGCJw==",
|
||||||
|
"type": "RsaSignature2017"
|
||||||
|
},
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"type": "Create"
|
||||||
|
}
|
|
@ -67,11 +67,14 @@ defmodule Eventos.Factory do
|
||||||
end
|
end
|
||||||
|
|
||||||
def comment_factory do
|
def comment_factory do
|
||||||
|
uuid = Ecto.UUID.generate()
|
||||||
|
|
||||||
%Eventos.Events.Comment{
|
%Eventos.Events.Comment{
|
||||||
text: "My Comment",
|
text: "My Comment",
|
||||||
actor: build(:actor),
|
actor: build(:actor),
|
||||||
event: build(:event),
|
event: build(:event),
|
||||||
uuid: Ecto.UUID.generate()
|
uuid: uuid,
|
||||||
|
url: "#{EventosWeb.Endpoint.url()}/comments/#{uuid}"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -86,10 +89,18 @@ defmodule Eventos.Factory do
|
||||||
organizer_actor: actor,
|
organizer_actor: actor,
|
||||||
category: build(:category),
|
category: build(:category),
|
||||||
physical_address: build(:address),
|
physical_address: build(:address),
|
||||||
|
public: true,
|
||||||
url: "#{EventosWeb.Endpoint.url()}/@#{actor.url}/#{Ecto.UUID.generate()}"
|
url: "#{EventosWeb.Endpoint.url()}/@#{actor.url}/#{Ecto.UUID.generate()}"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def participant_factory do
|
||||||
|
%Eventos.Events.Participant{
|
||||||
|
event: build(:event),
|
||||||
|
actor: build(:actor)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def session_factory do
|
def session_factory do
|
||||||
%Eventos.Events.Session{
|
%Eventos.Events.Session{
|
||||||
title: sequence("MySession"),
|
title: sequence("MySession"),
|
||||||
|
|
Loading…
Reference in a new issue