def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ mapping = { NotificationMessageTypes.FILE_UPLOADED: 'GroupProjectFileUploadedRenderer', NotificationMessageTypes.STAGE_OPEN: 'GroupProjectStageOpenRenderer', NotificationMessageTypes.STAGE_DUE: 'GroupProjectStageDueRenderer', NotificationMessageTypes.GRADES_POSTED: 'GroupProjectGradesPostedRenderer', } for message_type, renderer in mapping.iteritems(): register_notification_type( NotificationType( name=u"{prefix}.{type}".format(prefix=GROUP_PROJECT_V1_NOTIFICATION_PREFIX, type=message_type), renderer="{prefix}.{renderer}".format(prefix=GROUP_PROJECT_RENDERER_PREFIX, renderer=renderer), ) ) # GP v2 can reuse GP v1 renderers register_notification_type( NotificationType( name=u"{prefix}.{type}".format(prefix=GROUP_PROJECT_V2_NOTIFICATION_PREFIX, type=message_type), renderer="{prefix}.{renderer}".format(prefix=GROUP_PROJECT_RENDERER_PREFIX, renderer=renderer), ) )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ mapping = { NotificationMessageTypes.FILE_UPLOADED: 'GroupProjectFileUploadedRenderer', NotificationMessageTypes.STAGE_OPEN: 'GroupProjectStageOpenRenderer', NotificationMessageTypes.STAGE_DUE: 'GroupProjectStageDueRenderer', NotificationMessageTypes.GRADES_POSTED: 'GroupProjectGradesPostedRenderer', } for message_type, renderer in six.iteritems(mapping): register_notification_type( NotificationType( name=u"{prefix}.{type}".format(prefix=GROUP_PROJECT_V1_NOTIFICATION_PREFIX, type=message_type), renderer="{prefix}.{renderer}".format(prefix=GROUP_PROJECT_RENDERER_PREFIX, renderer=renderer), ) ) # GP v2 can reuse GP v1 renderers register_notification_type( NotificationType( name=u"{prefix}.{type}".format(prefix=GROUP_PROJECT_V2_NOTIFICATION_PREFIX, type=message_type), renderer="{prefix}.{renderer}".format(prefix=GROUP_PROJECT_RENDERER_PREFIX, renderer=renderer), ) )
def test_json_renderer(self): """ Make sure JSON renderer returns correct renderings """ msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.JsonRenderer', ) register_notification_type(msg_type) msg = NotificationMessage(namespace='test-runner', msg_type=msg_type, payload={ 'subject': 'test subject', 'body': 'test body', }) renderer = JsonRenderer() self.assertTrue(renderer.can_render_format(RENDER_FORMAT_JSON)) self.assertIsNone(renderer.get_template_path(RENDER_FORMAT_JSON)) self.assertEqual( json.loads(renderer.render(msg, RENDER_FORMAT_JSON, None)), msg.payload)
def test_json_renderer(self): """ Make sure JSON renderer returns correct renderings """ msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.JsonRenderer', ) register_notification_type(msg_type) msg = NotificationMessage( namespace='test-runner', msg_type=msg_type, payload={ 'subject': 'test subject', 'body': 'test body', } ) renderer = JsonRenderer() self.assertTrue(renderer.can_render_format(RENDER_FORMAT_JSON)) self.assertIsNone(renderer.get_template_path(RENDER_FORMAT_JSON)) self.assertEqual(json.loads(renderer.render(msg, RENDER_FORMAT_JSON, None)), msg.payload)
def test_multiple_types(self): """ Make sure the same type can be registered more than once """ # msg_type.name is a primary key, so verify this does # not throw an exception register_notification_type(self.msg_type)
def test_multiple_types(self): """ Make sure the same type can be registered more than once """ # msg_type.name is a primary key, so verify this does # not throw an exception register_notification_type(self.msg_type)
def setUp(self): """ Build out test harnessing """ self.msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) register_notification_type(self.msg_type) super(ConsumerAPITests, self).setUp()
def setUp(self): """ Build out test harnessing """ self.msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) register_notification_type(self.msg_type) super(ConsumerAPITests, self).setUp()
def setUp(self): """ Initialize some data """ clear_renderers() self.test_user_id = 1001 # some bogus user identifier self.msg_type = NotificationType( name="open-edx.edx_notifications.lib.tests.test_publisher", renderer="edx_notifications.renderers.basic.BasicSubjectBodyRenderer", ) register_notification_type(self.msg_type)
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ register_notification_type( NotificationType( name='open-edx.mobileapps.notifications', renderer= 'edx_notifications.renderers.basic.JsonRenderer' # using this for tests to pass. ))
def setUp(self): """ Initialize some data """ clear_renderers() self.test_user_id = 1001 # some bogus user identifier self.msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) register_notification_type(self.msg_type)
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ # updates/announcements in the course use-case. register_notification_type( NotificationType( name='open-edx.studio.announcements.new-announcement', renderer='edx_notifications.openedx.course_announcements.NewCourseAnnouncementRenderer', ) )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ register_notification_type( NotificationType( name=u'open-edx.xblock.group-project.file-uploaded', renderer='edx_notifications.openedx.group_project.GroupProjectFileUploadedRenderer', ) ) register_notification_type( NotificationType( name=u'open-edx.xblock.group-project.stage-open', renderer='edx_notifications.openedx.group_project.GroupProjectStageOpenRenderer', ) ) register_notification_type( NotificationType( name=u'open-edx.xblock.group-project.stage-due', renderer='edx_notifications.openedx.group_project.GroupProjectStageDueRenderer', ) ) register_notification_type( NotificationType( name=u'open-edx.xblock.group-project.grades-posted', renderer='edx_notifications.openedx.group_project.GroupProjectGradesPostedRenderer', ) )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ # updates/announcements in the course use-case. register_notification_type( NotificationType( name='open-edx.studio.announcements.new-announcement', renderer= 'edx_notifications.openedx.course_announcements.NewCourseAnnouncementRenderer', ))
def setUp(self): """ Sets up test environments """ startup.initialize() self.msg_type = NotificationType( name='open-edx.studio.announcements.new-announcement', renderer='edx_notifications.openedx.course_announcements.NewCourseAnnouncementRenderer' ) register_notification_type(self.msg_type) self.msg = NotificationMessage( namespace='foo/bar/baz', msg_type=self.msg_type, payload=CANNED_TEST_PAYLOAD['open-edx.studio.announcements.new-announcement'] )
def test_underscore(self): """ Tests on the UnderscoreStaticFileRenderer """ renderer = TestUnderscoreStaticFileRenderer( 'basic_subject_body.underscore') self.assertTrue(renderer.can_render_format(RENDER_FORMAT_HTML)) msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer= 'edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) register_notification_type(msg_type) self.assertIsNotNone(get_renderer_for_type(msg_type)) msg = NotificationMessage(namespace='test-runner', msg_type=msg_type, payload={ 'subject': 'test subject', 'body': 'test body', }, created=datetime.datetime.now(pytz.UTC)) renderer.get_template_path(RENDER_FORMAT_HTML) with self.assertRaises(NotImplementedError): renderer.get_template_path(RENDER_FORMAT_SMS) with self.assertRaises(NotImplementedError): renderer.render(msg, RENDER_FORMAT_SMS, None) html = renderer.render(msg, RENDER_FORMAT_HTML, None) with self.assertRaises(NotImplementedError): renderer.get_template_path(RENDER_FORMAT_SMS) self.assertIn('test subject', html) self.assertIn('test body', html) self.assertIn("<div class='xns-title'>", html) self.assertIn("<div class='xns-body'>", html) with self.assertRaises(Exception): bad_renderer = TestUnderscoreStaticFileRenderer('foo.underscore') bad_renderer.render(msg, RENDER_FORMAT_HTML, None)
def test_underscore(self): """ Tests on the UnderscoreStaticFileRenderer """ renderer = TestUnderscoreStaticFileRenderer('basic_subject_body.underscore') self.assertTrue(renderer.can_render_format(RENDER_FORMAT_HTML)) msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) register_notification_type(msg_type) self.assertIsNotNone(get_renderer_for_type(msg_type)) msg = NotificationMessage( namespace='test-runner', msg_type=msg_type, payload={ 'subject': 'test subject', 'body': 'test body', }, created=datetime.datetime.now(pytz.UTC) ) renderer.get_template_path(RENDER_FORMAT_HTML) with self.assertRaises(NotImplementedError): renderer.get_template_path(RENDER_FORMAT_SMS) with self.assertRaises(NotImplementedError): renderer.render(msg, RENDER_FORMAT_SMS, None) html = renderer.render(msg, RENDER_FORMAT_HTML, None) with self.assertRaises(NotImplementedError): renderer.get_template_path(RENDER_FORMAT_SMS) self.assertIn('test subject', html) self.assertIn('test body', html) self.assertIn("<div class='xns-title'>", html) self.assertIn("<div class='xns-body'>", html) with self.assertRaises(Exception): bad_renderer = TestUnderscoreStaticFileRenderer('foo.underscore') bad_renderer.render(msg, RENDER_FORMAT_HTML, None)
def setUp(self): """ Test setup """ startup.initialize(register_system_types=False) self.msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.JsonRenderer', ) register_notification_type(self.msg_type) self.msg = NotificationMessage(namespace='test-runner', msg_type=self.msg_type, payload={ 'foo': 'bar', 'one': 'two' })
def perform_type_registrations_handler(sender, **kwargs): # pylint: disable=unused-argument """ Register test notification types """ logger.info('Registering NotificationTypes...') register_notification_type( NotificationType( name='testserver.type1', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) ) register_notification_type( NotificationType( name='testserver.msg-with-resolved-click-link', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) )
def perform_type_registrations_handler(sender, **kwargs): # pylint: disable=unused-argument """ Register test notification types """ logger.info('Registering NotificationTypes...') register_notification_type( NotificationType( name='testserver.type1', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) ) register_notification_type( NotificationType( name='testserver.msg-with-resolved-click-link', renderer='edx_notifications.renderers.basic.BasicSubjectBodyRenderer', ) )
def setUp(self): """ Test setup """ startup.initialize(register_system_types=False) self.msg_type = NotificationType( name='open-edx.edx_notifications.lib.tests.test_publisher', renderer='edx_notifications.renderers.basic.JsonRenderer', ) register_notification_type(self.msg_type) self.msg = NotificationMessage( namespace='test-runner', msg_type=self.msg_type, payload={ 'foo': 'bar', 'one': 'two' } )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.progress.rank-changed', renderer= 'edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', )) register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.gradebook.rank-changed', renderer= 'edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', )) register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.engagement.rank-changed', renderer= 'edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', ))
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.progress.rank-changed', renderer='edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', ) ) register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.gradebook.rank-changed', renderer='edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', ) ) register_notification_type( NotificationType( name=u'open-edx.lms.leaderboard.engagement.rank-changed', renderer='edx_notifications.openedx.leaderboard.LeaderboardRankChangedRenderer', ) )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ # someone replying to thread use-case register_notification_type( NotificationType( name='open-edx.lms.discussions.reply-to-thread', renderer='edx_notifications.openedx.forums.ReplyToThreadRenderer', )) # someone following the thread use-case register_notification_type( NotificationType( name='open-edx.lms.discussions.thread-followed', renderer='edx_notifications.openedx.forums.ThreadFollowedRenderer', )) # new posting in a cohorted/private discussion in the course use-case. register_notification_type( NotificationType( name='open-edx.lms.discussions.cohorted-thread-added', renderer= 'edx_notifications.openedx.forums.CohortedThreadAddedRenderer', )) # new posting in a cohorted/private discussion in the course use-case. register_notification_type( NotificationType( name='open-edx.lms.discussions.cohorted-comment-added', renderer= 'edx_notifications.openedx.forums.CohortedCommentAddedRenderer', )) # someone voting the thread use-case register_notification_type( NotificationType( name='open-edx.lms.discussions.post-upvoted', renderer='edx_notifications.openedx.forums.PostUpvotedRenderer', )) # someone voting the comment use-case register_notification_type( NotificationType( name='open-edx.lms.discussions.comment-upvoted', renderer='edx_notifications.openedx.forums.CommentUpvotedRenderer', )) # someone flagging a post use-case register_notification_type( NotificationType( name='open-edx.lms.discussions.post-flagged', renderer='edx_notifications.openedx.forums.PostFlaggedRenderer', ))
def publish_notification(cls, namespace, msg_type_name, payload, parse_channel_ids, send_at=None, timer_name=None): """ Helper class method to hide some of the inner workings of this channel This will work with immediate or timer based publishing. 'namespace' is an instance of NotificationMessage 'msg_type' is the type name of the NotificationMessage 'payload' is the raw data dictionary to send over the mobile clients 'parse_channel_ids' is a list of Parse channel_ids, which are subscription lists, not to be confused with edx-notification's NotificationChannels - an unfortunate semantic collision. 'send_at' is a datetime when this notification should be sent. Note that firing of notifications is approximate, so it will not fire BEFORE send_at, but there might be a lag, depending on how frequent timer polling is configured in a runtime instance. 'timer_name' can be used in conjunction with 'send_at'. This is to allow for a fixed timer identifier in case the timed notification needs to be updated (or deleted) """ try: msg_type = get_notification_type(msg_type_name) except ItemNotFoundError: msg_type = NotificationType( name=msg_type_name, renderer='edx_notifications.renderers.basic.JsonRenderer') register_notification_type(msg_type) msg = NotificationMessage(namespace=namespace, msg_type=msg_type, payload=payload) if not send_at: # send immediately publish_notification_to_user( user_id=_PARSE_SERVICE_USER_ID, msg=msg, # we want to make sure we always call this channel provider preferred_channel=_PARSE_CHANNEL_NAME, channel_context={ # tunnel through the parse_channel_id through the # channel context 'parse_channel_ids': parse_channel_ids, }) else: # time-based sending, use a TimedNotification publish_timed_notification( msg=msg, send_at=send_at, scope_name='user', scope_context={'user_id': _PARSE_SERVICE_USER_ID}, timer_name=timer_name, timer_context={ # we want to make sure we always call this channel provider 'preferred_channel': _PARSE_CHANNEL_NAME, 'channel_context': { # tunnel through the parse_channel_id through # through the channel context 'parse_channel_ids': parse_channel_ids, } })
def publish_notification(cls, namespace, msg_type_name, payload, parse_channel_ids, send_at=None, timer_name=None): """ Helper class method to hide some of the inner workings of this channel This will work with immediate or timer based publishing. 'namespace' is an instance of NotificationMessage 'msg_type' is the type name of the NotificationMessage 'payload' is the raw data dictionary to send over the mobile clients 'parse_channel_ids' is a list of Parse channel_ids, which are subscription lists, not to be confused with edx-notification's NotificationChannels - an unfortunate semantic collision. 'send_at' is a datetime when this notification should be sent. Note that firing of notifications is approximate, so it will not fire BEFORE send_at, but there might be a lag, depending on how frequent timer polling is configured in a runtime instance. 'timer_name' can be used in conjunction with 'send_at'. This is to allow for a fixed timer identifier in case the timed notification needs to be updated (or deleted) """ try: msg_type = get_notification_type(msg_type_name) except ItemNotFoundError: msg_type = NotificationType( name=msg_type_name, renderer='edx_notifications.renderers.basic.JsonRenderer' ) register_notification_type(msg_type) msg = NotificationMessage( namespace=namespace, msg_type=msg_type, payload=payload ) if not send_at: # send immediately publish_notification_to_user( user_id=_PARSE_SERVICE_USER_ID, msg=msg, # we want to make sure we always call this channel provider preferred_channel=_PARSE_CHANNEL_NAME, channel_context={ # tunnel through the parse_channel_id through the # channel context 'parse_channel_ids': parse_channel_ids, } ) else: # time-based sending, use a TimedNotification publish_timed_notification( msg=msg, send_at=send_at, scope_name='user', scope_context={ 'user_id': _PARSE_SERVICE_USER_ID }, timer_name=timer_name, timer_context={ # we want to make sure we always call this channel provider 'preferred_channel': _PARSE_CHANNEL_NAME, 'channel_context': { # tunnel through the parse_channel_id through # through the channel context 'parse_channel_ids': parse_channel_ids, } } )
def register_notification_types(sender, **kwargs): # pylint: disable=unused-argument """ Register some standard NotificationTypes. This will be called automatically on the Notification subsystem startup (because we are receiving the 'perform_type_registrations' signal) """ # someone replying to thread use-case register_notification_type( NotificationType( name="open-edx.lms.discussions.reply-to-thread", renderer="edx_notifications.openedx.forums.ReplyToThreadRenderer", ) ) # someone following the thread use-case register_notification_type( NotificationType( name="open-edx.lms.discussions.thread-followed", renderer="edx_notifications.openedx.forums.ThreadFollowedRenderer", ) ) # new posting in a cohorted/private discussion in the course use-case. register_notification_type( NotificationType( name="open-edx.lms.discussions.cohorted-thread-added", renderer="edx_notifications.openedx.forums.CohortedThreadAddedRenderer", ) ) # new posting in a cohorted/private discussion in the course use-case. register_notification_type( NotificationType( name="open-edx.lms.discussions.cohorted-comment-added", renderer="edx_notifications.openedx.forums.CohortedCommentAddedRenderer", ) ) # someone voting the thread use-case register_notification_type( NotificationType( name="open-edx.lms.discussions.post-upvoted", renderer="edx_notifications.openedx.forums.PostUpvotedRenderer", ) ) # someone voting the comment use-case register_notification_type( NotificationType( name="open-edx.lms.discussions.comment-upvoted", renderer="edx_notifications.openedx.forums.CommentUpvotedRenderer", ) ) # someone flagging a post use-case register_notification_type( NotificationType( name="open-edx.lms.discussions.post-flagged", renderer="edx_notifications.openedx.forums.PostFlaggedRenderer", ) )