Backport user creation and update API endpoints improvements.

This commit is contained in:
Roberto Rosario
2017-01-27 02:06:09 -04:00
parent c71a8f4e13
commit 059237e4b9
2 changed files with 148 additions and 20 deletions

View File

@@ -2,8 +2,10 @@ from __future__ import unicode_literals
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
class GroupSerializer(serializers.HyperlinkedModelSerializer):
@@ -21,10 +23,16 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
class UserSerializer(serializers.HyperlinkedModelSerializer):
groups = GroupSerializer(many=True)
groups = GroupSerializer(read_only=True, many=True)
groups_pk_list = serializers.CharField(
help_text=_(
'List of group primary keys to which to the user.'
), required=False
)
password = serializers.CharField(
required=False, style={'input_type': 'password'}
required=False, style={'input_type': 'password'}, write_only=True
)
class Meta:
@@ -32,30 +40,47 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
'url': {'view_name': 'rest_api:user-detail'}
}
fields = (
'first_name', 'date_joined', 'email', 'groups', 'id', 'is_active',
'last_login', 'last_name', 'url', 'username', 'password'
'first_name', 'date_joined', 'email', 'groups', 'groups_pk_list',
'id', 'is_active', 'last_login', 'last_name', 'password', 'url',
'username'
)
model = get_user_model()
read_only_fields = ('last_login', 'date_joined')
write_only_fields = ('password',)
read_only_fields = ('groups', 'is_active', 'last_login', 'date_joined')
write_only_fields = ('password', 'group_pk_list')
def create(self, validated_data):
validated_data.pop('groups')
validated_data.pop('is_active')
user = get_user_model().objects.create_user(**validated_data)
groups_pk_list = validated_data.pop('groups_pk_list', '')
password = validated_data.pop('password', None)
instance = super(UserSerializer, self).create(validated_data)
return user
if password:
instance.set_password(password)
instance.save()
if groups_pk_list:
try:
for group in Group.objects.filter(pk__in=groups_pk_list.split(',')):
instance.groups.add(group)
except Exception as exception:
raise ValidationError(exception)
return instance
def update(self, instance, validated_data):
validated_data.pop('groups')
if 'password' in validated_data:
instance.set_password(validated_data['password'])
validated_data.pop('password')
for attr, value in validated_data.items():
setattr(instance, attr, value)
result = super(UserSerializer, self).update(instance, validated_data)
instance.save()
groups_pk_list = validated_data.pop('groups_pk_list', '')
return instance
if groups_pk_list:
instance.groups.clear()
try:
for group in Group.objects.filter(pk__in=groups_pk_list.split(',')):
instance.groups.add(group)
except Exception as exception:
raise ValidationError(exception)
return result

View File

@@ -1,7 +1,7 @@
from __future__ import unicode_literals
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.core.urlresolvers import reverse
from rest_framework.test import APITestCase
@@ -47,6 +47,43 @@ class UserManagementAPITestCase(APITestCase):
user = get_user_model().objects.get(pk=response.data['id'])
self.assertEqual(user.username, TEST_USER_USERNAME)
def test_user_create_with_group(self):
group_1 = Group.objects.create(name='test group 1')
response = self.client.post(
reverse('rest_api:user-list'), data={
'email': TEST_USER_EMAIL, 'password': TEST_USER_PASSWORD,
'username': TEST_USER_USERNAME,
'groups_pk_list': '{}'.format(group_1.pk)
}
)
self.assertEqual(response.status_code, 201)
user = get_user_model().objects.get(pk=response.data['id'])
self.assertEqual(user.username, TEST_USER_USERNAME)
self.assertQuerysetEqual(user.groups.all(), (repr(group_1),))
def test_user_create_with_groups(self):
group_1 = Group.objects.create(name='test group 1')
group_2 = Group.objects.create(name='test group 2')
response = self.client.post(
reverse('rest_api:user-list'), data={
'email': TEST_USER_EMAIL, 'password': TEST_USER_PASSWORD,
'username': TEST_USER_USERNAME,
'groups_pk_list': '{},{}'.format(group_1.pk, group_2.pk)
}
)
self.assertEqual(response.status_code, 201)
user = get_user_model().objects.get(pk=response.data['id'])
self.assertEqual(user.username, TEST_USER_USERNAME)
self.assertQuerysetEqual(
user.groups.all().order_by('name'), (repr(group_1), repr(group_2))
)
def test_user_create_login(self):
response = self.client.post(
reverse('rest_api:user-list'), data={
@@ -57,7 +94,35 @@ class UserManagementAPITestCase(APITestCase):
self.assertEqual(response.status_code, 201)
get_user_model().objects.get(pk=response.data['id'])
self.assertTrue(
self.client.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
)
def test_user_create_login_password_change(self):
response = self.client.post(
reverse('rest_api:user-list'), data={
'email': TEST_USER_EMAIL, 'password': 'bad_password',
'username': TEST_USER_USERNAME,
}
)
self.assertEqual(response.status_code, 201)
self.assertFalse(
self.client.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
)
user = get_user_model().objects.get(pk=response.data['id'])
response = self.client.patch(
reverse('rest_api:user-detail', args=(user.pk,)), data={
'password': TEST_USER_PASSWORD,
}
)
self.assertTrue(
self.client.login(
@@ -81,7 +146,7 @@ class UserManagementAPITestCase(APITestCase):
user.refresh_from_db()
self.assertEqual(user.username, TEST_USER_USERNAME_EDITED)
def test_document_type_edit_via_patch(self):
def test_user_edit_via_patch(self):
user = get_user_model().objects.create_user(
email=TEST_USER_EMAIL, password=TEST_USER_PASSWORD,
username=TEST_USER_USERNAME
@@ -97,7 +162,45 @@ class UserManagementAPITestCase(APITestCase):
user.refresh_from_db()
self.assertEqual(user.username, TEST_USER_USERNAME_EDITED)
def test_document_type_delete(self):
def test_user_edit_remove_groups_via_patch(self):
user = get_user_model().objects.create_user(
email=TEST_USER_EMAIL, password=TEST_USER_PASSWORD,
username=TEST_USER_USERNAME
)
group_1 = Group.objects.create(name='test group 1')
user.groups.add(group_1)
response = self.client.patch(
reverse('rest_api:user-detail', args=(user.pk,)),
)
self.assertEqual(response.status_code, 200)
user.refresh_from_db()
self.assertQuerysetEqual(
user.groups.all().order_by('name'), (repr(group_1),)
)
def test_user_edit_add_groups_via_patch(self):
user = get_user_model().objects.create_user(
email=TEST_USER_EMAIL, password=TEST_USER_PASSWORD,
username=TEST_USER_USERNAME
)
group_1 = Group.objects.create(name='test group 1')
response = self.client.patch(
reverse('rest_api:user-detail', args=(user.pk,)),
data={'groups_pk_list': '{}'.format(group_1.pk)}
)
self.assertEqual(response.status_code, 200)
user.refresh_from_db()
self.assertQuerysetEqual(
user.groups.all().order_by('name'), (repr(group_1),)
)
def test_user_delete(self):
user = get_user_model().objects.create_user(
email=TEST_USER_EMAIL, password=TEST_USER_PASSWORD,
username=TEST_USER_USERNAME