Refactoring of Actors context

This commit is contained in:
miffigriffy
2019-09-09 00:52:49 +02:00
parent 3a4a006c44
commit 4418275223
36 changed files with 1145 additions and 1345 deletions

View File

@@ -1,11 +1,15 @@
defmodule Mobilizon.ActorsTest do
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
use Mobilizon.DataCase
import Mobilizon.Factory
alias Mobilizon.{Actors, Config, Users}
alias Mobilizon.Actors.{Actor, Member, Follower, Bot}
alias Mobilizon.Media.File, as: FileModel
import Mobilizon.Factory
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Storage.Page
describe "actors" do
@valid_attrs %{
@@ -40,8 +44,6 @@ defmodule Mobilizon.ActorsTest do
}
@remote_account_url "https://social.tcit.fr/users/tcit"
@remote_account_username "tcit"
@remote_account_domain "social.tcit.fr"
setup do
user = insert(:user)
@@ -70,14 +72,14 @@ defmodule Mobilizon.ActorsTest do
assert actor_id == Users.get_actor_for_user(user).id
end
test "get_actor_with_everything/1 returns the actor with it's organized events", %{
test "get_actor_with_preload/1 returns the actor with it's organized events", %{
actor: actor
} do
assert Actors.get_actor_with_everything(actor.id).organized_events == []
assert Actors.get_actor_with_preload(actor.id).organized_events == []
event = insert(:event, organizer_actor: actor)
event_found_id =
Actors.get_actor_with_everything(actor.id).organized_events |> hd |> Map.get(:id)
Actors.get_actor_with_preload(actor.id).organized_events |> hd |> Map.get(:id)
assert event_found_id == event.id
end
@@ -97,7 +99,7 @@ defmodule Mobilizon.ActorsTest do
preferred_username: preferred_username,
domain: domain,
avatar: %FileModel{name: picture_name} = _picture
} = _actor} = Actors.get_or_fetch_by_url(@remote_account_url)
} = _actor} = ActivityPub.get_or_fetch_by_url(@remote_account_url)
assert picture_name == "avatar"
@@ -111,51 +113,51 @@ defmodule Mobilizon.ActorsTest do
end
end
test "get_local_actor_by_name_with_everything!/1 returns the local actor with it's organized events",
test "get_local_actor_by_name_with_preload!/1 returns the local actor with it's organized events",
%{
actor: actor
} do
assert Actors.get_local_actor_by_name_with_everything(actor.preferred_username).organized_events ==
assert Actors.get_local_actor_by_name_with_preload(actor.preferred_username).organized_events ==
[]
event = insert(:event, organizer_actor: actor)
event_found_id =
Actors.get_local_actor_by_name_with_everything(actor.preferred_username).organized_events
Actors.get_local_actor_by_name_with_preload(actor.preferred_username).organized_events
|> hd
|> Map.get(:id)
assert event_found_id == event.id
end
test "get_actor_by_name_with_everything!/1 returns the local actor with it's organized events",
test "get_actor_by_name_with_preload!/1 returns the local actor with it's organized events",
%{
actor: actor
} do
assert Actors.get_actor_by_name_with_everything(actor.preferred_username).organized_events ==
assert Actors.get_actor_by_name_with_preload(actor.preferred_username).organized_events ==
[]
event = insert(:event, organizer_actor: actor)
event_found_id =
Actors.get_actor_by_name_with_everything(actor.preferred_username).organized_events
Actors.get_actor_by_name_with_preload(actor.preferred_username).organized_events
|> hd
|> Map.get(:id)
assert event_found_id == event.id
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_preload!/1 returns the remote actor with it's organized events" do
use_cassette "actors/remote_actor_mastodon_tcit" do
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(@remote_account_url) do
assert Actors.get_actor_by_name_with_everything(
with {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_by_url(@remote_account_url) do
assert Actors.get_actor_by_name_with_preload(
"#{actor.preferred_username}@#{actor.domain}"
).organized_events == []
event = insert(:event, organizer_actor: actor)
event_found_id =
Actors.get_actor_by_name_with_everything(
Actors.get_actor_by_name_with_preload(
"#{actor.preferred_username}@#{actor.domain}"
).organized_events
|> hd
@@ -166,42 +168,21 @@ defmodule Mobilizon.ActorsTest do
end
end
test "get_or_fetch_by_url/1 returns the local actor for the url", %{
actor: %Actor{preferred_username: preferred_username} = actor
} do
with {:ok, %Actor{domain: domain} = actor} <- Actors.get_or_fetch_by_url(actor.url) do
assert preferred_username == actor.preferred_username
assert is_nil(domain)
end
end
test "get_or_fetch_by_url/1 returns the remote actor for the url" do
use_cassette "actors/remote_actor_mastodon_tcit" do
with {:ok, %Actor{preferred_username: preferred_username, domain: domain}} <-
Actors.get_or_fetch_by_url!(@remote_account_url) do
assert preferred_username == @remote_account_username
assert domain == @remote_account_domain
end
end
end
test "test find_local_by_username/1 returns local actors with similar usernames", %{
test "test get_local_actor_by_username/1 returns local actors with similar usernames", %{
actor: actor
} do
actor2 = insert(:actor, preferred_username: "tcit")
[%Actor{id: actor_found_id} | tail] = Actors.find_local_by_username("tcit")
[%Actor{id: actor_found_id} | tail] = Actors.get_local_actor_by_username("tcit")
%Actor{id: actor2_found_id} = hd(tail)
assert MapSet.new([actor_found_id, actor2_found_id]) == MapSet.new([actor.id, actor2.id])
end
test "test find_and_count_actors_by_username_or_name/4 returns actors with similar usernames",
%{
actor: %Actor{id: actor_id}
} do
test "test build_actors_by_username_or_name_page/4 returns actors with similar usernames",
%{actor: %Actor{id: actor_id}} do
use_cassette "actors/remote_actor_mastodon_tcit" do
with {:ok, %Actor{id: actor2_id}} <- Actors.get_or_fetch_by_url(@remote_account_url) do
%{total: 2, elements: actors} =
Actors.find_and_count_actors_by_username_or_name("tcit", [:Person])
with {:ok, %Actor{id: actor2_id}} <- ActivityPub.get_or_fetch_by_url(@remote_account_url) do
%Page{total: 2, elements: actors} =
Actors.build_actors_by_username_or_name_page("tcit", [:Person])
actors_ids = actors |> Enum.map(& &1.id)
@@ -210,35 +191,13 @@ defmodule Mobilizon.ActorsTest do
end
end
test "test find_and_count_actors_by_username_or_name/4 returns actors with similar names" do
test "test build_actors_by_username_or_name_page/4 returns actors with similar names" do
%{total: 0, elements: actors} =
Actors.find_and_count_actors_by_username_or_name("ohno", [:Person])
Actors.build_actors_by_username_or_name_page("ohno", [:Person])
assert actors == []
end
test "test get_public_key_for_url/1 with local actor", %{actor: actor} do
assert Actor.get_public_key_for_url(actor.url) ==
actor.keys |> Mobilizon.Actors.Actor.prepare_public_key()
end
@remote_actor_key {:ok,
{:RSAPublicKey,
20_890_513_599_005_517_665_557_846_902_571_022_168_782_075_040_010_449_365_706_450_877_170_130_373_892_202_874_869_873_999_284_399_697_282_332_064_948_148_602_583_340_776_692_090_472_558_740_998_357_203_838_580_321_412_679_020_304_645_826_371_196_718_081_108_049_114_160_630_664_514_340_729_769_453_281_682_773_898_619_827_376_232_969_899_348_462_205_389_310_883_299_183_817_817_999_273_916_446_620_095_414_233_374_619_948_098_516_821_650_069_821_783_810_210_582_035_456_563_335_930_330_252_551_528_035_801_173_640_288_329_718_719_895_926_309_416_142_129_926_226_047_930_429_802_084_560_488_897_717_417_403_272_782_469_039_131_379_953_278_833_320_195_233_761_955_815_307_522_871_787_339_192_744_439_894_317_730_207_141_881_699_363_391_788_150_650_217_284_777_541_358_381_165_360_697_136_307_663_640_904_621_178_632_289_787,
65_537}}
test "test get_public_key_for_url/1 with remote actor" do
use_cassette "actors/remote_actor_mastodon_tcit" do
assert Actor.get_public_key_for_url(@remote_account_url) == @remote_actor_key
end
end
test "test get_public_key_for_url/1 with remote actor and bad key" do
use_cassette "actors/remote_actor_mastodon_tcit_actor_deleted" do
assert Actor.get_public_key_for_url(@remote_account_url) ==
{:error, :actor_fetch_error}
end
end
test "create_actor/1 with valid data creates a actor" do
assert {:ok, %Actor{} = actor} = Actors.create_actor(@valid_attrs)
assert actor.summary == "some description"
@@ -351,10 +310,6 @@ defmodule Mobilizon.ActorsTest do
"/" <> banner_path
)
end
test "change_actor/1 returns a actor changeset", %{actor: actor} do
assert %Ecto.Changeset{} = Actors.change_actor(actor)
end
end
describe "groups" do
@@ -505,8 +460,8 @@ defmodule Mobilizon.ActorsTest do
assert {:ok, %Follower{} = follower} = Actors.create_follower(valid_attrs)
assert follower.approved == true
assert %{total: 1, elements: [target_actor]} = Actor.get_followings(actor)
assert %{total: 1, elements: [actor]} = Actor.get_followers(target_actor)
assert %{total: 1, elements: [target_actor]} = Actors.get_followings(actor)
assert %{total: 1, elements: [actor]} = Actors.get_followers(target_actor)
end
test "create_follower/1 with valid data but same actors fails to create a follower", %{
@@ -554,33 +509,28 @@ defmodule Mobilizon.ActorsTest do
assert_raise Ecto.NoResultsError, fn -> Actors.get_follower!(follower.id) end
end
test "change_follower/1 returns a follower changeset", context do
follower = create_test_follower(context)
assert %Ecto.Changeset{} = Actors.change_follower(follower)
end
test "follow/3 makes an actor follow another", %{actor: actor, target_actor: target_actor} do
# Preloading followers/followings
actor = Actors.get_actor_with_everything(actor.id)
target_actor = Actors.get_actor_with_everything(target_actor.id)
actor = Actors.get_actor_with_preload(actor.id)
target_actor = Actors.get_actor_with_preload(target_actor.id)
{:ok, follower} = Actor.follow(target_actor, actor)
{:ok, follower} = Actors.follow(target_actor, actor)
assert follower.actor.id == actor.id
# Referesh followers/followings
actor = Actors.get_actor_with_everything(actor.id)
target_actor = Actors.get_actor_with_everything(target_actor.id)
actor = Actors.get_actor_with_preload(actor.id)
target_actor = Actors.get_actor_with_preload(target_actor.id)
assert target_actor.followers |> Enum.map(& &1.actor_id) == [actor.id]
assert actor.followings |> Enum.map(& &1.target_actor_id) == [target_actor.id]
# Test if actor is already following target actor
assert {:error, :already_following, msg} = Actor.follow(target_actor, actor)
assert {:error, :already_following, msg} = Actors.follow(target_actor, actor)
assert msg =~ "already following"
# Test if target actor is suspended
target_actor = %{target_actor | suspended: true}
assert {:error, :suspended, msg} = Actor.follow(target_actor, actor)
assert {:error, :suspended, msg} = Actors.follow(target_actor, actor)
assert msg =~ "suspended"
end
end
@@ -620,8 +570,8 @@ defmodule Mobilizon.ActorsTest do
assert {:ok, %Member{} = member} = Actors.create_member(valid_attrs)
assert member.role == :member
assert [group] = Actor.get_groups_member_of(actor)
assert [actor] = Actor.get_members_for_group(group)
assert [group] = Actors.get_groups_member_of(actor)
assert [actor] = Actors.get_members_for_group(group)
end
test "create_member/1 with valid data but same actors fails to create a member", %{
@@ -666,10 +616,5 @@ defmodule Mobilizon.ActorsTest do
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_test_member(context)
assert %Ecto.Changeset{} = Actors.change_member(member)
end
end
end

View File

@@ -11,7 +11,6 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
alias Mobilizon.Events
alias Mobilizon.Events.Event
alias Mobilizon.Actors.Actor
alias Mobilizon.Actors
alias Mobilizon.Service.HTTPSignatures.Signature
alias Mobilizon.Service.ActivityPub
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
@@ -48,7 +47,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "returns an actor from url" do
use_cassette "activity_pub/fetch_framapiaf.org_users_tcit" do
assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} =
Actors.get_or_fetch_by_url("https://framapiaf.org/users/tcit")
ActivityPub.get_or_fetch_by_url("https://framapiaf.org/users/tcit")
end
end
end

View File

@@ -222,8 +222,8 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
assert data["type"] == "Follow"
assert data["id"] == "https://social.tcit.fr/users/tcit#follows/2"
actor = Actors.get_actor_with_everything(actor.id)
assert Actor.following?(Actors.get_actor_by_url!(data["actor"], true), actor)
actor = Actors.get_actor_with_preload(actor.id)
assert Actors.following?(Actors.get_actor_by_url!(data["actor"], true), actor)
end
# test "it works for incoming follow requests from hubzilla" do
@@ -498,7 +498,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
assert data["actor"] == "https://social.tcit.fr/users/tcit"
{:ok, followed} = Actors.get_actor_by_url(data["actor"])
refute Actor.following?(followed, actor)
refute Actors.following?(followed, actor)
end
# test "it works for incoming blocks" do
@@ -581,10 +581,10 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
follower = insert(:actor)
followed = insert(:actor)
refute Actor.following?(follower, followed)
refute Actors.following?(follower, followed)
{:ok, follow_activity, _} = ActivityPub.follow(follower, followed)
assert Actor.following?(follower, followed)
assert Actors.following?(follower, followed)
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
@@ -605,7 +605,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, follower} = Actors.get_actor_by_url(follower.url)
assert Actor.following?(follower, followed)
assert Actors.following?(follower, followed)
end
test "it works for incoming accepts which are referenced by IRI only" do
@@ -627,7 +627,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, follower} = Actors.get_actor_by_url(follower.url)
assert Actor.following?(follower, followed)
assert Actors.following?(follower, followed)
end
test "it fails for incoming accepts which cannot be correlated" do
@@ -646,7 +646,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, follower} = Actors.get_actor_by_url(follower.url)
refute Actor.following?(follower, followed)
refute Actors.following?(follower, followed)
end
test "it fails for incoming rejects which cannot be correlated" do
@@ -665,7 +665,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, follower} = Actors.get_actor_by_url(follower.url)
refute Actor.following?(follower, followed)
refute Actors.following?(follower, followed)
end
test "it works for incoming rejects which are referenced by IRI only" do
@@ -674,7 +674,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, follow_activity, _} = ActivityPub.follow(follower, followed)
assert Actor.following?(follower, followed)
assert Actors.following?(follower, followed)
reject_data =
File.read!("test/fixtures/mastodon-reject-activity.json")
@@ -684,7 +684,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
{:ok, %Activity{data: _}, _} = Transmogrifier.handle_incoming(reject_data)
refute Actor.following?(follower, followed)
refute Actors.following?(follower, followed)
end
test "it rejects activities without a valid ID" do

View File

@@ -6,6 +6,8 @@ defmodule MobilizonWeb.API.SearchTest do
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Storage.Page
alias MobilizonWeb.API.Search
import Mock
@@ -13,7 +15,7 @@ defmodule MobilizonWeb.API.SearchTest do
test "search an user by username" do
with_mock ActivityPub,
find_or_make_actor_from_nickname: fn "toto@domain.tld" -> {:ok, %Actor{id: 42}} end do
assert {:ok, %{total: 1, elements: [%Actor{id: 42}]}} ==
assert {:ok, %Page{total: 1, elements: [%Actor{id: 42}]}} ==
Search.search_actors("toto@domain.tld", 1, 10, :Person)
assert_called(ActivityPub.find_or_make_actor_from_nickname("toto@domain.tld"))
@@ -23,7 +25,7 @@ defmodule MobilizonWeb.API.SearchTest do
test "search something by URL" do
with_mock ActivityPub,
fetch_object_from_url: fn "https://social.tcit.fr/users/tcit" -> {:ok, %Actor{id: 42}} end do
assert {:ok, %{total: 1, elements: [%Actor{id: 42}]}} ==
assert {:ok, %Page{total: 1, elements: [%Actor{id: 42}]}} ==
Search.search_actors("https://social.tcit.fr/users/tcit", 1, 10, :Person)
assert_called(ActivityPub.fetch_object_from_url("https://social.tcit.fr/users/tcit"))
@@ -32,20 +34,20 @@ defmodule MobilizonWeb.API.SearchTest do
test "search actors" do
with_mock Actors,
find_and_count_actors_by_username_or_name: fn "toto", _type, 1, 10 ->
%{total: 1, elements: [%Actor{id: 42}]}
build_actors_by_username_or_name_page: fn "toto", _type, 1, 10 ->
%Page{total: 1, elements: [%Actor{id: 42}]}
end do
assert {:ok, %{total: 1, elements: [%Actor{id: 42}]}} =
Search.search_actors("toto", 1, 10, :Person)
assert_called(Actors.find_and_count_actors_by_username_or_name("toto", [:Person], 1, 10))
assert_called(Actors.build_actors_by_username_or_name_page("toto", [:Person], 1, 10))
end
end
test "search events" do
with_mock Events,
find_and_count_events_by_name: fn "toto", 1, 10 ->
%{total: 1, elements: [%Event{title: "super toto event"}]}
%Page{total: 1, elements: [%Event{title: "super toto event"}]}
end do
assert {:ok, %{total: 1, elements: [%Event{title: "super toto event"}]}} =
Search.search_events("toto", 1, 10)

View File

@@ -177,7 +177,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
test "it returns the followers in a collection", %{conn: conn} do
actor = insert(:actor, visibility: :public)
actor2 = insert(:actor)
Actor.follow(actor, actor2)
Actors.follow(actor, actor2)
result =
conn
@@ -190,7 +190,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
test "it returns no followers for a private actor", %{conn: conn} do
actor = insert(:actor, visibility: :private)
actor2 = insert(:actor)
Actor.follow(actor, actor2)
Actors.follow(actor, actor2)
result =
conn
@@ -205,7 +205,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
Enum.each(1..15, fn _ ->
other_actor = insert(:actor)
Actor.follow(actor, other_actor)
Actors.follow(actor, other_actor)
end)
result =
@@ -229,7 +229,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
test "it returns the followings in a collection", %{conn: conn} do
actor = insert(:actor)
actor2 = insert(:actor, visibility: :public)
Actor.follow(actor, actor2)
Actors.follow(actor, actor2)
result =
conn
@@ -242,7 +242,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
test "it returns no followings for a private actor", %{conn: conn} do
actor = insert(:actor)
actor2 = insert(:actor, visibility: :private)
Actor.follow(actor, actor2)
Actors.follow(actor, actor2)
result =
conn
@@ -257,7 +257,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
Enum.each(1..15, fn _ ->
other_actor = insert(:actor)
Actor.follow(other_actor, actor)
Actors.follow(other_actor, actor)
end)
result =
@@ -322,7 +322,7 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
# Enum.each(1..15, fn _ ->
# actor = Repo.get(Actor, actor.id)
# other_actor = insert(:actor)
# Actor.follow(actor, other_actor)
# Actors.follow(actor, other_actor)
# end)
# result =

View File

@@ -1,10 +1,13 @@
defmodule Mobilizon.Factory do
@moduledoc """
Factory for fixtures with ExMachina
Factory for fixtures with ExMachina.
"""
# with Ecto
use ExMachina.Ecto, repo: Mobilizon.Storage.Repo
alias Mobilizon.Actors.Actor
alias Mobilizon.Crypto
alias MobilizonWeb.Router.Helpers, as: Routes
alias MobilizonWeb.Endpoint
alias MobilizonWeb.Upload
@@ -21,10 +24,6 @@ defmodule Mobilizon.Factory do
end
def actor_factory do
key = :public_key.generate_key({:rsa, 2048, 65_537})
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
pem = [entry] |> :public_key.pem_encode() |> String.trim_trailing()
preferred_username = sequence("thomas")
%Mobilizon.Actors.Actor{
@@ -32,7 +31,7 @@ defmodule Mobilizon.Factory do
domain: nil,
followers: [],
followings: [],
keys: pem,
keys: Crypto.generate_rsa_2048_private_key(),
type: :Person,
avatar: build(:file, name: "Avatar"),
banner: build(:file, name: "Banner"),

View File

@@ -22,7 +22,7 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
{:ok, target_actor} = Actors.get_actor_by_url(target_instance)
refute is_nil(target_actor.domain)
assert Actor.following?(local_actor, target_actor)
assert Actors.following?(local_actor, target_actor)
end
end
end
@@ -36,11 +36,11 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
%Actor{} = local_actor = Relay.get_actor()
{:ok, %Actor{} = target_actor} = Actors.get_actor_by_url(target_instance)
assert %Follower{} = Actor.following?(local_actor, target_actor)
assert %Follower{} = Actors.following?(local_actor, target_actor)
Mix.Tasks.Mobilizon.Relay.run(["unfollow", target_instance])
refute Actor.following?(local_actor, target_actor)
refute Actors.following?(local_actor, target_actor)
end
end
end