Skip to content

Commit

Permalink
Added ResolveInfoTestCase
Browse files Browse the repository at this point in the history
  • Loading branch information
mongkok committed Aug 4, 2023
1 parent 4a45e21 commit 10d2408
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 64 deletions.
36 changes: 18 additions & 18 deletions tests/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
from graphql_jwt import decorators, exceptions

from .decorators import override_jwt_settings
from .testcases import TestCase
from .testcases import ResolveInfoTestCase


class UserPassesTests(TestCase):
class UserPassesTests(ResolveInfoTestCase):
def test_user_passes_test(self):
result = decorators.user_passes_test(
lambda u: u.pk == self.user.pk,
)(
lambda info: None
)(self.info(self.user))
)(self.info_mock(self.user))

self.assertIsNone(result)

Expand All @@ -23,66 +23,66 @@ def test_permission_denied(self):
)(lambda info: None)

with self.assertRaises(exceptions.PermissionDenied):
func(self.info(self.user))
func(self.info_mock(self.user))


class LoginRequiredTests(TestCase):
class LoginRequiredTests(ResolveInfoTestCase):
def test_login_required(self):
result = decorators.login_required(
lambda info: None,
)(self.info(self.user))
)(self.info_mock(self.user))

self.assertIsNone(result)

def test_permission_denied(self):
func = decorators.login_required(lambda info: None)

with self.assertRaises(exceptions.PermissionDenied):
func(self.info(AnonymousUser()))
func(self.info_mock(AnonymousUser()))


class StaffMemberRequiredTests(TestCase):
class StaffMemberRequiredTests(ResolveInfoTestCase):
def test_staff_member_required(self):
self.user.is_staff = True

result = decorators.staff_member_required(
lambda info: None,
)(self.info(self.user))
)(self.info_mock(self.user))

self.assertIsNone(result)

def test_permission_denied(self):
func = decorators.staff_member_required(lambda info: None)

with self.assertRaises(exceptions.PermissionDenied):
func(self.info(self.user))
func(self.info_mock(self.user))


class SuperuserRequiredTests(TestCase):
class SuperuserRequiredTests(ResolveInfoTestCase):
def test_superuser_required(self):
self.user.is_superuser = True

result = decorators.superuser_required(
lambda info: None,
)(self.info(self.user))
)(self.info_mock(self.user))

self.assertIsNone(result)

def test_permission_denied(self):
func = decorators.superuser_required(lambda info: None)

with self.assertRaises(exceptions.PermissionDenied):
func(self.info(self.user))
func(self.info_mock(self.user))


class PermissionRequiredTests(TestCase):
class PermissionRequiredTests(ResolveInfoTestCase):
def test_permission_required(self):
perm = Permission.objects.get(codename="add_user")
self.user.user_permissions.add(perm)

result = decorators.permission_required("auth.add_user")(
lambda info: None,
)(self.info(self.user))
)(self.info_mock(self.user))

self.assertIsNone(result)

Expand All @@ -92,13 +92,13 @@ def test_permission_denied(self):
)(lambda info: None)

with self.assertRaises(exceptions.PermissionDenied):
func(self.info(self.user))
func(self.info_mock(self.user))


class CSRFRotationTests(TestCase):
class CSRFRotationTests(ResolveInfoTestCase):
@override_jwt_settings(JWT_CSRF_ROTATION=True)
def test_csrf_rotation(self):
info_mock = self.info(AnonymousUser())
info_mock = self.info_mock(AnonymousUser())
decorators.csrf_rotation(
lambda cls, root, info, *args, **kwargs: None,
)(self, None, info_mock)
Expand Down
89 changes: 47 additions & 42 deletions tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

from django.contrib.auth.models import AnonymousUser

import graphene
from graphql import OperationDefinitionNode, OperationType

import graphql_jwt
from graphql_jwt.exceptions import JSONWebTokenError
from graphql_jwt.middleware import JSONWebTokenMiddleware, allow_any
from graphql_jwt.settings import jwt_settings

from .decorators import override_jwt_settings
from .testcases import TestCase
from .testcases import ResolveInfoTestCase


