Merge branch 'improve-file-docs' into 'master'

Improve file docs

See merge request framasoft/mobilizon!800
This commit is contained in:
Thomas Citharel 2021-01-18 16:46:29 +01:00
commit e0d9762f36
6 changed files with 81 additions and 9 deletions

View File

@ -480,7 +480,7 @@ defmodule Mobilizon.Federation.ActivityPub do
"to" => [group_members_url], "to" => [group_members_url],
"type" => "Remove", "type" => "Remove",
"actor" => moderator_url, "actor" => moderator_url,
"object" => member.actor.url, "object" => member.url,
"origin" => group_url "origin" => group_url
}, },
{:ok, activity} <- create_activity(remove_data, local), {:ok, activity} <- create_activity(remove_data, local),

View File

@ -686,8 +686,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
with {:ok, %Actor{id: moderator_id} = moderator} <- with {:ok, %Actor{id: moderator_id} = moderator} <-
data |> Utils.get_actor() |> ActivityPub.get_or_fetch_actor_by_url(), data |> Utils.get_actor() |> ActivityPub.get_or_fetch_actor_by_url(),
{:ok, %Actor{id: person_id}} <- {:ok, person_id} <- get_remove_object(object),
object |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url(),
{:ok, %Actor{type: :Group, id: group_id} = group} <- {:ok, %Actor{type: :Group, id: group_id} = group} <-
origin |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url(), origin |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url(),
{:is_admin, {:ok, %Member{role: role}}} {:is_admin, {:ok, %Member{role: role}}}
@ -1084,4 +1083,16 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
err err
end end
end end
# Before 1.0.4 the object of a "Remove" activity was an actor's URL
# instead of the member's URL.
# TODO: Remove in 1.2
@spec get_remove_object(map() | String.t()) :: {:ok, String.t() | integer()}
defp get_remove_object(object) do
case object |> Utils.get_url() |> ActivityPub.fetch_object_from_url() do
{:ok, %Member{actor: %Actor{id: person_id}}} -> {:ok, person_id}
{:ok, %Actor{id: person_id}} -> {:ok, person_id}
_ -> {:error, :remove_object_not_found}
end
end
end end

View File

