Django-oauth-toolkit : Тестирование пользовательского TokenView

Я пытаюсь написать модульный тест для пользовательской реализации django-oauth-toolkit TokenView

Причина наследования от TokenView заключается в том, чтобы потребовать токен 2FA перед генерацией токена доступа.

Ниже показано, как выглядит вид

class CustomTokenView(TokenView):
    @method_decorator(sensitive_post_parameters("password"))
    def post(self, request, *args, **kwargs):

        meta = request.META
        grant_type = urllib.parse.parse_qs(request.body.decode("utf-8")).get("grant_type")[0]


        if grant_type == "password":
            """
            Users trying to log in with email and password.
            """
            try:
                email = urllib.parse.parse_qs(request.body.decode("utf-8"))["username"][0]
            except KeyError:
                return JsonResponse(data={"message": "Email is required", "status": "0"}, status=400)

            try:
                token = urllib.parse.parse_qs(request.body.decode("utf-8"))["token"][0]
            except KeyError:
                return JsonResponse(data={"message": "Token is required", "status": "0"}, status=400)

            email = simplefunctions.remove_unicode(email)

            user_obj = CustomUser.objects.filter(
                email=email, is_active=True,
                is_staff=True,
                is_account_disabled=False).first()

            if user_obj is None:
                return JsonResponse(data={"message": "Invalid Email", "status": "0"}, status=400)
            else:
                application_log.debug(f"User {user_obj.email} tried to login with password. Request header data {meta}")

            if token:
                if not services.UserService.is_valid_2fa_token(user_obj, token):
                    return JsonResponse(data={"message": "Invalid Token", "status": "0"}, status=400)

            return super().post(request, *args, **kwargs)

        return JsonResponse(data={"message": "Invalid grant type", "status": "0"}, status=400)

Я могу извлечь данные каждого запроса и выполнить их валидацию. но возвращается ошибка, когда вызывается return super().post(request, *args, **kwargs).

Как выглядит мой тест

from oauth2_provider.settings import oauth2_settings
from oauth2_provider.models import get_access_token_model, get_application_model
from django.contrib.auth import get_user_model
from django.utils import timezone

Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()

class AdminAuthTests(APITestCase):

    def setUp(self):
        self.admin_user = UserFactory()
        self.admin_user.is_staff = True
        # self.admin_user.set_password("test_password")
        set_pin_hash(self.admin_user, "1234")
        self.admin_user.save()

        self.rogue_user = UserFactory()
        SecurityQuestionFactory.create(question="Mother's maiden name")
        SecurityQuestionFactory.create(question="Favorite Food")

        oauth2_settings._SCOPES = ["read", "write", "scope1", "scope2", "resource1"]

        self.application = Application.objects.create(
            name="Test Application",
            client_type="public",
            authorization_grant_type="password"
        )


    @patch('users.views.admin_auth_views.services.UserService.is_valid_2fa_token')
    def test_can_login_with_2fa(self, mock_is_valid_2fa_token):
        """
        The user should be able to log in with 2fa
        """
        mock_is_valid_2fa_token.return_value = True
        self.url = reverse("api-v2:token")
        payload = {
            "client_id": self.application.client_id,
            "username": self.admin_user.email,
            "grant_type": "password",
            "token": "123456",
            "password": "test_password",
        }
        data = urllib.parse.urlencode(payload).encode()
        res = self.client.post(self.url, data=data, format="json")
        res_json = res.json()
        print(data)
        print(res_json)
        mock_is_valid_2fa_token.assert_called_once()
        self.assertEqual(res.status_code, status.HTTP_200_OK)

Сообщение об ошибке

{'error': 'unsupported_grant_type'}

Я занимаюсь этим уже несколько дней и буду благодарен, если кто-то сможет дать мне несколько советов.

Вернуться на верх