Skip to content

Commit

Permalink
support indy students
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Oct 21, 2023
1 parent b90df7a commit 19a2aa3
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 38 deletions.
21 changes: 13 additions & 8 deletions codeforlife/tests/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from django.db.models import Model
from rest_framework.test import APITestCase as _APITestCase
from rest_framework.test import APIClient as _APIClient
from rest_framework.serializers import BaseSerializer
from rest_framework.serializers import ModelSerializer
from rest_framework.response import Response

from ..user.models import User, AuthFactor


AnySerializer = t.TypeVar("AnySerializer", bound=BaseSerializer)
AnyModelSerializer = t.TypeVar("AnyModelSerializer", bound=ModelSerializer)
AnyModel = t.TypeVar("AnyModel", bound=Model)


Expand Down Expand Up @@ -78,17 +78,17 @@ def login(self, **credentials):
def assert_data_equals_model(
data: t.Dict[str, t.Any],
model: AnyModel,
serializer_class: t.Type[AnySerializer],
model_serializer_class: t.Type[AnyModelSerializer],
):
assert (
data == serializer_class(model).data
data == model_serializer_class(model).data
), "Data does not equal serialized model."

def retrieve(
self,
basename: str,
model: AnyModel,
serializer_class: t.Type[AnySerializer],
model_serializer_class: t.Type[AnyModelSerializer],
status_code_assertion: StatusCodeAssertion = None,
**kwargs,
):
Expand All @@ -102,7 +102,7 @@ def retrieve(
self.assert_data_equals_model(
response.json(),
model,
serializer_class,
model_serializer_class,
)

return response
Expand All @@ -111,10 +111,15 @@ def list(
self,
basename: str,
models: t.Iterable[AnyModel],
serializer_class: t.Type[AnySerializer],
model_serializer_class: t.Type[AnyModelSerializer],
status_code_assertion: StatusCodeAssertion = None,
**kwargs,
):
model_class: t.Type[AnyModel] = model_serializer_class.Meta.model
assert model_class.objects.difference(
model_class.objects.filter(pk__in=[model.pk for model in models])
).exists(), "List must exclude some models for a valid test."

response: Response = self.get(
reverse(f"{basename}-list"),
status_code_assertion=status_code_assertion,
Expand All @@ -126,7 +131,7 @@ def list(
self.assert_data_equals_model(
data,
model,
serializer_class,
model_serializer_class,
)

return response
Expand Down
120 changes: 90 additions & 30 deletions codeforlife/user/tests/views/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TestUserViewSet(APITestCase):
Base naming convention:
test_{action}
action: This view set action.
action: The view set action.
https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions
"""

Expand Down Expand Up @@ -78,7 +78,27 @@ def _login_student(self):
assert user.student.class_field.teacher.school
return user

def _get_other_user(
def _login_indy_student(self):
user = self.client.login(
email="[email protected]", password="Password1"
)
assert user.student
assert not user.student.class_field
return user

def _get_other_school_user(
self,
user: User,
other_users: QuerySet[User],
is_teacher: bool,
):
other_user = other_users.first()
assert other_user
assert user != other_user
assert other_user.teacher if is_teacher else other_user.student
return other_user

def _get_another_school_user(
self,
user: User,
other_users: QuerySet[User],
Expand All @@ -90,24 +110,14 @@ def _get_other_user(
if user.teacher
else user.student.class_field.teacher.school
)

other_user = other_users.first()
assert other_user
assert user != other_user

if is_teacher:
assert other_user.teacher
other_school = other_user.teacher.school
else:
assert other_user.student
other_school = other_user.student.class_field.teacher.school

other_user = self._get_other_school_user(user, other_users, is_teacher)
other_school = (
other_user.teacher.school
if is_teacher
else other_user.student.class_field.teacher.school
)
assert other_school
if same_school:
assert school == other_school
else:
assert school != other_school

assert school == other_school if same_school else school != other_school
return other_user

"""
Expand All @@ -116,7 +126,8 @@ def _get_other_user(
user_type: The type of user that is making the request. Options:
- teacher: A teacher.
- student: A student.
- student: A school student.
- indy_student: A non-school student.
other_user_type: The type of user whose data is being requested. Options:
- self: User's own data.
Expand Down Expand Up @@ -146,6 +157,7 @@ def test_retrieve__teacher__self(self):
"""

user = self._login_teacher()

self._retrieve_user(user)

def test_retrieve__student__self(self):
Expand All @@ -154,6 +166,16 @@ def test_retrieve__student__self(self):
"""

user = self._login_student()

self._retrieve_user(user)

def test_retrieve__indy_student__self(self):
"""
Independent student can retrieve their own user data.
"""

user = self._login_indy_student()

self._retrieve_user(user)

def test_retrieve__teacher__teacher__same_school(self):
Expand All @@ -163,7 +185,7 @@ def test_retrieve__teacher__teacher__same_school(self):

user = self._login_teacher()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(id=user.id).filter(
new_teacher__school=user.teacher.school
Expand All @@ -181,7 +203,7 @@ def test_retrieve__teacher__student__same_school(self):

user = self._login_teacher()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.filter(
new_student__class_field__teacher__school=user.teacher.school
Expand All @@ -199,7 +221,7 @@ def test_retrieve__student__teacher__same_school(self):

user = self._login_student()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.filter(
new_teacher__school=user.student.class_field.teacher.school
Expand All @@ -220,7 +242,7 @@ def test_retrieve__student__student__same_school(self):

user = self._login_student()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(id=user.id).filter(
new_student__class_field__teacher__school=user.student.class_field.teacher.school
Expand All @@ -241,7 +263,7 @@ def test_retrieve__teacher__teacher__not_same_school(self):

user = self._login_teacher()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(
new_teacher__school=user.teacher.school
Expand All @@ -262,7 +284,7 @@ def test_retrieve__teacher__student__not_same_school(self):

user = self._login_teacher()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(
new_student__class_field__teacher__school=user.teacher.school
Expand All @@ -283,7 +305,7 @@ def test_retrieve__student__teacher__not_same_school(self):

user = self._login_student()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(
new_teacher__school=user.student.class_field.teacher.school
Expand All @@ -304,7 +326,7 @@ def test_retrieve__student__student__not_same_school(self):

user = self._login_student()

other_user = self._get_other_user(
other_user = self._get_another_school_user(
user,
other_users=User.objects.exclude(
new_student__class_field__teacher__school=user.student.class_field.teacher.school
Expand All @@ -318,13 +340,42 @@ def test_retrieve__student__student__not_same_school(self):
status_code_assertion=status.HTTP_404_NOT_FOUND,
)

def test_retrieve__indy_student__teacher(self):
"""
Independent student can not retrieve a teacher.
"""

user = self._login_indy_student()

self._get_other_school_user(
user,
other_users=User.objects.filter(new_teacher__school__isnull=False),
is_teacher=True,
)

def test_retrieve__indy_student__student(self):
"""
Independent student can not retrieve a student.
"""

user = self._login_indy_student()

self._get_other_school_user(
user,
other_users=User.objects.filter(
new_student__class_field__teacher__school__isnull=False
),
is_teacher=False,
)

"""
List naming convention:
test_list__{user_type}
user_type: The type of user that is making the request. Options:
- teacher: A teacher.
- student: A student.
- student: A school student.
- indy_student: A non-school student.
"""

def _list_users(
Expand Down Expand Up @@ -355,9 +406,18 @@ def test_list__teacher(self):

def test_list__student(self):
"""
Student can list only themselves.
Student can list only themself.
"""

user = self._login_student()

self._list_users([user])

def test_list__indy_student(self):
"""
Independent student can list only themself.
"""

user = self._login_indy_student()

self._list_users([user])

0 comments on commit 19a2aa3

Please sign in to comment.