2022-11-26 09:09:31 -08:00
|
|
|
import pytest
|
|
|
|
from asgiref.sync import async_to_sync
|
|
|
|
|
|
|
|
from activities.models import Post
|
2023-01-15 12:35:45 -08:00
|
|
|
from users.models import Block, Domain, Follow, Identity
|
2022-11-26 09:09:31 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_post_targets_simple(identity, other_identity, remote_identity):
|
|
|
|
"""
|
|
|
|
Tests that a simple top level post returns the correct targets.
|
|
|
|
"""
|
|
|
|
# Test a post with no mentions targets author
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Hello</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity}
|
|
|
|
|
|
|
|
# Test remote reply targets original post author
|
|
|
|
Post.objects.create(
|
|
|
|
content="<p>Reply</p>",
|
|
|
|
author=remote_identity,
|
|
|
|
local=False,
|
|
|
|
in_reply_to=post.absolute_object_uri(),
|
|
|
|
)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity}
|
|
|
|
|
|
|
|
# Test a post with local and remote mentions
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Hello @test and @other</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
)
|
|
|
|
# Mentions are targeted
|
|
|
|
post.mentions.add(remote_identity)
|
|
|
|
post.mentions.add(other_identity)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
# Targets everyone
|
|
|
|
assert targets == {identity, other_identity, remote_identity}
|
|
|
|
|
|
|
|
# Test remote post with mentions
|
|
|
|
post.local = False
|
|
|
|
post.save()
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
2022-12-11 23:54:51 -08:00
|
|
|
# Only targets locals who are mentioned
|
|
|
|
assert targets == {other_identity}
|
2022-11-26 09:09:31 -08:00
|
|
|
|
|
|
|
|
2023-01-08 12:46:40 -08:00
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_post_targets_shared(identity, other_identity):
|
|
|
|
"""
|
|
|
|
Tests that remote identities with the same shared inbox only get one target.
|
|
|
|
"""
|
|
|
|
# Create a pair of remote identities that share an inbox URI
|
|
|
|
domain = Domain.objects.create(domain="remote.test", local=False, state="updated")
|
|
|
|
remote1 = Identity.objects.create(
|
|
|
|
actor_uri="https://remote.test/test1/",
|
|
|
|
inbox_uri="https://remote.test/@test1/inbox/",
|
|
|
|
shared_inbox_uri="https://remote.test/inbox/",
|
|
|
|
profile_uri="https://remote.test/@test1/",
|
|
|
|
username="test1",
|
|
|
|
domain=domain,
|
|
|
|
name="Test1",
|
|
|
|
local=False,
|
|
|
|
state="updated",
|
|
|
|
)
|
|
|
|
remote2 = Identity.objects.create(
|
|
|
|
actor_uri="https://remote.test/test2/",
|
|
|
|
inbox_uri="https://remote.test/@test2/inbox/",
|
|
|
|
shared_inbox_uri="https://remote.test/inbox/",
|
|
|
|
profile_uri="https://remote.test/@test2/",
|
|
|
|
username="test2",
|
|
|
|
domain=domain,
|
|
|
|
name="Test2",
|
|
|
|
local=False,
|
|
|
|
state="updated",
|
|
|
|
)
|
|
|
|
|
|
|
|
# Make a post mentioning one local and two remote identities
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Test</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
)
|
|
|
|
post.mentions.add(other_identity)
|
|
|
|
post.mentions.add(remote1)
|
|
|
|
post.mentions.add(remote2)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
|
|
|
|
# We should only have one of remote1 or remote2 in there as they share a
|
|
|
|
# shared inbox URI
|
|
|
|
assert (targets == {identity, other_identity, remote1}) or (
|
|
|
|
targets
|
|
|
|
== {
|
|
|
|
identity,
|
|
|
|
other_identity,
|
|
|
|
remote2,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-11-26 09:09:31 -08:00
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_post_local_only(identity, other_identity, remote_identity):
|
|
|
|
"""
|
|
|
|
Tests that a simple top level post returns the correct targets.
|
|
|
|
"""
|
|
|
|
# Test a short username (remote)
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Hello @test and @other</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
visibility=Post.Visibilities.local_only,
|
|
|
|
)
|
|
|
|
post.mentions.add(remote_identity)
|
|
|
|
post.mentions.add(other_identity)
|
|
|
|
|
|
|
|
# Remote mention is not targeted
|
|
|
|
post.mentions.add(remote_identity)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity, other_identity}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_post_followers(identity, other_identity, remote_identity):
|
|
|
|
|
|
|
|
Follow.objects.create(source=other_identity, target=identity)
|
|
|
|
Follow.objects.create(source=remote_identity, target=identity)
|
|
|
|
|
|
|
|
# Test Public post w/o mentions targets self and followers
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Hello</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
visibility=Post.Visibilities.public,
|
|
|
|
)
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity, other_identity, remote_identity}
|
|
|
|
|
2022-12-11 23:54:51 -08:00
|
|
|
# Remote post only targets local followers, not the author
|
2022-11-26 09:09:31 -08:00
|
|
|
post.local = False
|
|
|
|
post.save()
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
2022-12-11 23:54:51 -08:00
|
|
|
assert targets == {other_identity}
|
2022-11-26 09:09:31 -08:00
|
|
|
|
|
|
|
# Local Only post only targets local followers
|
|
|
|
post.local = True
|
|
|
|
post.visibility = Post.Visibilities.local_only
|
|
|
|
post.save()
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity, other_identity}
|
|
|
|
|
|
|
|
# Mentioned posts do not target unmentioned followers
|
|
|
|
post.visibility = Post.Visibilities.mentioned
|
|
|
|
post.save()
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity}
|
2023-01-15 12:35:45 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_post_blocked(identity, other_identity, remote_identity):
|
|
|
|
"""
|
|
|
|
Blocked users should never get a copy of a post even if they're mentioned.
|
|
|
|
"""
|
|
|
|
# Block the two other identities, one with mute only
|
|
|
|
Block.create_local_mute(identity, other_identity)
|
|
|
|
Block.create_local_block(identity, remote_identity)
|
|
|
|
|
|
|
|
# Make a post
|
|
|
|
post = Post.objects.create(
|
|
|
|
content="<p>Hello @test and @other</p>",
|
|
|
|
author=identity,
|
|
|
|
local=True,
|
|
|
|
)
|
|
|
|
post.mentions.add(remote_identity)
|
|
|
|
post.mentions.add(other_identity)
|
|
|
|
|
|
|
|
# The muted block should be in targets, the full block should not
|
|
|
|
targets = async_to_sync(post.aget_targets)()
|
|
|
|
assert targets == {identity, other_identity}
|