class AuthenticateByHeaderTests(TestCase):
class AuthenticateByHeaderTests(ResolveInfoTestCase):
def setUp(self):
super().setUp()
self.middleware = JSONWebTokenMiddleware()
Expand All @@ -24,7 +28,7 @@ def test_authenticate(self):
}

next_mock = mock.Mock()
info_mock = self.info(AnonymousUser(), **headers)
info_mock = self.info_mock(user=AnonymousUser(), headers=headers)

self.middleware.resolve(next_mock, None, info_mock)

Expand All @@ -41,7 +45,7 @@ def test_not_authenticate(self, authenticate_mock):
}

next_mock = mock.Mock()
info_mock = self.info(AnonymousUser(), **headers)
info_mock = self.info_mock(user=AnonymousUser(), headers=headers)

self.middleware.resolve(next_mock, None, info_mock)

Expand All @@ -58,7 +62,7 @@ def test_invalid_token(self):
}

next_mock = mock.Mock()
info_mock = self.info(AnonymousUser(), **headers)
info_mock = self.info_mock(user=AnonymousUser(), headers=headers)

with self.assertRaises(JSONWebTokenError):
self.middleware.resolve(next_mock, None, info_mock)
Expand All @@ -74,7 +78,7 @@ def test_already_authenticated(self, authenticate_mock):
}

next_mock = mock.Mock()
info_mock = self.info(self.user, **headers)
info_mock = self.info_mock(user=self.user, headers=headers)

self.middleware.resolve(next_mock, None, info_mock)

Expand All @@ -90,38 +94,39 @@ def test_allow_any(self):
}

next_mock = mock.Mock()
info_mock = self.info(AnonymousUser(), **headers)
info_mock = self.info_mock(user=AnonymousUser(), headers=headers)

self.middleware.resolve(next_mock, None, info_mock)

next_mock.assert_called_once_with(None, info_mock)
self.assertIsInstance(info_mock.context.user, AnonymousUser)

def test_authenticate_context(self):
info_mock = self.info()
info_mock = self.info_mock(path=["path"])

self.middleware.cached_allow_any.add("test")
self.middleware.cached_allow_any.add("path")
authenticate_context = self.middleware.authenticate_context(info_mock)

self.assertFalse(authenticate_context)


class AuthenticateByArgumentTests(TestCase):
class AuthenticateByArgumentTests(ResolveInfoTestCase):
@override_jwt_settings(JWT_ALLOW_ARGUMENT=True)
def setUp(self):
super().setUp()
self.middleware = JSONWebTokenMiddleware()

@override_jwt_settings(
JWT_ALLOW_ARGUMENT=True, JWT_ALLOW_ANY_HANDLER=lambda *args, **kwargs: False
JWT_ALLOW_ARGUMENT=True,
JWT_ALLOW_ANY_HANDLER=lambda *args, **kwargs: False,
)
def test_authenticate(self):
kwargs = {
jwt_settings.JWT_ARGUMENT_NAME: self.token,
}

next_mock = mock.Mock()
info_mock = self.info(AnonymousUser())
info_mock = self.info_mock(AnonymousUser())

self.middleware.resolve(next_mock, None, info_mock, **kwargs)

Expand All @@ -134,8 +139,7 @@ def test_authenticate(self):
@override_jwt_settings(JWT_ALLOW_ARGUMENT=True)
def test_authenticate_parent(self):
next_mock = mock.Mock()
info_mock = self.info(AnonymousUser())
info_mock.path = ["0", "1"]
info_mock = self.info_mock(user=AnonymousUser(), path=["0", "1"])

self.middleware.cached_authentication.insert(["0"], self.user)
self.middleware.resolve(next_mock, None, info_mock)
Expand All @@ -146,7 +150,7 @@ def test_authenticate_parent(self):
@override_jwt_settings(JWT_ALLOW_ARGUMENT=True)
def test_clear_authentication(self):
next_mock = mock.Mock()
info_mock = self.info(self.user)
info_mock = self.info_mock(self.user)

self.middleware.resolve(next_mock, None, info_mock)

Expand All @@ -156,7 +160,7 @@ def test_clear_authentication(self):
@override_jwt_settings(JWT_ALLOW_ARGUMENT=True)
def test_clear_session_authentication(self):
next_mock = mock.Mock()
info_mock = self.info(self.user)
info_mock = self.info_mock(self.user)
info_mock.context.session = self.client.session

self.middleware.resolve(next_mock, None, info_mock)
Expand All @@ -167,55 +171,56 @@ def test_clear_session_authentication(self):
@override_jwt_settings(JWT_ALLOW_ARGUMENT=True)
def test_context_has_not_attr_user(self):
next_mock = mock.Mock()
info_mock = self.info()
info_mock = self.info_mock()

self.middleware.resolve(next_mock, None, info_mock)

next_mock.assert_called_once_with(None, info_mock)
self.assertFalse(hasattr(info_mock.context, "user"))


class AllowAnyTests(TestCase):
def info(self, user, **headers):
info_mock = super().info(user, **headers)
info_mock.field_name = "test"
info_mock.operation.operation.value = "query"
return info_mock
class AllowAnyMutation(graphene.Mutation):
def mutate(root, info):
return None

def info_with_field_mock(self, user, field=None):
info_mock = self.info(user)
info_mock.schema.query_type = mock.Mock(
fields={
"test": field,
}
)
return info_mock

def info_with_type_mock(self, user, type=None):
type_mock = mock.Mock(type=mock.Mock(graphene_type=type))
return self.info_with_field_mock(user, type_mock)
class AllowAnyTests(ResolveInfoTestCase):
def info_mock(self, user, **kwargs):
class Mutation(graphene.ObjectType):
test = AllowAnyMutation.Field()
verify = graphql_jwt.Verify.Field()

schema = graphene.Schema(mutation=Mutation).graphql_schema
operation = OperationDefinitionNode(operation=OperationType("mutation"))

return super().info_mock(
user=user,
schema=schema,
operation=operation,
**kwargs,
)

@override_jwt_settings(JWT_ALLOW_ANY_CLASSES=["tests.testcases.TestCase"])
@override_jwt_settings(JWT_ALLOW_ANY_CLASSES=[f"{__name__}.AllowAnyMutation"])
def test_allow_any(self):
info_mock = self.info_with_type_mock(self.user, TestCase)
info_mock = self.info_mock(self.user, field_name="test")
allowed = allow_any(info_mock)

self.assertTrue(allowed)

def test_not_allow_any(self):
info_mock = self.info_with_type_mock(self.user, TestCase)
def test_allow_jwt_mutations(self):
info_mock = self.info_mock(user=self.user, field_name="verify")
allowed = allow_any(info_mock)

self.assertFalse(allowed)
self.assertTrue(allowed)

def test_unknown_field(self):
info_mock = self.info_with_field_mock(self.user)
info_mock = self.info_mock(self.user)
allowed = allow_any(info_mock)

self.assertFalse(allowed)

def test_unknown_type(self):
info_mock = self.info_with_type_mock(self.user)
def test_not_allow_any(self):
info_mock = self.info_mock(self.user, field_name="test")
allowed = allow_any(info_mock)

self.assertFalse(allowed)
13 changes: 9 additions & 4 deletions tests/testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import graphene
from graphene_django.views import GraphQLView
from graphql.execution.execute import GraphQLResolveInfo

from graphql_jwt.decorators import jwt_cookie
from graphql_jwt.settings import jwt_settings
Expand All @@ -29,16 +28,22 @@ def setUp(self):
self.token = jwt_encode(self.payload)
self.request_factory = RequestFactory()

def info(self, user=None, **headers):
request = self.request_factory.post("/", **headers)

class ResolveInfoTestCase(TestCase):
def info_mock(self, user=None, path=None, headers=None, **kwargs):
request = self.request_factory.post("/", **(headers or {}))

if user is not None:
request.user = user

if path is None:
path = [""]

return mock.Mock(
context=request,
path=["test"],
path=path,
spec=graphene.ResolveInfo,
**kwargs,
)


Expand Down

0 comments on commit 10d2408

Please sign in to comment.