Skip to content

Commit

Permalink
feat: discussion user endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
helllllllder committed Nov 24, 2023
1 parent 2c30be4 commit 08ae98d
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 1 deletion.
2 changes: 2 additions & 0 deletions chats/apps/discussions/models/discussion.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ def create_discussion_user(self, from_user, to_user, role=None):
permission=to_permission, role=role
)
self.check_queued()
self.notify_user(action="update", user_permission=to_permission)

return discussion_user

def create_discussion_message(self, message, user=None, system=False, notify=True):
Expand Down
1 change: 1 addition & 0 deletions chats/apps/discussions/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .discussion_users import DiscussionUserListSerializer # noqa
from .discussions import DiscussionCreateSerializer # noqa
from .discussions import DiscussionDetailSerializer # noqa
from .discussions import DiscussionListSerializer # noqa
22 changes: 22 additions & 0 deletions chats/apps/discussions/serializers/discussion_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from rest_framework import serializers

from ..models import DiscussionUser


class DiscussionUserListSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(
source="permission.user.first_name", read_only=True
)
last_name = serializers.CharField(
source="permission.user.last_name", read_only=True
)
email = serializers.CharField(source="permission.user.email", read_only=True)

class Meta:
model = DiscussionUser
fields = [
"first_name",
"last_name",
"email",
"role",
]
129 changes: 129 additions & 0 deletions chats/apps/discussions/tests/test_discussion_users_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from django.urls import reverse
from parameterized import parameterized
from rest_framework import status
from rest_framework.test import APITestCase


class CreateDiscussionUserViewActionTests(APITestCase):
# ("Scenario description", room, queue, subject, initial_message, user_token, expected_response_status)
fixtures = [
"chats/fixtures/fixture_app.json",
"chats/fixtures/fixture_discussion.json",
]

parameters = [
# Success parameters
(
"Creator can add users to discussion",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
"[email protected]",
"d7fddba0b1dfaad72aa9e21876cbc93caa9ce3fa",
status.HTTP_201_CREATED,
),
(
"Queue user can add itself to the discussion",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
"[email protected]",
"a0358e20c8755568189d3a7e688ac3ec771317e2",
status.HTTP_201_CREATED,
),
(
"Admin can add itself to the discussion",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
"[email protected]",
"4215e6d6666e54f7db9f98100533aa68909fd855",
status.HTTP_201_CREATED,
),
(
"Queue user cannot add other users to the discussion",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
"[email protected]",
"a0358e20c8755568189d3a7e688ac3ec771317e2",
status.HTTP_400_BAD_REQUEST,
),
(
"Added users cannot add other users to the discussion",
"36584c70-aaf9-4f5c-b0c3-0547bb23879d",
"[email protected]",
"a0358e20c8755568189d3a7e688ac3ec771317e2",
status.HTTP_400_BAD_REQUEST,
),
(
"Cannot add a user that is already added to the discussion",
"36584c70-aaf9-4f5c-b0c3-0547bb23879d",
"[email protected]",
"a0358e20c8755568189d3a7e688ac3ec771317e2",
status.HTTP_400_BAD_REQUEST,
),
]

def _create_discussion_user(self, token, discussion, body):
url = reverse("discussion-detail", kwargs={"uuid": discussion}) + "add_agents/"
client = self.client
client.credentials(HTTP_AUTHORIZATION="Token " + token)
response = client.post(url, format="json", data=body)
return response

@parameterized.expand(parameters)
def test_add_user_to_discussion(
self, _, discussion, user_email, token, expected_status
):
discussion_data = {
"user_email": user_email,
}

response = self._create_discussion_user(token, discussion, discussion_data)

self.assertEqual(response.status_code, expected_status)


class ListDiscussionUserViewActionTests(APITestCase):
fixtures = [
"chats/fixtures/fixture_app.json",
"chats/fixtures/fixture_discussion.json",
]
parameters = [
(
"Creator can list all users on the discussions",
"d7fddba0b1dfaad72aa9e21876cbc93caa9ce3fa",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
status.HTTP_200_OK,
1,
),
(
"Admin can list all users on the discussions",
"4215e6d6666e54f7db9f98100533aa68909fd855",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
status.HTTP_200_OK,
1,
),
(
"Added user can list all users on the discussions",
"a0358e20c8755568189d3a7e688ac3ec771317e2",
"36584c70-aaf9-4f5c-b0c3-0547bb23879d",
status.HTTP_200_OK,
3,
),
(
"Outside project user cannot list discussion users",
"1218da72b087b8be7f0e2520a515e968ab866fdd",
"3c2d1694-8db9-4f09-976b-e263f9d79c99",
status.HTTP_403_FORBIDDEN,
None,
),
]

def _list_discussion_user(self, token, discussion, params={}):
url = reverse("discussion-detail", kwargs={"uuid": discussion}) + "list_agents/"
client = self.client
client.credentials(HTTP_AUTHORIZATION="Token " + token)
response = client.get(url, data=params)
return response

@parameterized.expand(parameters)
def test_discussion_user_list(
self, _, token, discussion, expected_status, expected_count
):
response = self._list_discussion_user(token=token, discussion=discussion)
self.assertEqual(response.status_code, expected_status)
self.assertEqual(response.json().get("count"), expected_count)
54 changes: 54 additions & 0 deletions chats/apps/discussions/views/_discussion_user_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response

from ..app_services.feedbacks import create_discussion_feedback_message
from ..models import DiscussionUser
from ..serializers import DiscussionUserListSerializer

User = get_user_model()


class DiscussionUserActionsMixin:
"""This should be used with a Discussion model viewset"""

@action(detail=True, methods=["POST"], url_name="add_agents", filterset_class=None)
def add_agents(self, request, *args, **kwargs):
try:
user = request.data.get("user_email")
user = User.objects.get(email=user)
discussion = self.get_object()
added_agent = discussion.create_discussion_user(
from_user=request.user, to_user=user
)
feedback = {"user": added_agent.user.first_name}
create_discussion_feedback_message(discussion, feedback, "da")

return Response(
{
"first_name": added_agent.user.first_name,
"last_name": added_agent.user.last_name,
"role": added_agent.role,
},
status=status.HTTP_201_CREATED,
)
except Exception as error:
return Response(
{"detail": f"{type(error)}: {error}"},
status=status.HTTP_400_BAD_REQUEST,
)

@action(detail=True, methods=["GET"], url_name="list_agents", filterset_class=None)
def list_agents(self, request, *args, **kwargs):
discussion = self.get_object()

queryset = DiscussionUser.objects.filter(discussion=discussion)

page = self.paginate_queryset(queryset)
if page is not None:
serializer = DiscussionUserListSerializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = DiscussionUserListSerializer(queryset, many=True)
return Response(serializer.data)
3 changes: 2 additions & 1 deletion chats/apps/discussions/views/discussion.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
DiscussionListSerializer,
)
from ..usecases import CreateDiscussionUseCase
from ._discussion_user_actions import DiscussionUserActionsMixin
from .permissions import CanManageDiscussion

User = get_user_model()


class DiscussionViewSet(viewsets.ModelViewSet):
class DiscussionViewSet(viewsets.ModelViewSet, DiscussionUserActionsMixin):
queryset = Discussion.objects.all()
filter_backends = [filters.OrderingFilter, DjangoFilterBackend]
filterset_class = DiscussionFilter
Expand Down

0 comments on commit 08ae98d

Please sign in to comment.