Skip to content

Commit

Permalink
feat: changed message object to dictionary when sending ACE_MESSAGE_S…
Browse files Browse the repository at this point in the history
…ENT signal (#306)
  • Loading branch information
muhammadadeeltajamul authored Sep 16, 2024
1 parent da4da56 commit d882dbd
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 8 deletions.
2 changes: 1 addition & 1 deletion edx_ace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .recipient import Recipient
from .recipient_resolver import RecipientResolver

__version__ = '1.11.1'
__version__ = '1.11.2'


__all__ = [
Expand Down
4 changes: 2 additions & 2 deletions edx_ace/delivery.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from django.conf import settings

from edx_ace.errors import RecoverableChannelDeliveryError
from edx_ace.signals import ACE_MESSAGE_SENT
from edx_ace.utils.date import get_current_time
from edx_ace.utils.signals import send_ace_message_sent_signal

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -61,7 +61,7 @@ def deliver(channel, rendered_message, message):
message.report(f'{channel_type}_delivery_retried', num_seconds)
else:
message.report(f'{channel_type}_delivery_succeeded', True)
ACE_MESSAGE_SENT.send(sender=channel, message=message)
send_ace_message_sent_signal(channel, message)
return

delivery_expired_report = f'{channel_type}_delivery_expired'
Expand Down
10 changes: 5 additions & 5 deletions edx_ace/tests/test_delivery.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ def setUp(self):
)
self.current_time = datetime.datetime.utcnow().replace(tzinfo=tzutc())

@patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
@patch('edx_ace.delivery.send_ace_message_sent_signal')
def test_happy_path(self, mock_ace_message_sent):
deliver(self.mock_channel, sentinel.rendered_email, self.message)
self.mock_channel.deliver.assert_called_once_with(self.message, sentinel.rendered_email)
# check if ACE_MESSAGE_SENT is raised
mock_ace_message_sent.assert_called_once_with(sender=self.mock_channel, message=self.message)
mock_ace_message_sent.assert_called_once_with(self.mock_channel, self.message)

def test_fatal_error(self):
self.mock_channel.deliver.side_effect = FatalChannelDeliveryError('testing')
with self.assertRaises(FatalChannelDeliveryError):
deliver(self.mock_channel, sentinel.rendered_email, self.message)

@patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
@patch('edx_ace.delivery.send_ace_message_sent_signal')
@patch('edx_ace.delivery.get_current_time')
def test_custom_message_expiration(self, mock_get_current_time, mock_ace_message_sent):
self.message.expiration_time = self.current_time - datetime.timedelta(seconds=10)
Expand Down Expand Up @@ -106,7 +106,7 @@ def test_multiple_retries(self, mock_get_current_time, mock_time):
assert mock_time.sleep.call_args_list == [call(1), call(1)]
assert self.mock_channel.deliver.call_count == 3

@patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
@patch('edx_ace.delivery.send_ace_message_sent_signal')
def test_message_sent_signal_for_push_channel(self, mock_ace_message_sent):
"""
Test that ACE_MESSAGE_SENT signal is sent when a message is delivered to a push channel.
Expand All @@ -117,4 +117,4 @@ def test_message_sent_signal_for_push_channel(self, mock_ace_message_sent):
)
deliver(mock_push_channel, sentinel.rendered_email, self.message)
# check if ACE_MESSAGE_SENT is raised
mock_ace_message_sent.assert_called_once_with(sender=mock_push_channel, message=self.message)
mock_ace_message_sent.assert_called_once_with(mock_push_channel, self.message)
47 changes: 47 additions & 0 deletions edx_ace/tests/utils/test_signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""
Tests for the utils/signals module.
"""
from django.test import TestCase

from edx_ace.utils.signals import make_serializable_object


class TestMakeSerializableObject(TestCase):
def test_primitive_types(self):
self.assertEqual(make_serializable_object(42), 42)
self.assertEqual(make_serializable_object(3.14), 3.14)
self.assertEqual(make_serializable_object("string"), "string")
self.assertEqual(make_serializable_object(True), True)
self.assertEqual(make_serializable_object(None), None)

def test_dict(self):
input_dict = {
"int": 1,
"float": 2.0,
"str": "test",
"bool": False,
"none": None,
"list": [1, 2, 3],
"nested_dict": {"key": "value"}
}
self.assertEqual(make_serializable_object(input_dict), input_dict)

def test_list(self):
input_list = [1, 2.0, "test", False, None, [1, 2, 3], {"key": "value"}]
self.assertEqual(make_serializable_object(input_list), input_list)

def test_non_serializable(self):
class NonSerializable:
pass

obj = NonSerializable()
self.assertEqual(make_serializable_object(obj), str(obj))

def test_non_serializable_list(self):
class NonSerializable:
pass

obj = NonSerializable()
obj2 = NonSerializable()
obj_list = [obj, obj2]
self.assertEqual(make_serializable_object(obj_list), [str(obj), str(obj2)])
46 changes: 46 additions & 0 deletions edx_ace/utils/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Utils for signals.
"""
from edx_ace.signals import ACE_MESSAGE_SENT


def make_serializable_object(obj):
"""
Takes a dictionary/list and returns a dictionary/list with all the values converted
to JSON serializable objects.
"""
try:
if isinstance(obj, (int, float, str, bool)) or obj is None:
return obj
elif isinstance(obj, dict):
return {key: make_serializable_object(value) for key, value in obj.items()}
elif isinstance(obj, list):
return [make_serializable_object(element) for element in obj]
except Exception: # pylint: disable=broad-except
pass
return str(obj)


def send_ace_message_sent_signal(channel, message):
"""
Creates dictionary from message, makes it JSON serializable and
sends the ACE_MESSAGE_SENT signal.
"""
try:
channel_name = channel.__class__.__name__
except AttributeError:
channel_name = 'Other'
data = {
'name': message.name,
'app_label': message.app_label,
'recipient': {
'email': getattr(message.recipient, 'email_address', ''),
'user_id': getattr(message.recipient, 'lms_user_id', ''),
},
'channel': channel_name,
'context': message.context,
'options': message.options,
'uuid': str(message.uuid),
'send_uuid': str(message.send_uuid),
}
ACE_MESSAGE_SENT.send(sender=channel, message=make_serializable_object(data))

0 comments on commit d882dbd

Please sign in to comment.