Skip to content

Commit

Permalink
🦺 ensure message fields are correct for response/not response
Browse files Browse the repository at this point in the history
  • Loading branch information
krmax44 committed Dec 16, 2024
1 parent befa14d commit 7c7e499
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 3 deletions.
2 changes: 2 additions & 0 deletions froide/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from froide.foirequest.models import FoiMessage, FoiRequest
from froide.foirequest.signals import email_left_queue
from froide.foirequest.tests.factories import (
FoiMessageDraftFactory,
FoiMessageFactory,
FoiProjectFactory,
FoiRequestFactory,
Expand All @@ -33,6 +34,7 @@
register(FoiRequestFollowerFactory)
register(PublicBodyFactory)
register(FoiMessageFactory)
register(FoiMessageDraftFactory)
register(ClassificationFactory)
register(FoiLawFactory)
register(JurisdictionFactory)
Expand Down
15 changes: 14 additions & 1 deletion froide/foirequest/api_views/message.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _

from django_filters import rest_framework as filters
from rest_framework import permissions, viewsets
Expand Down Expand Up @@ -77,6 +78,18 @@ def publish(self, request, pk=None):
if not message.is_response:
message.sender_user = request.user

if not message.can_be_published():
if message.is_response:
error_message = _(
"Response messages must have a sender public body, no sender user and no recipient public body."
)
else:
error_message = _(
"Non-response messages must have a recipent public body, but no sender public body."
)

return Response({"detail": error_message}, status=400)

message.save()

if message.is_response:
Expand All @@ -85,7 +98,7 @@ def publish(self, request, pk=None):
)
else:
FoiRequest.message_sent.send(
sender=message.request, message=message, uer=request.user
sender=message.request, message=message, user=request.user
)

# return it as a regular message
Expand Down
14 changes: 14 additions & 0 deletions froide/foirequest/models/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,20 @@ class Meta:
verbose_name = _("Freedom of Information Message Draft")
verbose_name_plural = _("Freedom of Information Message Drafts")

def can_be_published(self) -> bool:
# see constraints of FoiMessage
if self.is_response:
return (
self.sender_public_body is not None
and self.recipient_public_body is None
and self.sender_user is None
)
else:
return (
self.sender_public_body is None
and self.recipient_public_body is not None
)


class Delivery(models.TextChoices):
STATUS_UNKNOWN = ("unknown", _("unknown"))
Expand Down
6 changes: 6 additions & 0 deletions froide/foirequest/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
FoiAttachment,
FoiEvent,
FoiMessage,
FoiMessageDraft,
FoiProject,
FoiRequest,
PublicBodySuggestion,
Expand Down Expand Up @@ -156,6 +157,11 @@ class Meta:
not_publishable = False


class FoiMessageDraftFactory(FoiMessageFactory):
class Meta:
model = FoiMessageDraft


class FoiAttachmentFactory(DjangoModelFactory):
class Meta:
model = FoiAttachment
Expand Down
58 changes: 56 additions & 2 deletions froide/foirequest/tests/test_api_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,28 @@ def test_message_draft(client: Client, user):
response = client.get(reverse("api:message-detail", kwargs={"pk": message_id}))
assert response.status_code == 404

# can't publish without recipient
publish_uri = reverse("api:message-draft-publish", kwargs={"pk": message_id})
response = client.post(publish_uri)
assert response.status_code == 400

# letter was sent by public body to user
public_body = factories.PublicBodyFactory.create()
response = client.patch(
resource_uri,
data={
"sender_public_body": reverse(
"api:publicbody-detail", kwargs={"pk": public_body.pk}
),
"recipient_public_body": None,
"is_response": True,
},
content_type="application/json",
)
assert response.status_code == 200

# publish
resource_uri = reverse("api:message-draft-publish", kwargs={"pk": message_id})
response = client.post(resource_uri)
response = client.post(publish_uri)
assert response.status_code == 200
assert "/draft/" not in response.json()["resource_uri"]

Expand All @@ -104,6 +123,34 @@ def test_message_draft(client: Client, user):
response = client.delete(resource_uri)
assert response.status_code == 404

# user send a message to public body
response = client.post(
"/api/v1/message/draft/",
data={
"request": reverse("api:request-detail", kwargs={"pk": request.pk}),
"kind": "post",
"recipient_public_body": reverse(
"api:publicbody-detail", kwargs={"pk": public_body.pk}
),
"sender_public_body": None,
"is_response": False,
},
content_type="application/json",
)
assert response.status_code == 201
print(response.json())

message_id = response.json()["id"]
publish_uri = reverse("api:message-draft-publish", kwargs={"pk": message_id})

response = client.post(publish_uri)
assert response.status_code == 200

# ensure event was created
assert FoiEvent.objects.get(
message=message_id, event_name="message_sent", user=user
)


@pytest.mark.django_db
def test_auth(client, user):
Expand All @@ -122,6 +169,13 @@ def test_auth(client, user):
)
assert response.status_code == 401

# can't publish drafts
draft = factories.FoiMessageDraftFactory.create(request=request)
response = client.post(
reverse("api:message-draft-publish", kwargs={"pk": draft.pk})
)
assert response.status_code == 401

# needs to be own request
client.login(email=user.email, password="froide")
response = client.post(
Expand Down

0 comments on commit 7c7e499

Please sign in to comment.