mirror of
https://github.com/jointakahe/takahe.git
synced 2025-02-21 09:56:15 +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
|
# 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)
|
value = models.CharField(max_length=50, blank=True, null=True)
|
||||||
|
|
||||||
# When the activity was originally created (as opposed to when we received it)
|
# When the activity was originally created (as opposed to when we received it)
|
||||||
|
@ -392,6 +392,7 @@ class PostInteraction(StatorModel):
|
||||||
# Get the right type
|
# Get the right type
|
||||||
if data["type"].lower() == "like":
|
if data["type"].lower() == "like":
|
||||||
type = cls.Types.like
|
type = cls.Types.like
|
||||||
|
value = data.get("content") or data.get("_misskey_reaction")
|
||||||
elif data["type"].lower() == "announce":
|
elif data["type"].lower() == "announce":
|
||||||
type = cls.Types.boost
|
type = cls.Types.boost
|
||||||
elif (
|
elif (
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
from types import EllipsisType
|
||||||
|
|
||||||
from activities.models import (
|
from activities.models import (
|
||||||
Post,
|
Post,
|
||||||
|
@ -38,7 +39,7 @@ class PostService:
|
||||||
def __init__(self, post: Post):
|
def __init__(self, post: Post):
|
||||||
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
|
Performs an interaction on this Post
|
||||||
"""
|
"""
|
||||||
|
@ -46,28 +47,39 @@ class PostService:
|
||||||
type=type,
|
type=type,
|
||||||
identity=identity,
|
identity=identity,
|
||||||
post=self.post,
|
post=self.post,
|
||||||
|
value=value,
|
||||||
)[0]
|
)[0]
|
||||||
if interaction.state not in PostInteractionStates.group_active():
|
if interaction.state not in PostInteractionStates.group_active():
|
||||||
interaction.transition_perform(PostInteractionStates.new)
|
interaction.transition_perform(PostInteractionStates.new)
|
||||||
self.post.calculate_stats()
|
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
|
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(
|
for interaction in PostInteraction.objects.filter(
|
||||||
type=type,
|
type=type,
|
||||||
identity=identity,
|
identity=identity,
|
||||||
post=self.post,
|
post=self.post,
|
||||||
|
**additional_fields,
|
||||||
):
|
):
|
||||||
interaction.transition_perform(PostInteractionStates.undone)
|
interaction.transition_perform(PostInteractionStates.undone)
|
||||||
|
|
||||||
self.post.calculate_stats()
|
self.post.calculate_stats()
|
||||||
|
|
||||||
def like_as(self, identity: Identity):
|
def like_as(self, identity: Identity, reaction: str | None = None):
|
||||||
self.interact_as(identity, PostInteraction.Types.like)
|
"""
|
||||||
|
Add a Like to the post, including reactions.
|
||||||
|
"""
|
||||||
|
self.interact_as(identity, PostInteraction.Types.like, value=reaction)
|
||||||
|
|
||||||
def unlike_as(self, identity: Identity):
|
def unlike_as(self, identity: Identity, reaction: str | None = None):
|
||||||
self.uninteract_as(identity, PostInteraction.Types.like)
|
self.uninteract_as(identity, PostInteraction.Types.like, value=reaction)
|
||||||
|
|
||||||
def boost_as(self, identity: Identity):
|
def boost_as(self, identity: Identity):
|
||||||
self.interact_as(identity, PostInteraction.Types.boost)
|
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