From b87c3d0cc67444778bcf4129ba665d63ebf8043e Mon Sep 17 00:00:00 2001 From: SKairinos Date: Wed, 18 Sep 2024 10:56:29 +0000 Subject: [PATCH 1/2] include user type when resetting students' password --- src/api/views/student.py | 7 +++++++ src/api/views/student_test.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/src/api/views/student.py b/src/api/views/student.py index f3c1d28d..533ab23a 100644 --- a/src/api/views/student.py +++ b/src/api/views/student.py @@ -29,6 +29,13 @@ def get_permissions(self): def get_queryset(self): return self.request.school_teacher_user.teacher.students + def get_serializer_context(self): + serializer_context = super().get_serializer_context() + if self.action == "reset_password": + serializer_context["user_type"] = "student" + + return serializer_context + def get_serializer_class(self): if self.action == "release": return ReleaseStudentSerializer diff --git a/src/api/views/student_test.py b/src/api/views/student_test.py index fe52f4e1..6093b9c6 100644 --- a/src/api/views/student_test.py +++ b/src/api/views/student_test.py @@ -218,6 +218,15 @@ def test_get_queryset__reset_password__non_admin(self): request_method="put", ) + # test: get serializer context + + def test_get_serializer_context__reset_password(self): + """Serializer context sets user type as student.""" + self.assert_get_serializer_context( + serializer_context={"user_type": "student"}, + action="reset_password", + ) + # test: get serializer class def test_get_serializer_class__release(self): From 29caa6ca67a0267c004be2b384580aa9f11dd66d Mon Sep 17 00:00:00 2001 From: SKairinos Date: Thu, 19 Sep 2024 13:02:01 +0000 Subject: [PATCH 2/2] student name in class --- src/api/serializers/user.py | 14 ++++++++++++++ src/api/serializers/user_test.py | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/api/serializers/user.py b/src/api/serializers/user.py index 90612e97..15f3d48d 100644 --- a/src/api/serializers/user.py +++ b/src/api/serializers/user.py @@ -50,6 +50,20 @@ class BaseUserSerializer(_BaseUserSerializer[AnyUser], t.Generic[AnyUser]): + def validate_first_name(self, value: str): + user = self.instance + if user and user.student and user.student.class_field: + if User.objects.filter( + first_name=value, + new_student__class_field=user.student.class_field, + ).exists(): + raise serializers.ValidationError( + "A student in this class already has this name.", + code="student_name_in_class", + ) + + return value + # TODO: make email unique in new models and remove this validation. def validate_email(self, value: str): user = User.objects.filter(email__iexact=value).first() diff --git a/src/api/serializers/user_test.py b/src/api/serializers/user_test.py index e500d963..078f72e9 100644 --- a/src/api/serializers/user_test.py +++ b/src/api/serializers/user_test.py @@ -16,6 +16,7 @@ User, ) from django.contrib.auth.hashers import make_password +from django.db.models import Count from ..auth import password_reset_token_generator from .user import ( @@ -36,6 +37,27 @@ class TestBaseUserSerializer(ModelSerializerTestCase[User, User]): model_serializer_class = BaseUserSerializer[User] # fixtures = ["school_1"] + def test_validate_first_name__student_name_in_class(self): + """ + Cannot assign a student-user a name that already exists in their class. + """ + klass = ( + Class.objects.annotate(student_count=Count("students")) + .filter(student_count__gte=2) + .first() + ) + assert klass + students = klass.students.all() + student_user_1 = StudentUser.objects.get(new_student=students[0]) + student_user_2 = StudentUser.objects.get(new_student=students[1]) + + self.assert_validate_field( + name="first_name", + value=student_user_2.first_name, + error_code="student_name_in_class", + instance=student_user_1, + ) + def test_validate_email__already_exists(self): """Cannot assign a user an email that already exists.""" user_fields = User.objects.values("email").first()