Skip to content

Commit 91420d2

Browse files
send email to fogbugz add test
1 parent 339cd1a commit 91420d2

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

services/web/server/src/simcore_service_webserver/conversations/_controller/_conversations_messages_rest.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import functools
12
import logging
3+
from typing import Any
24

35
from aiohttp import web
6+
from common_library.json_serialization import json_dumps
47
from models_library.api_schemas_webserver.conversations import (
58
ConversationMessagePatch,
69
ConversationMessageRestGet,
@@ -16,6 +19,7 @@
1619
PageQueryParameters,
1720
)
1821
from models_library.rest_pagination_utils import paginate_data
22+
from models_library.utils.fastapi_encoders import jsonable_encoder
1923
from pydantic import BaseModel, ConfigDict
2024
from servicelib.aiohttp import status
2125
from servicelib.aiohttp.requests_validation import (
@@ -58,6 +62,10 @@ class _ConversationMessageCreateBodyParams(BaseModel):
5862
model_config = ConfigDict(extra="forbid")
5963

6064

65+
def _json_encoder_and_dumps(obj: Any, **kwargs):
66+
return json_dumps(jsonable_encoder(obj), **kwargs)
67+
68+
6169
@routes.post(
6270
f"/{VTAG}/conversations/{{conversation_id}}/messages",
6371
name="create_conversation_message",
@@ -102,9 +110,11 @@ async def create_conversation_message(request: web.Request):
102110
email_template_path = await products_web.get_product_template_path(
103111
request, template_name
104112
)
105-
_conversation_url = (
106-
f"{request.url}/#/conversations/{path_params.conversation_id}"
107-
)
113+
_url = request.url
114+
if _url.port:
115+
_conversation_url = f"{_url.scheme}://{_url.host}:{_url.port}/#/conversations/{path_params.conversation_id}"
116+
else:
117+
_conversation_url = f"{_url.scheme}://{_url.host}/#/conversations/{path_params.conversation_id}"
108118
_extra_context = conversation.extra_context
109119
await email_service.send_email_from_template(
110120
request,
@@ -124,6 +134,7 @@ async def create_conversation_message(request: web.Request):
124134
"conversation_url": _conversation_url,
125135
"message_content": message.content,
126136
"extra_context": _extra_context,
137+
"dumps": functools.partial(_json_encoder_and_dumps, indent=1),
127138
},
128139
)
129140
except Exception: # pylint: disable=broad-except

services/web/server/src/simcore_service_webserver/templates/common/request_support.jinja2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ TEST extra_context: {{ extra_context }}
2828
</p>
2929

3030
<p>
31-
Extra Contect:
31+
Extra Context:
3232
</p>
3333

3434
<pre>

services/web/server/tests/unit/with_dbs/04/conversations/test_conversations_messages_rest.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,3 +448,62 @@ async def test_conversation_messages_nonexistent_resources(
448448
)
449449
resp = await client.delete(f"{delete_url}")
450450
await assert_status(resp, status.HTTP_404_NOT_FOUND)
451+
452+
453+
### Test with a database
454+
@pytest.mark.parametrize("user_role", [UserRole.USER])
455+
async def test_conversation_messages_with_database(
456+
client: TestClient,
457+
logged_user: UserInfoDict,
458+
mocker: MockerFixture,
459+
):
460+
"""Test conversation messages with direct database interaction"""
461+
# Mock the email service to verify it's called for first message
462+
mock_send_email = mocker.patch(
463+
"simcore_service_webserver.email.email_service.send_email_from_template"
464+
)
465+
466+
assert client.app
467+
468+
# Create a conversation directly via API (no mocks)
469+
base_url = client.app.router["list_conversations"].url_for()
470+
body = {"name": "Database Test Conversation", "type": "SUPPORT"}
471+
resp = await client.post(f"{base_url}", json=body)
472+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
473+
conversation_id = data["conversationId"]
474+
475+
# Verify the conversation was created
476+
assert conversation_id is not None
477+
assert data["name"] == "Database Test Conversation"
478+
assert data["type"] == "SUPPORT"
479+
480+
# Create a message in the conversation
481+
create_message_url = client.app.router["create_conversation_message"].url_for(
482+
conversation_id=conversation_id
483+
)
484+
message_body = {"content": "Hello from database test", "type": "MESSAGE"}
485+
resp = await client.post(f"{create_message_url}", json=message_body)
486+
message_data, _ = await assert_status(resp, status.HTTP_201_CREATED)
487+
488+
# Verify the message was created
489+
assert message_data["messageId"] is not None
490+
assert message_data["content"] == "Hello from database test"
491+
assert message_data["type"] == "MESSAGE"
492+
assert message_data["conversationId"] == conversation_id
493+
494+
# Verify email was sent for first message
495+
assert mock_send_email.call_count == 1
496+
497+
# Create a second message
498+
second_message_body = {"content": "Second message", "type": "MESSAGE"}
499+
resp = await client.post(f"{create_message_url}", json=second_message_body)
500+
second_message_data, _ = await assert_status(resp, status.HTTP_201_CREATED)
501+
502+
# Verify the second message was created
503+
assert second_message_data["messageId"] is not None
504+
assert second_message_data["content"] == "Second message"
505+
assert second_message_data["type"] == "MESSAGE"
506+
assert second_message_data["conversationId"] == conversation_id
507+
508+
# Verify email was NOT sent again for second message (still only 1 call)
509+
assert mock_send_email.call_count == 1

0 commit comments

Comments
 (0)