diff --git a/cms/djangoapps/contentstore/push_notification.py b/cms/djangoapps/contentstore/push_notification.py index d6e8f65737..ec99d61713 100644 --- a/cms/djangoapps/contentstore/push_notification.py +++ b/cms/djangoapps/contentstore/push_notification.py @@ -2,6 +2,7 @@ Helper methods for push notifications from Studio. """ +from uuid import uuid4 from django.conf import settings from logging import exception as log_exception @@ -46,17 +47,36 @@ def send_push_course_update(course_key_string, course_subscription_id, course_di settings.PARSE_KEYS["APPLICATION_ID"], settings.PARSE_KEYS["REST_API_KEY"], ) + push_payload = { + "action": "course.announcement", + "notification-id": unicode(uuid4()), + + "course-id": course_key_string, + "course-name": course_display_name, + } + push_channels = [course_subscription_id] + + # Push to all Android devices Push.alert( - data={ - "course-id": course_key_string, - "action": "course.announcement", - "action-loc-key": "VIEW_BUTTON", - "loc-key": "COURSE_ANNOUNCEMENT_NOTIFICATION_BODY", - "loc-args": [course_display_name], - "title-loc-key": "COURSE_ANNOUNCEMENT_NOTIFICATION_TITLE", - "title-loc-args": [], - }, - channels=[course_subscription_id], + data=push_payload, + channels={"$in": push_channels}, + where={"deviceType": "android"}, ) + + # Push to all iOS devices + # With additional payload so that + # 1. The push is displayed automatically + # 2. The app gets it even in the background. + # See http://stackoverflow.com/questions/19239737/silent-push-notification-in-ios-7-does-not-work + push_payload.update({ + "alert": "", + "content-available": 1 + }) + Push.alert( + data=push_payload, + channels={"$in": push_channels}, + where={"deviceType": "ios"}, + ) + except ParseError as error: log_exception(error.message) diff --git a/cms/djangoapps/contentstore/views/tests/test_course_updates.py b/cms/djangoapps/contentstore/views/tests/test_course_updates.py index cb6a725a6c..94f92fe637 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_updates.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_updates.py @@ -303,4 +303,14 @@ class CourseUpdateTest(CourseTestCase): def test_notifications_sent_to_parse(self, mock_parse_push): PushNotificationConfig(enabled=True).save() self.post_course_update(send_push_notification=True) - self.assertTrue(mock_parse_push.alert.called) + self.assertEquals(mock_parse_push.alert.call_count, 2) + + @override_settings(PARSE_KEYS={"APPLICATION_ID": "TEST_APPLICATION_ID", "REST_API_KEY": "TEST_REST_API_KEY"}) + @patch("contentstore.push_notification.log_exception") + @patch("contentstore.push_notification.Push") + def test_notifications_error_from_parse(self, mock_parse_push, mock_log_exception): + PushNotificationConfig(enabled=True).save() + from parse_rest.core import ParseError + mock_parse_push.alert.side_effect = ParseError + self.post_course_update(send_push_notification=True) + self.assertTrue(mock_log_exception.called)