diff --git a/apps/users/serializers.py b/apps/users/serializers.py index d6e2ae7..edc1338 100644 --- a/apps/users/serializers.py +++ b/apps/users/serializers.py @@ -1,9 +1,9 @@ -from rest_framework import serializers +from rest_framework.serializers import ModelSerializer from apps.users.models import User -class UserSerializer(serializers.ModelSerializer): +class UserSerializer(ModelSerializer): class Meta: model = User - fields = ['id', 'uuid', 'email_address', 'first_name', 'last_name', 'bio', 'timezone', 'avatar_url', 'is_manager', 'date_of_birth', 'created_at', 'updated_at'] - read_only_fields = ['id', 'uuid', 'created_at', 'updated_at'] \ No newline at end of file + fields = ['id', 'uuid', 'email_address', 'first_name', 'last_name', 'bio', 'timezone', 'avatar_url', 'is_manager', 'date_of_birth', 'created_at', 'updated_at', 'is_staff'] + read_only_fields = ['id', 'uuid', 'created_at', 'updated_at', 'is_staff'] \ No newline at end of file diff --git a/apps/users/tests/test_api_auth.py b/apps/users/tests/test_api_auth.py index 73a6972..950b26a 100644 --- a/apps/users/tests/test_api_auth.py +++ b/apps/users/tests/test_api_auth.py @@ -212,7 +212,8 @@ class UserSignupActionTests(TestCase): 'confirm_password': 'newpass123', 'first_name': 'New', 'last_name': 'User', - 'date_of_birth': '1995-05-05' + 'date_of_birth': '1995-05-05', + 'manager': False }) self.assertEqual(response.status_code, HTTP_201_CREATED) data = response.json() @@ -232,7 +233,8 @@ class UserSignupActionTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) data = response.json() @@ -244,7 +246,8 @@ class UserSignupActionTests(TestCase): 'email_address': 'newuser2@example.com', 'password': 'newpass123', 'confirm_password': 'newpass123', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) data = response.json() @@ -255,7 +258,20 @@ class UserSignupActionTests(TestCase): 'email_address': 'newuser3@example.com', 'password': 'newpass123', 'confirm_password': 'newpass123', - 'first_name': 'New' + 'first_name': 'New', + 'manager': True + }) + self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) + data = response.json() + self.assertFalse(data['success']) + + def test_signup_missing_manager(self): + response = self.client.post('/api/user/signup/', { + 'email_address': 'missingmanager@example.com', + 'password': 'newpass123', + 'confirm_password': 'newpass123', + 'first_name': 'Missing', + 'last_name': 'Manager' }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) data = response.json() @@ -267,7 +283,8 @@ class UserSignupActionTests(TestCase): 'password': 'newpass123', 'confirm_password': 'differentpass', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager' : True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) data = response.json() @@ -278,7 +295,8 @@ class UserSignupActionTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) @@ -287,7 +305,8 @@ class UserSignupActionTests(TestCase): 'email_address': 'newuser@example.com', 'confirm_password': 'newpass123', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) @@ -301,7 +320,8 @@ class UserSignupActionTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_201_CREATED) user = User.objects.get(email_address='NewUser@example.com') @@ -318,7 +338,8 @@ class UserSignupActionTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'New', - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) @@ -465,7 +486,8 @@ class UserEdgeCaseTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': long_name, - 'last_name': long_name + 'last_name': long_name, + 'manager': True }) self.assertEqual(response.status_code, HTTP_201_CREATED) @@ -476,7 +498,8 @@ class UserEdgeCaseTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': too_long_name, - 'last_name': 'User' + 'last_name': 'User', + 'manager': True }) self.assertIn(response.status_code, [HTTP_400_BAD_REQUEST, HTTP_201_CREATED]) @@ -486,7 +509,8 @@ class UserEdgeCaseTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'José', - 'last_name': "O'Brien-Smith" + 'last_name': "O'Brien-Smith", + 'manager': True }) self.assertEqual(response.status_code, HTTP_201_CREATED) @@ -507,7 +531,8 @@ class UserEdgeCaseTests(TestCase): 'email_address': 'missingconfirm@example.com', 'password': 'newpass123', 'first_name': 'Missing', - 'last_name': 'Confirm' + 'last_name': 'Confirm', + 'manager': True }) self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST) @@ -562,7 +587,8 @@ class UserEdgeCaseTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'Optional', - 'last_name': 'Fields' + 'last_name': 'Fields', + 'manager': True }) self.assertEqual(response.status_code, HTTP_201_CREATED) @@ -608,7 +634,8 @@ class UserEdgeCaseTests(TestCase): 'password': 'newpass123', 'confirm_password': 'newpass123', 'first_name': 'Invalid', - 'last_name': 'Email' + 'last_name': 'Email', + 'manager': True }) self.assertIn(response.status_code, [HTTP_400_BAD_REQUEST, HTTP_201_CREATED]) @@ -618,7 +645,8 @@ class UserEdgeCaseTests(TestCase): 'password': '', 'confirm_password': '', 'first_name': 'Empty', - 'last_name': 'Pass' + 'last_name': 'Pass', + 'manager': True }) self.assertIn(response.status_code, [HTTP_400_BAD_REQUEST, HTTP_201_CREATED]) diff --git a/apps/users/viewsets.py b/apps/users/viewsets.py index 392a2fd..d446a40 100644 --- a/apps/users/viewsets.py +++ b/apps/users/viewsets.py @@ -58,6 +58,9 @@ class UserViewSet(ReadOnlyModelViewSet): if not data.get('first_name') or not data.get('last_name'): return Response({'detail': 'First and last name(s) must be provided.', 'success': False}, status=HTTP_400_BAD_REQUEST) + + if not data.get('manager') or data.get('manager').lower() != 'true' and data.get('manager').lower() != 'false': + return Response({'detail': '"manager" field must be true or false.', 'success': False}, status=HTTP_400_BAD_REQUEST) if data.get('password') != data.get('confirm_password'): return Response({'detail': 'Passwords do not match.', 'success': False}, status=HTTP_400_BAD_REQUEST) @@ -67,7 +70,8 @@ class UserViewSet(ReadOnlyModelViewSet): password=data.get('password'), first_name=data.get('first_name'), last_name=data.get('last_name'), - date_of_birth=data.get('date_of_birth') + date_of_birth=data.get('date_of_birth'), + is_manager=data.get('manager').lower() == 'true' ) return Response({'detail': 'User account created successfully.', 'success': True}, status=HTTP_201_CREATED) except Exception as e: