Fix events from former followed instances showing up

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-10-14 09:45:58 +02:00
parent bb6e7070bd
commit cf9b8d5f46
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
3 changed files with 78 additions and 10 deletions

View file

@ -1643,12 +1643,17 @@ defmodule Mobilizon.Events do
where(query, [q], q.local == true) where(query, [q], q.local == true)
end end
@spec filter_local_or_from_followed_instances_events(Ecto.Query.t()) :: Ecto.Query.t() @spec filter_local_or_from_followed_instances_events(Ecto.Query.t()) ::
Ecto.Query.t()
defp filter_local_or_from_followed_instances_events(query) do defp filter_local_or_from_followed_instances_events(query) do
from(q in query, follower_actor_id = Mobilizon.Config.relay_actor_id()
left_join: s in Share,
on: s.uri == q.url, query
where: q.local == true or not is_nil(s.uri) |> join(:left, [q], s in Share, on: s.uri == q.url)
|> join(:left, [_q, ..., s], f in Follower, on: f.target_actor_id == s.actor_id)
|> where(
[q, ..., s, f],
q.local == true or (f.actor_id == ^follower_actor_id and not is_nil(s.uri))
) )
end end

View file

@ -6,6 +6,7 @@ defmodule Mobilizon.EventsTest do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.{Event, Participant, Session, Tag, TagRelation, Track} alias Mobilizon.Events.{Event, Participant, Session, Tag, TagRelation, Track}
alias Mobilizon.Federation.ActivityPub.Relay
alias Mobilizon.Service.Workers alias Mobilizon.Service.Workers
alias Mobilizon.Storage.Page alias Mobilizon.Storage.Page
@ -19,10 +20,54 @@ defmodule Mobilizon.EventsTest do
category: "meeting" category: "meeting"
} }
describe "list_events/5" do
setup do
actor = insert(:actor)
event = insert(:event, organizer_actor: actor, visibility: :public, local: true)
Mobilizon.Config.clear_config_cache()
{:ok, actor: actor, event: event}
end
test "list_events/0 returns all events", %{event: event} do
assert event.title == hd(Events.list_events()).title
end
test "list_events/5 returns events from other instances if we follow them",
%{event: _event} do
events = Events.list_events()
assert length(events) == 1
%Actor{id: remote_instance_actor_id} = remote_instance_actor = insert(:instance_actor)
%Actor{id: remote_actor_id} = insert(:actor, domain: "somedomain.tld", user: nil)
%Event{url: remote_event_url} = insert(:event, local: false, title: "My Remote event")
Mobilizon.Share.create(remote_event_url, remote_instance_actor_id, remote_actor_id)
%Actor{} = own_instance_actor = Relay.get_actor()
insert(:follower, target_actor: remote_instance_actor, actor: own_instance_actor)
events = Events.list_events()
assert length(events) == 2
assert events |> Enum.any?(fn event -> event.title == "My Remote event" end)
end
test "list_events/5 doesn't return events from other instances if we don't follow them anymore",
%{event: _event} do
%Actor{id: remote_instance_actor_id} = insert(:instance_actor)
%Actor{id: remote_actor_id} = insert(:actor, domain: "somedomain.tld", user: nil)
%Event{url: remote_event_url} = insert(:event, local: false, title: "My Remote event")
Mobilizon.Share.create(remote_event_url, remote_instance_actor_id, remote_actor_id)
events = Events.list_events()
assert length(events) == 1
assert events |> Enum.all?(fn event -> event.title != "My Remote event" end)
end
end
describe "events" do describe "events" do
setup do setup do
actor = insert(:actor) actor = insert(:actor)
event = insert(:event, organizer_actor: actor, visibility: :public) event = insert(:event, organizer_actor: actor, visibility: :public, local: true)
Workers.BuildSearch.insert_search_event(event) Workers.BuildSearch.insert_search_event(event)
{:ok, actor: actor, event: event} {:ok, actor: actor, event: event}
end end
@ -41,10 +86,6 @@ defmodule Mobilizon.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", %{event: event} do
assert event.title == hd(Events.list_events()).title
end
test "get_event!/1 returns the event with given id", %{event: event} do test "get_event!/1 returns the event with given id", %{event: event} do
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) refute Ecto.assoc_loaded?(Events.get_event!(event.id).organizer_actor)

View file

@ -78,6 +78,28 @@ defmodule Mobilizon.Factory do
) )
end end
def instance_actor_factory do
preferred_username = "relay"
domain = "#{sequence("mydomain")}.com"
struct!(
actor_factory(),
%{
preferred_username: preferred_username,
type: :Application,
url: "http://#{domain}/#{preferred_username}",
followers_url: Actor.build_url(preferred_username, :followers),
following_url: Actor.build_url(preferred_username, :following),
members_url: Actor.build_url(preferred_username, :members),
resources_url: Actor.build_url(preferred_username, :resources),
inbox_url: Actor.build_url(preferred_username, :inbox),
outbox_url: Actor.build_url(preferred_username, :outbox),
user: nil,
domain: domain
}
)
end
def follower_factory do def follower_factory do
uuid = Ecto.UUID.generate() uuid = Ecto.UUID.generate()