@ -55,6 +55,10 @@ defmodule Mobilizon.Discussions do
@public_visibility [:public, :unlisted] @public_visibility [:public, :unlisted]
@doc """
Callback for Absinthe Ecto Dataloader
"""
@spec data :: Dataloader.Ecto.t()
def data do def data do
Dataloader.Ecto.new(Repo, query: &query/2) Dataloader.Ecto.new(Repo, query: &query/2)
end end
@ -65,6 +69,7 @@ defmodule Mobilizon.Discussions do
We only get first comment of thread, and count replies. We only get first comment of thread, and count replies.
Read: https://hexdocs.pm/absinthe/ecto.html#dataloader Read: https://hexdocs.pm/absinthe/ecto.html#dataloader
""" """
@spec query(atom(), map()) :: Ecto.Queryable.t()
def query(Comment, _params) do def query(Comment, _params) do
Comment Comment
|> join(:left, [c], r in Comment, on: r.origin_comment_id == c.id) |> join(:left, [c], r in Comment, on: r.origin_comment_id == c.id)
@ -94,6 +99,9 @@ defmodule Mobilizon.Discussions do
@spec get_comment!(integer | String.t()) :: Comment.t() @spec get_comment!(integer | String.t()) :: Comment.t()
def get_comment!(id), do: Repo.get!(Comment, id) def get_comment!(id), do: Repo.get!(Comment, id)
@doc """
Get a single comment by it's ID and all associations preloaded
"""
@spec get_comment_with_preload(String.t() | integer() | nil) :: Comment.t() | nil @spec get_comment_with_preload(String.t() | integer() | nil) :: Comment.t() | nil
def get_comment_with_preload(nil), do: nil def get_comment_with_preload(nil), do: nil
@ -160,6 +168,10 @@ defmodule Mobilizon.Discussions do
|> Repo.preload(@comment_preloads) |> Repo.preload(@comment_preloads)
end end
@doc """
Get all comment threads under an event
"""
@spec get_threads(String.t() | integer()) :: [Comment.t()]
def get_threads(event_id) do def get_threads(event_id) do
Comment Comment
|> where([c, _], c.event_id == ^event_id and is_nil(c.origin_comment_id)) |> where([c, _], c.event_id == ^event_id and is_nil(c.origin_comment_id))
@ -179,6 +191,10 @@ defmodule Mobilizon.Discussions do
|> Repo.all() |> Repo.all()
end end
@doc """
Get a comment or create it
"""
@spec get_or_create_comment(map()) :: {:ok, Comment.t()}
def get_or_create_comment(%{"url" => url} = attrs) do def get_or_create_comment(%{"url" => url} = attrs) do
case Repo.get_by(Comment, url: url) do case Repo.get_by(Comment, url: url) do
%Comment{} = comment -> {:ok, Repo.preload(comment, @comment_preloads)} %Comment{} = comment -> {:ok, Repo.preload(comment, @comment_preloads)}
@ -239,6 +255,9 @@ defmodule Mobilizon.Discussions do
Repo.all(from(c in Comment, where: c.visibility == ^:public)) Repo.all(from(c in Comment, where: c.visibility == ^:public))
end end
@doc """
Returns a paginated list of local comments
"""
@spec list_local_comments(integer | nil, integer | nil) :: Page.t() @spec list_local_comments(integer | nil, integer | nil) :: Page.t()
def list_local_comments(page \\ nil, limit \\ nil) do def list_local_comments(page \\ nil, limit \\ nil) do
Comment Comment
@ -274,6 +293,9 @@ defmodule Mobilizon.Discussions do
|> Repo.all() |> Repo.all()
end end
@doc """
Get all the comments contained into a discussion
"""
@spec get_comments_for_discussion(integer, integer | nil, integer | nil) :: Page.t() @spec get_comments_for_discussion(integer, integer | nil, integer | nil) :: Page.t()
def get_comments_for_discussion(discussion_id, page \\ nil, limit \\ nil) do def get_comments_for_discussion(discussion_id, page \\ nil, limit \\ nil) do
Comment Comment
@ -302,12 +324,19 @@ defmodule Mobilizon.Discussions do
|> Repo.one() |> Repo.one()
end end
@doc """
Get a discussion by it's ID
"""
@spec get_discussion(String.t() | integer()) :: Discussion.t()
def get_discussion(discussion_id) do def get_discussion(discussion_id) do
Discussion Discussion
|> Repo.get(discussion_id) |> Repo.get(discussion_id)
|> Repo.preload(@discussion_preloads) |> Repo.preload(@discussion_preloads)
end end
@doc """
Get a discussion by it's URL
"""
@spec get_discussion_by_url(String.t() | nil) :: Discussion.t() | nil @spec get_discussion_by_url(String.t() | nil) :: Discussion.t() | nil
def get_discussion_by_url(nil), do: nil def get_discussion_by_url(nil), do: nil
@ -317,12 +346,19 @@ defmodule Mobilizon.Discussions do
|> Repo.preload(@discussion_preloads) |> Repo.preload(@discussion_preloads)
end end
@doc """
Get a discussion by it's slug
"""
@spec get_discussion_by_slug(String.t()) :: Discussion.t()
def get_discussion_by_slug(discussion_slug) do def get_discussion_by_slug(discussion_slug) do
Discussion Discussion
|> Repo.get_by(slug: discussion_slug) |> Repo.get_by(slug: discussion_slug)
|> Repo.preload(@discussion_preloads) |> Repo.preload(@discussion_preloads)
end end
@doc """
Get a paginated list of discussions for a group actor
"""
@spec find_discussions_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t() @spec find_discussions_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
def find_discussions_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do def find_discussions_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
Discussion Discussion
@ -366,6 +402,10 @@ defmodule Mobilizon.Discussions do
end end
end end
@doc """
Create a response to a discussion
"""
@spec reply_to_discussion(Discussion.t(), map()) :: {:ok, Discussion.t()}
def reply_to_discussion(%Discussion{id: discussion_id} = discussion, attrs \\ %{}) do def reply_to_discussion(%Discussion{id: discussion_id} = discussion, attrs \\ %{}) do
with {:ok, %{comment: %Comment{} = comment, discussion: %Discussion{} = discussion}} <- with {:ok, %{comment: %Comment{} = comment, discussion: %Discussion{} = discussion}} <-
Multi.new() Multi.new()
@ -415,6 +455,7 @@ defmodule Mobilizon.Discussions do
|> Repo.transaction() |> Repo.transaction()
end end
@spec public_comments_for_actor_query(String.t() | integer()) :: [Comment.t()]
defp public_comments_for_actor_query(actor_id) do defp public_comments_for_actor_query(actor_id) do
Comment Comment
|> where([c], c.actor_id == ^actor_id and c.visibility in ^@public_visibility) |> where([c], c.actor_id == ^actor_id and c.visibility in ^@public_visibility)
@ -422,6 +463,7 @@ defmodule Mobilizon.Discussions do
|> preload_for_comment() |> preload_for_comment()
end end
@spec public_replies_for_thread_query(String.t() | integer()) :: [Comment.t()]
defp public_replies_for_thread_query(comment_id) do defp public_replies_for_thread_query(comment_id) do
Comment Comment
|> where([c], c.origin_comment_id == ^comment_id and c.visibility in ^@public_visibility) |> where([c], c.origin_comment_id == ^comment_id and c.visibility in ^@public_visibility)
@ -444,6 +486,7 @@ defmodule Mobilizon.Discussions do
) )
end end
@spec filter_comments_under_events(Ecto.Query.t()) :: Ecto.Query.t()
defp filter_comments_under_events(query) do defp filter_comments_under_events(query) do
where(query, [c], is_nil(c.discussion_id) and not is_nil(c.event_id)) where(query, [c], is_nil(c.discussion_id) and not is_nil(c.event_id))
end end

