Skip to content

Commit

Permalink
fix type imports
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Nov 4, 2024
1 parent 4c8e557 commit 77bd91c
Showing 1 changed file with 62 additions and 25 deletions.
87 changes: 62 additions & 25 deletions codeforlife/tests/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@
from rest_framework.test import APIClient as _APIClient

from ..types import DataDict, JsonDict
from ..user.models import AdminSchoolTeacherUser
from ..user.models import AnyUser as RequestUser
from ..user.models import (
AuthFactor,
IndependentUser,
NonAdminSchoolTeacherUser,
NonSchoolTeacherUser,
SchoolTeacherUser,
StudentUser,
TeacherUser,
TypedUser,
User,
)
from .api_request_factory import APIRequestFactory
from .test import TestCase

LoginUser = t.TypeVar("LoginUser", bound=User)


class APIClient(_APIClient, t.Generic[RequestUser]):
if t.TYPE_CHECKING:
from ..user.models import (
AdminSchoolTeacherUser,
AuthFactor,
IndependentUser,
NonAdminSchoolTeacherUser,
NonSchoolTeacherUser,
SchoolTeacherUser,
StudentUser,
TeacherUser,
TypedUser,
User,
)

RequestUser = t.TypeVar("RequestUser", bound=User)
LoginUser = t.TypeVar("LoginUser", bound=User)


class APIClient(_APIClient, t.Generic["RequestUser"]):
"""Base API client to be inherited by all other API clients."""

_test_case: "APITestCase[RequestUser]"
Expand All @@ -56,7 +58,7 @@ def __init__(
)

@classmethod
def get_request_user_class(cls) -> t.Type[RequestUser]:
def get_request_user_class(cls) -> t.Type["RequestUser"]:
"""Get the request's user class.
Returns:
Expand Down Expand Up @@ -118,7 +120,10 @@ def _make_assertions():
# Login Helpers
# --------------------------------------------------------------------------

def _login_user_type(self, user_type: t.Type[LoginUser], **credentials):
def _login_user_type(self, user_type: t.Type["LoginUser"], **credentials):
# pylint: disable-next=import-outside-toplevel
from ..user.models import AuthFactor

# Logout current user (if any) before logging in next user.
self.logout()
assert super().login(
Expand All @@ -135,7 +140,7 @@ def _login_user_type(self, user_type: t.Type[LoginUser], **credentials):
with patch.object(timezone, "now", return_value=now):
assert super().login(
request=self.request_factory.post(
user=t.cast(RequestUser, user)
user=t.cast("RequestUser", user)
),
otp=otp,
), f'Failed to login with OTP "{otp}" at {now}.'
Expand All @@ -162,6 +167,9 @@ def login_teacher(self, email: str, password: str = "password"):
Returns:
The teacher-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import TeacherUser

return self._login_user_type(
TeacherUser, email=email, password=password
)
Expand All @@ -176,6 +184,9 @@ def login_school_teacher(self, email: str, password: str = "password"):
Returns:
The school-teacher-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import SchoolTeacherUser

return self._login_user_type(
SchoolTeacherUser, email=email, password=password
)
Expand All @@ -192,6 +203,9 @@ def login_admin_school_teacher(
Returns:
The admin-school-teacher-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import AdminSchoolTeacherUser

return self._login_user_type(
AdminSchoolTeacherUser, email=email, password=password
)
Expand All @@ -208,6 +222,9 @@ def login_non_admin_school_teacher(
Returns:
The non-admin-school-teacher-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import NonAdminSchoolTeacherUser

return self._login_user_type(
NonAdminSchoolTeacherUser, email=email, password=password
)
Expand All @@ -222,6 +239,9 @@ def login_non_school_teacher(self, email: str, password: str = "password"):
Returns:
The non-school-teacher-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import NonSchoolTeacherUser

return self._login_user_type(
NonSchoolTeacherUser, email=email, password=password
)
Expand All @@ -239,6 +259,9 @@ def login_student(
Returns:
The student-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import StudentUser

return self._login_user_type(
StudentUser,
first_name=first_name,
Expand All @@ -256,18 +279,32 @@ def login_indy(self, email: str, password: str = "password"):
Returns:
The independent-user.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import IndependentUser

return self._login_user_type(
IndependentUser, email=email, password=password
)

def login_as(self, user: TypedUser, password: str = "password"):
def login_as(self, user: "TypedUser", password: str = "password"):
"""Log in as a user. The user instance needs to be a user proxy in order
to know which credentials are required.
Args:
user: The user to log in as.
password: The user's password.
"""
# pylint: disable-next=import-outside-toplevel
from ..user.models import (
AdminSchoolTeacherUser,
IndependentUser,
NonAdminSchoolTeacherUser,
NonSchoolTeacherUser,
SchoolTeacherUser,
StudentUser,
TeacherUser,
)

auth_user = None

if isinstance(user, AdminSchoolTeacherUser):
Expand Down Expand Up @@ -487,14 +524,14 @@ def options( # type: ignore[override]
# pylint: enable=too-many-arguments,redefined-builtin


class APITestCase(TestCase, t.Generic[RequestUser]):
class APITestCase(TestCase, t.Generic["RequestUser"]):
"""Base API test case to be inherited by all other API test cases."""

client: APIClient[RequestUser]
client_class: t.Type[APIClient[RequestUser]] = APIClient
client: APIClient["RequestUser"]
client_class: t.Type[APIClient["RequestUser"]] = APIClient

@classmethod
def get_request_user_class(cls) -> t.Type[RequestUser]:
def get_request_user_class(cls) -> t.Type["RequestUser"]:
"""Get the request's user class.
Returns:
Expand Down

0 comments on commit 77bd91c

Please sign in to comment.