edx-ace 1.11.1__tar.gz → 1.11.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {edx-ace-1.11.1/edx_ace.egg-info → edx-ace-1.11.2}/PKG-INFO +1 -1
  2. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/__init__.py +1 -1
  3. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/delivery.py +2 -2
  4. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_delivery.py +5 -5
  5. edx-ace-1.11.2/edx_ace/tests/utils/test_signals.py +47 -0
  6. edx-ace-1.11.2/edx_ace/utils/signals.py +46 -0
  7. {edx-ace-1.11.1 → edx-ace-1.11.2/edx_ace.egg-info}/PKG-INFO +1 -1
  8. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/SOURCES.txt +2 -0
  9. {edx-ace-1.11.1 → edx-ace-1.11.2}/CHANGELOG.rst +0 -0
  10. {edx-ace-1.11.1 → edx-ace-1.11.2}/LICENSE.txt +0 -0
  11. {edx-ace-1.11.1 → edx-ace-1.11.2}/MANIFEST.in +0 -0
  12. {edx-ace-1.11.1 → edx-ace-1.11.2}/README.rst +0 -0
  13. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/ace.py +0 -0
  14. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/apps.py +0 -0
  15. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/__init__.py +0 -0
  16. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/braze.py +0 -0
  17. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/django_email.py +0 -0
  18. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/file.py +0 -0
  19. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/mixins.py +0 -0
  20. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/push_notification.py +0 -0
  21. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/channel/sailthru.py +0 -0
  22. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/errors.py +0 -0
  23. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/message.py +0 -0
  24. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/monitoring.py +0 -0
  25. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/policy.py +0 -0
  26. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/presentation.py +0 -0
  27. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/push_notifications/views/__init__.py +0 -0
  28. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/recipient.py +0 -0
  29. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/recipient_resolver.py +0 -0
  30. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/renderers.py +0 -0
  31. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/serialization.py +0 -0
  32. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/signals.py +0 -0
  33. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/templatetags/acetags.py +0 -0
  34. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/test_utils/__init__.py +0 -0
  35. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_braze.py +0 -0
  36. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_channel_helpers.py +0 -0
  37. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_django_email.py +0 -0
  38. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_file_email.py +0 -0
  39. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_push_notification.py +0 -0
  40. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/channel/test_sailthru.py +0 -0
  41. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_ace.py +0 -0
  42. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_date.py +0 -0
  43. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_message.py +0 -0
  44. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_policy.py +0 -0
  45. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_presentation.py +0 -0
  46. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_templates/testapp/edx_ace/testmessage/email/body.html +0 -0
  47. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/tests/test_templates/testapp/edx_ace/testmessage/email/head.html +0 -0
  48. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/utils/__init__.py +0 -0
  49. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/utils/date.py +0 -0
  50. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/utils/once.py +0 -0
  51. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace/utils/plugins.py +0 -0
  52. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/dependency_links.txt +0 -0
  53. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/entry_points.txt +0 -0
  54. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/not-zip-safe +0 -0
  55. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/requires.txt +0 -0
  56. {edx-ace-1.11.1 → edx-ace-1.11.2}/edx_ace.egg-info/top_level.txt +0 -0
  57. {edx-ace-1.11.1 → edx-ace-1.11.2}/requirements/base.in +0 -0
  58. {edx-ace-1.11.1 → edx-ace-1.11.2}/requirements/constraints.txt +0 -0
  59. {edx-ace-1.11.1 → edx-ace-1.11.2}/setup.cfg +0 -0
  60. {edx-ace-1.11.1 → edx-ace-1.11.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-ace
3
- Version: 1.11.1
3
+ Version: 1.11.2
4
4
  Summary: Framework for Messaging
5
5
  Home-page: https://github.com/openedx/edx-ace
6
6
  Author: edX
@@ -13,7 +13,7 @@ from .policy import Policy, PolicyResult
13
13
  from .recipient import Recipient
14
14
  from .recipient_resolver import RecipientResolver
15
15
 
16
- __version__ = '1.11.1'
16
+ __version__ = '1.11.2'
17
17
 
18
18
 
19
19
  __all__ = [
@@ -10,8 +10,8 @@ import time
10
10
  from django.conf import settings
11
11
 
12
12
  from edx_ace.errors import RecoverableChannelDeliveryError
13
- from edx_ace.signals import ACE_MESSAGE_SENT
14
13
  from edx_ace.utils.date import get_current_time
14
+ from edx_ace.utils.signals import send_ace_message_sent_signal
15
15
 
16
16
  LOG = logging.getLogger(__name__)
17
17
 
@@ -61,7 +61,7 @@ def deliver(channel, rendered_message, message):
61
61
  message.report(f'{channel_type}_delivery_retried', num_seconds)
62
62
  else:
63
63
  message.report(f'{channel_type}_delivery_succeeded', True)
64
- ACE_MESSAGE_SENT.send(sender=channel, message=message)
64
+ send_ace_message_sent_signal(channel, message)
65
65
  return
66
66
 
67
67
  delivery_expired_report = f'{channel_type}_delivery_expired'
@@ -34,19 +34,19 @@ class TestDelivery(TestCase): # pylint: disable=missing-class-docstring
34
34
  )
35
35
  self.current_time = datetime.datetime.utcnow().replace(tzinfo=tzutc())
36
36
 
37
- @patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
37
+ @patch('edx_ace.delivery.send_ace_message_sent_signal')
38
38
  def test_happy_path(self, mock_ace_message_sent):
39
39
  deliver(self.mock_channel, sentinel.rendered_email, self.message)
40
40
  self.mock_channel.deliver.assert_called_once_with(self.message, sentinel.rendered_email)
41
41
  # check if ACE_MESSAGE_SENT is raised
42
- mock_ace_message_sent.assert_called_once_with(sender=self.mock_channel, message=self.message)
42
+ mock_ace_message_sent.assert_called_once_with(self.mock_channel, self.message)
43
43
 
44
44
  def test_fatal_error(self):
45
45
  self.mock_channel.deliver.side_effect = FatalChannelDeliveryError('testing')
46
46
  with self.assertRaises(FatalChannelDeliveryError):
47
47
  deliver(self.mock_channel, sentinel.rendered_email, self.message)
48
48
 
49
- @patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
49
+ @patch('edx_ace.delivery.send_ace_message_sent_signal')
50
50
  @patch('edx_ace.delivery.get_current_time')
51
51
  def test_custom_message_expiration(self, mock_get_current_time, mock_ace_message_sent):
52
52
  self.message.expiration_time = self.current_time - datetime.timedelta(seconds=10)
@@ -106,7 +106,7 @@ class TestDelivery(TestCase): # pylint: disable=missing-class-docstring
106
106
  assert mock_time.sleep.call_args_list == [call(1), call(1)]
107
107
  assert self.mock_channel.deliver.call_count == 3
108
108
 
109
- @patch('edx_ace.delivery.ACE_MESSAGE_SENT.send')
109
+ @patch('edx_ace.delivery.send_ace_message_sent_signal')
110
110
  def test_message_sent_signal_for_push_channel(self, mock_ace_message_sent):
111
111
  """
112
112
  Test that ACE_MESSAGE_SENT signal is sent when a message is delivered to a push channel.
@@ -117,4 +117,4 @@ class TestDelivery(TestCase): # pylint: disable=missing-class-docstring
117
117
  )
118
118
  deliver(mock_push_channel, sentinel.rendered_email, self.message)
119
119
  # check if ACE_MESSAGE_SENT is raised
120
- mock_ace_message_sent.assert_called_once_with(sender=mock_push_channel, message=self.message)
120
+ mock_ace_message_sent.assert_called_once_with(mock_push_channel, self.message)
@@ -0,0 +1,47 @@
1
+ """
2
+ Tests for the utils/signals module.
3
+ """
4
+ from django.test import TestCase
5
+
6
+ from edx_ace.utils.signals import make_serializable_object
7
+
8
+
9
+ class TestMakeSerializableObject(TestCase):
10
+ def test_primitive_types(self):
11
+ self.assertEqual(make_serializable_object(42), 42)
12
+ self.assertEqual(make_serializable_object(3.14), 3.14)
13
+ self.assertEqual(make_serializable_object("string"), "string")
14
+ self.assertEqual(make_serializable_object(True), True)
15
+ self.assertEqual(make_serializable_object(None), None)
16
+
17
+ def test_dict(self):
18
+ input_dict = {
19
+ "int": 1,
20
+ "float": 2.0,
21
+ "str": "test",
22
+ "bool": False,
23
+ "none": None,
24
+ "list": [1, 2, 3],
25
+ "nested_dict": {"key": "value"}
26
+ }
27
+ self.assertEqual(make_serializable_object(input_dict), input_dict)
28
+
29
+ def test_list(self):
30
+ input_list = [1, 2.0, "test", False, None, [1, 2, 3], {"key": "value"}]
31
+ self.assertEqual(make_serializable_object(input_list), input_list)
32
+
33
+ def test_non_serializable(self):
34
+ class NonSerializable:
35
+ pass
36
+
37
+ obj = NonSerializable()
38
+ self.assertEqual(make_serializable_object(obj), str(obj))
39
+
40
+ def test_non_serializable_list(self):
41
+ class NonSerializable:
42
+ pass
43
+
44
+ obj = NonSerializable()
45
+ obj2 = NonSerializable()
46
+ obj_list = [obj, obj2]
47
+ self.assertEqual(make_serializable_object(obj_list), [str(obj), str(obj2)])
@@ -0,0 +1,46 @@
1
+ """
2
+ Utils for signals.
3
+ """
4
+ from edx_ace.signals import ACE_MESSAGE_SENT
5
+
6
+
7
+ def make_serializable_object(obj):
8
+ """
9
+ Takes a dictionary/list and returns a dictionary/list with all the values converted
10
+ to JSON serializable objects.
11
+ """
12
+ try:
13
+ if isinstance(obj, (int, float, str, bool)) or obj is None:
14
+ return obj
15
+ elif isinstance(obj, dict):
16
+ return {key: make_serializable_object(value) for key, value in obj.items()}
17
+ elif isinstance(obj, list):
18
+ return [make_serializable_object(element) for element in obj]
19
+ except Exception: # pylint: disable=broad-except
20
+ pass
21
+ return str(obj)
22
+
23
+
24
+ def send_ace_message_sent_signal(channel, message):
25
+ """
26
+ Creates dictionary from message, makes it JSON serializable and
27
+ sends the ACE_MESSAGE_SENT signal.
28
+ """
29
+ try:
30
+ channel_name = channel.__class__.__name__
31
+ except AttributeError:
32
+ channel_name = 'Other'
33
+ data = {
34
+ 'name': message.name,
35
+ 'app_label': message.app_label,
36
+ 'recipient': {
37
+ 'email': getattr(message.recipient, 'email_address', ''),
38
+ 'user_id': getattr(message.recipient, 'lms_user_id', ''),
39
+ },
40
+ 'channel': channel_name,
41
+ 'context': message.context,
42
+ 'options': message.options,
43
+ 'uuid': str(message.uuid),
44
+ 'send_uuid': str(message.send_uuid),
45
+ }
46
+ ACE_MESSAGE_SENT.send(sender=channel, message=make_serializable_object(data))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-ace
3
- Version: 1.11.1
3
+ Version: 1.11.2
4
4
  Summary: Framework for Messaging
5
5
  Home-page: https://github.com/openedx/edx-ace
6
6
  Author: edX
@@ -49,9 +49,11 @@ edx_ace/tests/channel/test_push_notification.py
49
49
  edx_ace/tests/channel/test_sailthru.py
50
50
  edx_ace/tests/test_templates/testapp/edx_ace/testmessage/email/body.html
51
51
  edx_ace/tests/test_templates/testapp/edx_ace/testmessage/email/head.html
52
+ edx_ace/tests/utils/test_signals.py
52
53
  edx_ace/utils/__init__.py
53
54
  edx_ace/utils/date.py
54
55
  edx_ace/utils/once.py
55
56
  edx_ace/utils/plugins.py
57
+ edx_ace/utils/signals.py
56
58
  requirements/base.in
57
59
  requirements/constraints.txt
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes