diff --git a/km_api/conftest.py b/km_api/conftest.py index c7d3c0b4..b5aaeac6 100644 --- a/km_api/conftest.py +++ b/km_api/conftest.py @@ -85,6 +85,14 @@ def api_rf(): return UserAPIRequestFactory(user=AnonymousUser()) +@pytest.fixture +def apns_device_factory(db): + """ + Fixture to get the factory used to create APNS devices. + """ + return factories.APNSDeviceFactory + + @pytest.fixture def email_factory(db): """ diff --git a/km_api/factories.py b/km_api/factories.py index 220799ab..bb91a117 100644 --- a/km_api/factories.py +++ b/km_api/factories.py @@ -10,6 +10,17 @@ import factory +class APNSDeviceFactory(factory.django.DjangoModelFactory): + """ + Factory for generating APNS devices. + """ + user = factory.SubFactory('factories.UserFactory') + registration_id = factory.Sequence(lambda n: str(n)) + + class Meta: + model = 'push_notifications.APNSDevice' + + class EmailFactory(factory.django.DjangoModelFactory): """ Factory for generating ``EmailAddress`` instances. diff --git a/km_api/km_api/settings.py b/km_api/km_api/settings.py index a25327fa..90c2169c 100644 --- a/km_api/km_api/settings.py +++ b/km_api/km_api/settings.py @@ -44,6 +44,7 @@ 'corsheaders', 'django_filters', 'dry_rest_permissions', + 'push_notifications', 'raven.contrib.django.raven_compat', 'rest_email_auth', 'rest_framework', @@ -59,6 +60,7 @@ 'know_me.journal', 'know_me.profile', 'mailing_list', + 'notifications', ] MIDDLEWARE = [ diff --git a/km_api/km_api/urls.py b/km_api/km_api/urls.py index f8219a21..7ec82972 100644 --- a/km_api/km_api/urls.py +++ b/km_api/km_api/urls.py @@ -27,4 +27,5 @@ url(r'^auth/', include('km_auth.urls')), url(r'^docs/', include_docs_urls(title='Know Me API')), url(r'^know-me/', include('know_me.urls')), + url(r'^notifications/', include('notifications.urls')), ] diff --git a/km_api/notifications/__init__.py b/km_api/notifications/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/km_api/notifications/tests/__init__.py b/km_api/notifications/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/km_api/notifications/tests/integration/__init__.py b/km_api/notifications/tests/integration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/km_api/notifications/tests/integration/test_apns_device_list_view.py b/km_api/notifications/tests/integration/test_apns_device_list_view.py new file mode 100644 index 00000000..d0860f95 --- /dev/null +++ b/km_api/notifications/tests/integration/test_apns_device_list_view.py @@ -0,0 +1,68 @@ +import pytest + +from push_notifications.api.rest_framework import APNSDeviceSerializer + +from rest_framework import status +from rest_framework.reverse import reverse + + +url = reverse('notifications:apns-device-list') + + +@pytest.mark.integration +def test_get_apns_device_list( + api_client, + api_rf, + apns_device_factory, + user_factory): + """ + Sending a GET request to the view should return a list of the user's + registered APNS devices. + """ + user = user_factory() + api_client.force_authenticate(user=user) + api_rf.user = user + + apns_device_factory(user=user) + apns_device_factory(user=user) + + request = api_rf.get(url) + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + + serializer = APNSDeviceSerializer( + user.apnsdevice_set.all(), + context={'request': request}, + many=True, + ) + + assert response.data == serializer.data + + +@pytest.mark.integration +def test_post_new_apns_device(api_client, api_rf, user_factory): + """ + Sending a POST request to the view should create a new APNS device + attached to the requesting user. + """ + user = user_factory() + api_client.force_authenticate(user=user) + api_rf.user = user + + data = { + # The registration ID must be 64 or 200 characters + 'registration_id': '1' * 64, + } + + request = api_rf.post(url, data) + response = api_client.post(url, data) + + assert response.status_code == status.HTTP_201_CREATED + + serializer = APNSDeviceSerializer( + user.apnsdevice_set.get(), + context={'request': request}, + ) + + assert response.data == serializer.data diff --git a/km_api/notifications/tests/views/__init__.py b/km_api/notifications/tests/views/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/km_api/notifications/urls.py b/km_api/notifications/urls.py new file mode 100644 index 00000000..1c28cfe7 --- /dev/null +++ b/km_api/notifications/urls.py @@ -0,0 +1,17 @@ +from django.conf.urls import include, url + +from push_notifications.api.rest_framework import APNSDeviceAuthorizedViewSet + +from rest_framework.routers import DefaultRouter + + +app_name = 'notifications' + + +router = DefaultRouter() +router.register('apns', APNSDeviceAuthorizedViewSet, 'apns-device') + + +urlpatterns = [ + url(r'^', include(router.urls)), +] diff --git a/requirements/base.txt b/requirements/base.txt index 653f9b5b..93e22146 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -6,6 +6,7 @@ boto3 == 1.6.8 coreapi == 2.3.3 django-cors-headers == 2.2.0 django-filter == 1.1.0 +django-push-notifications == 1.6.0 django-rest-email-auth == 1.0.0 django-ses == 0.8.5 django-solo == 1.1.3