chat/apps/chat/tests/test_conversation_close.py

112 lines
3.3 KiB
Python

import uuid
from unittest.mock import Mock
import pytest
from apps.chat.exceptions import ConversationClosedError
from apps.chat.models import Conversation, ConversationStatus
from apps.chat.services.conversation import ConversationService
from apps.chat.services.message import MessageService
def _make_conv(status=ConversationStatus.OPEN, closed_by_uuid=None, channel_id="ch-close"):
return Conversation.objects.create(
mattermost_channel_id=channel_id,
status=status,
closed_by_uuid=closed_by_uuid,
)
def _svc():
return ConversationService(mattermost_client=Mock())
@pytest.mark.django_db
def test_close_sets_status_and_closed_by():
conv = _make_conv()
closer = uuid.uuid4()
result = _svc().close(conv.uuid, closer)
assert result.status == ConversationStatus.CLOSED
assert result.closed_by_uuid == closer
conv.refresh_from_db()
assert conv.status == ConversationStatus.CLOSED
assert conv.closed_by_uuid == closer
@pytest.mark.django_db
def test_close_is_idempotent():
closer = uuid.uuid4()
other = uuid.uuid4()
conv = _make_conv(status=ConversationStatus.CLOSED, closed_by_uuid=closer)
result = _svc().close(conv.uuid, other)
assert result.status == ConversationStatus.CLOSED
assert result.closed_by_uuid == closer # unchanged — original closer preserved
@pytest.mark.django_db
def test_reopen_by_closer_succeeds():
closer = uuid.uuid4()
conv = _make_conv(status=ConversationStatus.CLOSED, closed_by_uuid=closer)
result = _svc().reopen(conv.uuid, closer)
assert result.status == ConversationStatus.OPEN
assert result.closed_by_uuid is None
@pytest.mark.django_db
def test_reopen_by_other_user_raises_permission_error():
closer = uuid.uuid4()
other = uuid.uuid4()
conv = _make_conv(status=ConversationStatus.CLOSED, closed_by_uuid=closer)
with pytest.raises(PermissionError):
_svc().reopen(conv.uuid, other)
conv.refresh_from_db()
assert conv.status == ConversationStatus.CLOSED
@pytest.mark.django_db
def test_reopen_is_idempotent_when_already_open():
conv = _make_conv(status=ConversationStatus.OPEN)
someone = uuid.uuid4()
result = _svc().reopen(conv.uuid, someone)
assert result.status == ConversationStatus.OPEN
@pytest.mark.django_db
def test_send_message_to_closed_conversation_raises():
closer = uuid.uuid4()
conv = _make_conv(status=ConversationStatus.CLOSED, closed_by_uuid=closer)
sender_uuid = uuid.uuid4()
svc = MessageService(mattermost_client=Mock(), storage_service=Mock(), publishers=[])
with pytest.raises(ConversationClosedError):
svc.send(conv.uuid, sender_uuid, "text", text="hello")
@pytest.mark.django_db
def test_send_message_after_reopen_succeeds():
closer = uuid.uuid4()
conv = _make_conv(status=ConversationStatus.CLOSED, closed_by_uuid=closer)
sender_uuid = uuid.uuid4()
_svc().reopen(conv.uuid, closer)
mm_client = Mock()
mm_client.post_message.return_value = "post-1"
svc = MessageService(mattermost_client=mm_client, storage_service=Mock(), publishers=[])
result = svc.send(conv.uuid, sender_uuid, "text", text="hello again")
assert result["post_id"] == "post-1"
mm_client.post_message.assert_called_once_with("ch-close", "hello again")