diff --git a/adhocracy-plus/config/urls.py b/adhocracy-plus/config/urls.py index 501076c0f..09bc61ef8 100644 --- a/adhocracy-plus/config/urls.py +++ b/adhocracy-plus/config/urls.py @@ -30,6 +30,7 @@ from apps.interactiveevents.api import LikesViewSet from apps.interactiveevents.api import LiveQuestionViewSet from apps.interactiveevents.routers import LikesDefaultRouter +from apps.moderatorfeedback.api import AiCommentFeedbackViewSet from apps.moderatorfeedback.api import CommentWithFeedbackViewSet from apps.moderatorfeedback.api import ModeratorCommentFeedbackViewSet from apps.moderatorremark.api import ModeratorRemarkViewSet @@ -86,6 +87,7 @@ comment_router.register( r"moderatorfeedback", ModeratorCommentFeedbackViewSet, basename="moderatorfeedback" ) +comment_router.register(r"aicomments", AiCommentFeedbackViewSet, basename="aicomments") urlpatterns = [ # General platform urls diff --git a/apps/ai_reports/models.py b/apps/ai_reports/models.py index 7592e1dd1..44d02b63a 100644 --- a/apps/ai_reports/models.py +++ b/apps/ai_reports/models.py @@ -14,3 +14,6 @@ class AiReport(TimeStampedModel): on_delete=models.CASCADE, related_name="ai_report", ) + + def __str__(self): + return "%s" % (self.explanation) diff --git a/apps/ai_reports/serializers.py b/apps/ai_reports/serializers.py new file mode 100644 index 000000000..6fe6f1930 --- /dev/null +++ b/apps/ai_reports/serializers.py @@ -0,0 +1,13 @@ +from rest_framework import serializers + +from apps.ai_reports.models import AiReport + + +class AiReportSerializer(serializers.ModelSerializer): + class Meta: + model = AiReport + fields = ( + "explanation", + "category", + "comment", + ) diff --git a/apps/moderatorfeedback/api.py b/apps/moderatorfeedback/api.py index a8a31b0d6..51efaf245 100644 --- a/apps/moderatorfeedback/api.py +++ b/apps/moderatorfeedback/api.py @@ -4,6 +4,8 @@ from adhocracy4.api.mixins import CommentMixin from adhocracy4.api.permissions import ViewSetRulesPermission from adhocracy4.comments_async import api as a4_api +from apps.ai_reports.models import AiReport +from apps.ai_reports.serializers import AiReportSerializer from apps.moderatorfeedback.models import ModeratorCommentFeedback from apps.moderatorfeedback.serializers import ModeratorCommentFeedbackSerializer from apps.moderatorfeedback.serializers import ThreadListSerializer @@ -28,6 +30,21 @@ def get_queryset(self): return ModeratorCommentFeedback.objects.filter(comment=self.comment) +class AiCommentFeedbackViewSet( + CommentMixin, + mixins.ListModelMixin, + viewsets.GenericViewSet, +): + serializer_class = AiReportSerializer + permission_classes = (ViewSetRulesPermission,) + + def get_permission_object(self): + return self.comment + + def get_queryset(self): + return AiReport.objects.filter(comment=self.comment) + + class CommentWithFeedbackViewSet(a4_api.CommentViewSet): def get_serializer_class(self): if self.action == "list": diff --git a/apps/moderatorfeedback/serializers.py b/apps/moderatorfeedback/serializers.py index 565c7bcb8..65537eb02 100644 --- a/apps/moderatorfeedback/serializers.py +++ b/apps/moderatorfeedback/serializers.py @@ -34,6 +34,7 @@ def get_last_edit(self, feedback): class CommentWithFeedbackSerializer(a4_serializers.CommentSerializer): moderator_feedback = ModeratorCommentFeedbackSerializer(read_only=True) + ai_report = serializers.StringRelatedField(read_only=True) class Meta: model = Comment diff --git a/apps/userdashboard/api.py b/apps/userdashboard/api.py index 3deb62c44..8af337e4a 100644 --- a/apps/userdashboard/api.py +++ b/apps/userdashboard/api.py @@ -76,13 +76,6 @@ def get_queryset(self): + Count("ai_report", distinct=True), ) - reported_by = self.request.query_params.get("reported_by") - - if reported_by == "ai": - comments = comments.filter(ai_report__isnull=False) - elif reported_by == "users": - comments = comments.filter(reports__isnull=False) - return comments def update(self, request, *args, **kwargs): diff --git a/changelog/7571.md b/changelog/7571.md new file mode 100644 index 000000000..3cd0f6d9e --- /dev/null +++ b/changelog/7571.md @@ -0,0 +1,3 @@ +### Added + +- Ai report serializer for comments viewset (#7571) diff --git a/tests/moderatorfeedback/conftest.py b/tests/moderatorfeedback/conftest.py index 25648287d..931870fd2 100644 --- a/tests/moderatorfeedback/conftest.py +++ b/tests/moderatorfeedback/conftest.py @@ -1,8 +1,10 @@ from pytest_factoryboy import register +from tests.ai_reports.factories import AiReportFactory from tests.ideas.factories import IdeaFactory from .factories import ModeratorCommentFeedbackFactory +register(AiReportFactory) register(IdeaFactory) register(ModeratorCommentFeedbackFactory) diff --git a/tests/moderatorfeedback/test_moderator_comment_feedback_api.py b/tests/moderatorfeedback/test_moderator_comment_feedback_api.py index 0f6b6a362..8a42844c5 100644 --- a/tests/moderatorfeedback/test_moderator_comment_feedback_api.py +++ b/tests/moderatorfeedback/test_moderator_comment_feedback_api.py @@ -4,6 +4,39 @@ from apps.moderatorfeedback.models import ModeratorCommentFeedback +@pytest.mark.django_db +def test_moderator_and_ai_report_added_in_comment( + idea, + comment_factory, + apiclient, + moderator_comment_feedback_factory, + ai_report_factory, +): + comment = comment_factory(content_object=idea) + feedback = moderator_comment_feedback_factory( + comment=comment, + ) + assert feedback.project == comment.project + + ai_report = ai_report_factory(comment=comment) + url = reverse( + "comments-detail", + kwargs={ + "pk": comment.pk, + "content_type": comment.content_type.pk, + "object_pk": comment.object_pk, + }, + ) + response = apiclient.get(url) + assert ( + feedback.feedback_text in response.data["moderator_feedback"]["feedback_text"] + ) + assert comment.ai_report.explanation == ai_report.explanation + + assert ai_report.explanation in response.data["ai_report"] + assert response.status_code == 200 + + @pytest.mark.django_db def test_anonymous_cannot_add_feedback(apiclient, idea, comment_factory): comment = comment_factory(pk=1, content_object=idea)