View File

@ -103,8 +103,8 @@ defmodule Mobilizon.Mixfile do
{:bamboo_smtp, "~> 3.0"}, {:bamboo_smtp, "~> 3.0"},
{:geolix, "~> 2.0"}, {:geolix, "~> 2.0"},
{:geolix_adapter_mmdb2, "~> 0.6.0"}, {:geolix_adapter_mmdb2, "~> 0.6.0"},
{:absinthe, "~> 1.5.5"}, {:absinthe, "~> 1.6"},
{:absinthe_phoenix, "~> 2.0.0"}, {:absinthe_phoenix, github: "tcitworld/absinthe_phoenix", branch: "patch-1"},
{:absinthe_plug, "~> 1.5.0"}, {:absinthe_plug, "~> 1.5.0"},
{:dataloader, "~> 1.0.6"}, {:dataloader, "~> 1.0.6"},
{:plug_cowboy, "~> 2.0"}, {:plug_cowboy, "~> 2.0"},

View File

@ -1,8 +1,8 @@
%{ %{
"absinthe": {:hex, :absinthe, "1.5.5", "22b26228f56dc6a1074c52cea9c64e869a0cb2427403bcf9056c422d36c66292", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "41e79ed4bffbab4986493ff4120c948d59871fd08ad5e31195129ce3c01aad58"}, "absinthe": {:hex, :absinthe, "1.6.0", "7cb42eebbb9cbf5077541d73c189e205ebe12caf1c78372fc5b9e706fc8ac298", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "99915841495522332b3af8ff10c9cbb51e256b28d9b19c0dfaac5f044b6bfb66"},
"absinthe_ecto": {:hex, :absinthe_ecto, "0.1.3", "420b68129e79fe4571a4838904ba03e282330d335da47729ad52ffd7b8c5fcb1", [:mix], [{:absinthe, "~> 1.3.0 or ~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "355b9db34abfab96ae1e025434b66e11002babcf4fe6b7144d26ff7548985f52"}, "absinthe_ecto": {:hex, :absinthe_ecto, "0.1.3", "420b68129e79fe4571a4838904ba03e282330d335da47729ad52ffd7b8c5fcb1", [:mix], [{:absinthe, "~> 1.3.0 or ~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "355b9db34abfab96ae1e025434b66e11002babcf4fe6b7144d26ff7548985f52"},
"absinthe_phoenix": {:hex, :absinthe_phoenix, "2.0.0", "01c6a90af0ca12ee08d0fb93e23f9890d75bb6d3027f49ee4383bc03058ef5c3", [:mix], [{:absinthe, "~> 1.5.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.5.0", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "7ffbfe9fb82a14cafb78885cc2cef4f9d454bbbe2c95eec12b5463f5a20d1020"}, "absinthe_phoenix": {:git, "https://github.com/tcitworld/absinthe_phoenix.git", "4759d4141fb6254f5e7726ad6a00d7618116fb9e", [branch: "patch-1"]},
"absinthe_plug": {:hex, :absinthe_plug, "1.5.2", "995de73f0afa763e0aae17e4e0e4affbb5d79e33199bf7e075aeb07f1fb6b7d1", [:mix], [{:absinthe, "~> 1.5.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e03549bce5bb77d7b4a9bd68c69f442b0f4409b723b9ce41683ac5c1c70b5958"}, "absinthe_plug": {:hex, :absinthe_plug, "1.5.3", "40b62edddc7db94098ab2f4a3011c17189862a3dbc50580fc92e3cb7953e9b36", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "8378204b9b0c1f37bd7a52ecde8fa627e553a8bf04610d20e1bce2dbde71fdb2"},
"argon2_elixir": {:hex, :argon2_elixir, "2.4.0", "2a22ea06e979f524c53b42b598fc6ba38cdcbc977a155e33e057732cfb1fb311", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "4ea82e183cf8e7f66dab1f767fedcfe6a195e140357ef2b0423146b72e0a551d"}, "argon2_elixir": {:hex, :argon2_elixir, "2.4.0", "2a22ea06e979f524c53b42b598fc6ba38cdcbc977a155e33e057732cfb1fb311", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "4ea82e183cf8e7f66dab1f767fedcfe6a195e140357ef2b0423146b72e0a551d"},
"atomex": {:hex, :atomex, "0.3.0", "19b5d1a2aef8706dbd307385f7d5d9f6f273869226d317492c396c7bacf26402", [:mix], [{:xml_builder, "~> 2.0.0", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "025dbc3a3e99380894791a093019f535d0ef6cf1916f6ec1b778ac107fcfc3e4"}, "atomex": {:hex, :atomex, "0.3.0", "19b5d1a2aef8706dbd307385f7d5d9f6f273869226d317492c396c7bacf26402", [:mix], [{:xml_builder, "~> 2.0.0", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "025dbc3a3e99380894791a093019f535d0ef6cf1916f6ec1b778ac107fcfc3e4"},
"auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]}, "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]},

View File

@ -17,7 +17,7 @@ defmodule Mobilizon.Federation.ActivityPubTest do
alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Todos.{Todo, TodoList}
alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityPub.{Relay, Utils}
alias Mobilizon.Federation.HTTPSignatures.Signature alias Mobilizon.Federation.HTTPSignatures.Signature
alias Mobilizon.Service.HTTP.ActivityPub.Mock alias Mobilizon.Service.HTTP.ActivityPub.Mock
@ -125,6 +125,11 @@ defmodule Mobilizon.Federation.ActivityPubTest do
assert_called(ActivityPub.make_actor_from_url(@actor_url, false)) assert_called(ActivityPub.make_actor_from_url(@actor_url, false))
end end
end end
@public_url "https://www.w3.org/ns/activitystreams#Public"
test "activitystreams#Public uri returns Relay actor" do
assert ActivityPub.get_or_fetch_actor_by_url(@public_url) == {:ok, Relay.get_actor()}
end
end end
describe "create activities" do describe "create activities" do
@ -301,6 +306,19 @@ defmodule Mobilizon.Federation.ActivityPubTest do
end end
end end
describe "remove a member" do
test "it creates an remove activity" do
group = insert(:group)
member = insert(:member, parent: group)
moderator = insert(:actor)
{:ok, activity, _member} = ActivityPub.remove(member, group, moderator, true)
assert activity.data["type"] == "Remove"
assert activity.data["actor"] == moderator.url
assert activity.data["to"] == [group.members_url]
assert activity.data["object"] == member.url
end
end
describe "create a todo list" do describe "create a todo list" do
@todo_list_title "My TODO-list" @todo_list_title "My TODO-list"