Skip to content
Snippets Groups Projects
Commit bbd6f788 authored by Greg Price's avatar Greg Price
Browse files

Add endpoint to get user list for a preference

The endpoint includes the key of the desired preference in the URL and
returns the list of users for whom the preference is set (regardless of
the value).
parent 8f01756c
No related branches found
No related tags found
No related merge requests found
from django.contrib.auth.models import User
from django.core.validators import RegexValidator
from django.db import models
class UserPreference(models.Model):
"""A user's preference, stored as generic text to be processed by client"""
KEY_REGEX = r"[-_a-zA-Z0-9]+"
user = models.ForeignKey(User, db_index=True, related_name="preferences")
key = models.CharField(max_length=255, db_index=True)
key = models.CharField(max_length=255, db_index=True, validators=[RegexValidator(KEY_REGEX)])
value = models.TextField()
class Meta:
......
......@@ -66,7 +66,7 @@ class ApiTestCase(TestCase):
def assertUserIsValid(self, user):
"""Assert that the given user result is valid"""
self.assertItemsEqual(user.keys(), ["email", "id", "name", "username", "preferences", "url"])
self.assertItemsEqual(user.keys(), ["email", "id", "name", "username", "preferences", "url"])
self.assertItemsEqual(
user["preferences"].items(),
[(pref.key, pref.value) for pref in self.prefs if pref.user.id == user["id"]]
......@@ -373,3 +373,59 @@ class UserPreferenceViewSetTest(UserApiTestCase):
"url": uri,
}
)
class PreferenceUsersListViewTest(UserApiTestCase):
LIST_URI = "/user_api/v1/preferences/key0/users/"
def test_options(self):
self.assertAllowedMethods(self.LIST_URI, ["OPTIONS", "GET", "HEAD"])
def test_put_not_allowed(self):
self.assertHttpMethodNotAllowed(self.request_with_auth("put", self.LIST_URI))
def test_patch_not_allowed(self):
raise SkipTest("Django 1.4's test client does not support patch")
def test_delete_not_allowed(self):
self.assertHttpMethodNotAllowed(self.request_with_auth("delete", self.LIST_URI))
def test_unauthorized(self):
self.assertHttpForbidden(self.client.get(self.LIST_URI))
@override_settings(DEBUG=True)
@override_settings(EDX_API_KEY=None)
def test_debug_auth(self):
self.assertHttpOK(self.client.get(self.LIST_URI))
def test_get_basic(self):
result = self.get_json(self.LIST_URI)
self.assertEqual(result["count"], 2)
self.assertIsNone(result["next"])
self.assertIsNone(result["previous"])
users = result["results"]
self.assertEqual(len(users), 2)
for user in users:
self.assertUserIsValid(user)
def test_get_pagination(self):
first_page = self.get_json(self.LIST_URI, data={"page_size": 1})
self.assertEqual(first_page["count"], 2)
first_page_next_uri = first_page["next"]
self.assertIsNone(first_page["previous"])
first_page_users = first_page["results"]
self.assertEqual(len(first_page_users), 1)
second_page = self.get_json(first_page_next_uri)
self.assertEqual(second_page["count"], 2)
self.assertIsNone(second_page["next"])
second_page_prev_uri = second_page["previous"]
second_page_users = second_page["results"]
self.assertEqual(len(second_page_users), 1)
self.assertEqual(self.get_json(second_page_prev_uri), first_page)
for user in first_page_users + second_page_users:
self.assertUserIsValid(user)
all_user_uris = [user["url"] for user in first_page_users + second_page_users]
self.assertEqual(len(set(all_user_uris)), 2)
from django.conf.urls import include, patterns, url
from rest_framework import routers
from user_api import views as user_api_views
from user_api.models import UserPreference
user_api_router = routers.DefaultRouter()
......@@ -9,4 +10,8 @@ user_api_router.register(r'user_prefs', user_api_views.UserPreferenceViewSet)
urlpatterns = patterns(
'',
url(r'^v1/', include(user_api_router.urls)),
url(
r'^v1/preferences/(?P<pref_key>{})/users/$'.format(UserPreference.KEY_REGEX),
user_api_views.PreferenceUsersListView.as_view()
),
)
......@@ -2,6 +2,7 @@ from django.conf import settings
from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import filters
from rest_framework import generics
from rest_framework import permissions
from rest_framework import viewsets
from user_api.serializers import UserSerializer, UserPreferenceSerializer
......@@ -43,3 +44,14 @@ class UserPreferenceViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = UserPreferenceSerializer
paginate_by = 10
paginate_by_param = "page_size"
class PreferenceUsersListView(generics.ListAPIView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (ApiKeyHeaderPermission,)
serializer_class = UserSerializer
paginate_by = 10
paginate_by_param = "page_size"
def get_queryset(self):
return User.objects.filter(preferences__key=self.kwargs["pref_key"]).prefetch_related("preferences")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment