mirror of
https://github.com/jointakahe/takahe.git
synced 2025-02-16 23:55:14 +00:00
Store any incoming reactions PostInteraction.value
This commit is contained in:
parent
83607779cd
commit
4c3cae337c
3 changed files with 69 additions and 7 deletions
|
@ -154,7 +154,7 @@ class PostInteraction(StatorModel):
|
|||
)
|
||||
|
||||
# Used to store any interaction extra text value like the vote
|
||||
# in the question/poll case
|
||||
# in the question/poll case, or the reaction
|
||||
value = models.CharField(max_length=50, blank=True, null=True)
|
||||
|
||||
# When the activity was originally created (as opposed to when we received it)
|
||||
|
@ -392,6 +392,7 @@ class PostInteraction(StatorModel):
|
|||
# Get the right type
|
||||
if data["type"].lower() == "like":
|
||||
type = cls.Types.like
|
||||
value = data.get("content") or data.get("_misskey_reaction")
|
||||
elif data["type"].lower() == "announce":
|
||||
type = cls.Types.boost
|
||||
elif (
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
from types import EllipsisType
|
||||
|
||||
from activities.models import (
|
||||
Post,
|
||||
|
@ -38,7 +39,7 @@ class PostService:
|
|||
def __init__(self, post: Post):
|
||||
self.post = post
|
||||
|
||||
def interact_as(self, identity: Identity, type: str):
|
||||
def interact_as(self, identity: Identity, type: str, value: str | None = None):
|
||||
"""
|
||||
Performs an interaction on this Post
|
||||
"""
|
||||
|
@ -46,28 +47,39 @@ class PostService:
|
|||
type=type,
|
||||
identity=identity,
|
||||
post=self.post,
|
||||
value=value,
|
||||
)[0]
|
||||
if interaction.state not in PostInteractionStates.group_active():
|
||||
interaction.transition_perform(PostInteractionStates.new)
|
||||
self.post.calculate_stats()
|
||||
|
||||
def uninteract_as(self, identity, type):
|
||||
def uninteract_as(self, identity, type, value: str | None | EllipsisType = ...):
|
||||
"""
|
||||
Undoes an interaction on this Post
|
||||
"""
|
||||
# Only search by value if it was actually given
|
||||
additional_fields = {}
|
||||
if value is not ...:
|
||||
additional_fields["value"] = value
|
||||
|
||||
for interaction in PostInteraction.objects.filter(
|
||||
type=type,
|
||||
identity=identity,
|
||||
post=self.post,
|
||||
**additional_fields,
|
||||
):
|
||||
interaction.transition_perform(PostInteractionStates.undone)
|
||||
|
||||
self.post.calculate_stats()
|
||||
|
||||
def like_as(self, identity: Identity):
|
||||
self.interact_as(identity, PostInteraction.Types.like)
|
||||
def like_as(self, identity: Identity, reaction: str | None = None):
|
||||
"""
|
||||
Add a Like to the post, including reactions.
|
||||
"""
|
||||
self.interact_as(identity, PostInteraction.Types.like, value=reaction)
|
||||
|
||||
def unlike_as(self, identity: Identity):
|
||||
self.uninteract_as(identity, PostInteraction.Types.like)
|
||||
def unlike_as(self, identity: Identity, reaction: str | None = None):
|
||||
self.uninteract_as(identity, PostInteraction.Types.like, value=reaction)
|
||||
|
||||
def boost_as(self, identity: Identity):
|
||||
self.interact_as(identity, PostInteraction.Types.boost)
|
||||
|
|
49
tests/activities/models/test_reactions.py
Normal file
49
tests/activities/models/test_reactions.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
import pytest
|
||||
|
||||
from activities.models import Post, TimelineEvent
|
||||
from activities.services import PostService
|
||||
from users.models import Identity, InboxMessage
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize("local", [True, False])
|
||||
@pytest.mark.parametrize("reaction", ["\U0001F607"])
|
||||
def test_react_notification(
|
||||
identity: Identity,
|
||||
other_identity: Identity,
|
||||
remote_identity: Identity,
|
||||
stator,
|
||||
local: bool,
|
||||
reaction: str,
|
||||
):
|
||||
"""
|
||||
Ensures that a like of a local Post notifies its author
|
||||
"""
|
||||
post = Post.create_local(author=identity, content="I love birds!")
|
||||
if local:
|
||||
PostService(post).like_as(other_identity, reaction)
|
||||
else:
|
||||
message = {
|
||||
"id": "test",
|
||||
"type": "Like",
|
||||
"actor": remote_identity.actor_uri,
|
||||
"object": post.object_uri,
|
||||
"content": reaction,
|
||||
}
|
||||
InboxMessage.objects.create(message=message)
|
||||
|
||||
# Implement any blocks
|
||||
interactor = other_identity if local else remote_identity
|
||||
|
||||
# Run stator thrice - to receive the post, make fanouts and then process them
|
||||
stator.run_single_cycle()
|
||||
stator.run_single_cycle()
|
||||
stator.run_single_cycle()
|
||||
|
||||
# Verify we got an event
|
||||
event = TimelineEvent.objects.filter(
|
||||
type=TimelineEvent.Types.liked, identity=identity
|
||||
).first()
|
||||
assert event
|
||||
assert event.subject_identity == interactor
|
||||
assert event.subject_post_interaction.value == reaction
|
Loading…
Reference in a new issue