mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-04-11 04:34:20 +03:00
Bugfix: call resolver
function in DjangoConnectionField
as documented (#1529)
* treat warnings as errors when running the tests * silence warnings * bugfix: let DjangoConnectionField call its resolver function that is, the one specified using DjangoConnectionField(..., resolver=some_func) * ignore the DeprecationWarning about typing.ByteString in graphql
This commit is contained in:
parent
97deb761e9
commit
e69e4a0399
|
@ -28,3 +28,5 @@ TEMPLATES = [
|
|||
GRAPHENE = {"SCHEMA": "graphene_django.tests.schema_view.schema"}
|
||||
|
||||
ROOT_URLCONF = "graphene_django.tests.urls"
|
||||
|
||||
USE_TZ = True
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import graphene
|
||||
from graphene import Schema, relay, resolve_only_args
|
||||
from graphene import Schema, relay
|
||||
from graphene_django import DjangoConnectionField, DjangoObjectType
|
||||
|
||||
from .data import create_ship, get_empire, get_faction, get_rebels, get_ship, get_ships
|
||||
|
@ -62,16 +62,13 @@ class Query(graphene.ObjectType):
|
|||
node = relay.Node.Field()
|
||||
ships = DjangoConnectionField(Ship, description="All the ships.")
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_ships(self):
|
||||
def resolve_ships(self, info):
|
||||
return get_ships()
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_rebels(self):
|
||||
def resolve_rebels(self, info):
|
||||
return get_rebels()
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_empire(self):
|
||||
def resolve_empire(self, info):
|
||||
return get_empire()
|
||||
|
||||
|
||||
|
|
|
@ -199,19 +199,13 @@ def convert_field_to_string(field, registry=None):
|
|||
)
|
||||
|
||||
|
||||
@convert_django_field.register(models.BigAutoField)
|
||||
@convert_django_field.register(models.AutoField)
|
||||
@convert_django_field.register(models.BigAutoField)
|
||||
@convert_django_field.register(models.SmallAutoField)
|
||||
def convert_field_to_id(field, registry=None):
|
||||
return ID(description=get_django_field_description(field), required=not field.null)
|
||||
|
||||
|
||||
if hasattr(models, "SmallAutoField"):
|
||||
|
||||
@convert_django_field.register(models.SmallAutoField)
|
||||
def convert_field_small_to_id(field, registry=None):
|
||||
return convert_field_to_id(field, registry)
|
||||
|
||||
|
||||
@convert_django_field.register(models.UUIDField)
|
||||
def convert_field_to_uuid(field, registry=None):
|
||||
return UUID(
|
||||
|
|
|
@ -247,7 +247,7 @@ class DjangoConnectionField(ConnectionField):
|
|||
def wrap_resolve(self, parent_resolver):
|
||||
return partial(
|
||||
self.connection_resolver,
|
||||
parent_resolver,
|
||||
self.resolver or parent_resolver,
|
||||
self.connection_type,
|
||||
self.get_manager(),
|
||||
self.get_queryset_resolver(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from django import forms
|
||||
from django import VERSION as DJANGO_VERSION, forms
|
||||
from pytest import raises
|
||||
|
||||
from graphene import (
|
||||
|
@ -19,12 +19,16 @@ from graphene import (
|
|||
from ..converter import convert_form_field
|
||||
|
||||
|
||||
def assert_conversion(django_field, graphene_field, *args):
|
||||
field = django_field(*args, help_text="Custom Help Text")
|
||||
def assert_conversion(django_field, graphene_field, *args, **kwargs):
|
||||
# Arrange
|
||||
help_text = kwargs.setdefault("help_text", "Custom Help Text")
|
||||
field = django_field(*args, **kwargs)
|
||||
# Act
|
||||
graphene_type = convert_form_field(field)
|
||||
# Assert
|
||||
assert isinstance(graphene_type, graphene_field)
|
||||
field = graphene_type.Field()
|
||||
assert field.description == "Custom Help Text"
|
||||
assert field.description == help_text
|
||||
return field
|
||||
|
||||
|
||||
|
@ -59,7 +63,12 @@ def test_should_slug_convert_string():
|
|||
|
||||
|
||||
def test_should_url_convert_string():
|
||||
assert_conversion(forms.URLField, String)
|
||||
kwargs = {}
|
||||
if DJANGO_VERSION >= (5, 0):
|
||||
# silence RemovedInDjango60Warning
|
||||
kwargs["assume_scheme"] = "https"
|
||||
|
||||
assert_conversion(forms.URLField, String, **kwargs)
|
||||
|
||||
|
||||
def test_should_choice_convert_string():
|
||||
|
@ -75,8 +84,7 @@ def test_should_regex_convert_string():
|
|||
|
||||
|
||||
def test_should_uuid_convert_string():
|
||||
if hasattr(forms, "UUIDField"):
|
||||
assert_conversion(forms.UUIDField, UUID)
|
||||
assert_conversion(forms.UUIDField, UUID)
|
||||
|
||||
|
||||
def test_should_integer_convert_int():
|
||||
|
|
|
@ -96,8 +96,7 @@ def test_should_regex_convert_string():
|
|||
|
||||
|
||||
def test_should_uuid_convert_string():
|
||||
if hasattr(serializers, "UUIDField"):
|
||||
assert_conversion(serializers.UUIDField, graphene.String)
|
||||
assert_conversion(serializers.UUIDField, graphene.String)
|
||||
|
||||
|
||||
def test_should_model_convert_field():
|
||||
|
|
|
@ -53,9 +53,8 @@ def assert_conversion(django_field, graphene_field, *args, **kwargs):
|
|||
|
||||
|
||||
def test_should_unknown_django_field_raise_exception():
|
||||
with raises(Exception) as excinfo:
|
||||
with raises(Exception, match="Don't know how to convert the Django field"):
|
||||
convert_django_field(None)
|
||||
assert "Don't know how to convert the Django field" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_should_date_time_convert_string():
|
||||
|
@ -115,8 +114,7 @@ def test_should_big_auto_convert_id():
|
|||
|
||||
|
||||
def test_should_small_auto_convert_id():
|
||||
if hasattr(models, "SmallAutoField"):
|
||||
assert_conversion(models.SmallAutoField, graphene.ID, primary_key=True)
|
||||
assert_conversion(models.SmallAutoField, graphene.ID, primary_key=True)
|
||||
|
||||
|
||||
def test_should_uuid_convert_id():
|
||||
|
@ -166,14 +164,14 @@ def test_field_with_choices_convert_enum():
|
|||
help_text="Language", choices=(("es", "Spanish"), ("en", "English"))
|
||||
)
|
||||
|
||||
class TranslatedModel(models.Model):
|
||||
class ChoicesModel(models.Model):
|
||||
language = field
|
||||
|
||||
class Meta:
|
||||
app_label = "test"
|
||||
|
||||
graphene_type = convert_django_field_with_choices(field).type.of_type
|
||||
assert graphene_type._meta.name == "TestTranslatedModelLanguageChoices"
|
||||
assert graphene_type._meta.name == "TestChoicesModelLanguageChoices"
|
||||
assert graphene_type._meta.enum.__members__["ES"].value == "es"
|
||||
assert graphene_type._meta.enum.__members__["ES"].description == "Spanish"
|
||||
assert graphene_type._meta.enum.__members__["EN"].value == "en"
|
||||
|
@ -186,14 +184,14 @@ def test_field_with_callable_choices_convert_enum():
|
|||
|
||||
field = models.CharField(help_text="Language", choices=get_choices)
|
||||
|
||||
class TranslatedModel(models.Model):
|
||||
class CallableChoicesModel(models.Model):
|
||||
language = field
|
||||
|
||||
class Meta:
|
||||
app_label = "test"
|
||||
|
||||
graphene_type = convert_django_field_with_choices(field).type.of_type
|
||||
assert graphene_type._meta.name == "TestTranslatedModelLanguageChoices"
|
||||
assert graphene_type._meta.name == "TestCallableChoicesModelLanguageChoices"
|
||||
assert graphene_type._meta.enum.__members__["ES"].value == "es"
|
||||
assert graphene_type._meta.enum.__members__["ES"].description == "Spanish"
|
||||
assert graphene_type._meta.enum.__members__["EN"].value == "en"
|
||||
|
|
|
@ -26,6 +26,7 @@ class TestShouldCallGetQuerySetOnForeignKey:
|
|||
class ReporterType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Reporter
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
@ -36,6 +37,7 @@ class TestShouldCallGetQuerySetOnForeignKey:
|
|||
class ArticleType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
@ -200,6 +202,7 @@ class TestShouldCallGetQuerySetOnForeignKeyNode:
|
|||
class ReporterType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Reporter
|
||||
fields = "__all__"
|
||||
interfaces = (Node,)
|
||||
|
||||
@classmethod
|
||||
|
@ -211,6 +214,7 @@ class TestShouldCallGetQuerySetOnForeignKeyNode:
|
|||
class ArticleType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = "__all__"
|
||||
interfaces = (Node,)
|
||||
|
||||
@classmethod
|
||||
|
@ -370,6 +374,7 @@ class TestShouldCallGetQuerySetOnOneToOne:
|
|||
class FilmDetailsType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = FilmDetails
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
@ -380,6 +385,7 @@ class TestShouldCallGetQuerySetOnOneToOne:
|
|||
class FilmType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Film
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import base64
|
||||
import datetime
|
||||
from unittest.mock import ANY, Mock
|
||||
|
||||
import pytest
|
||||
from django.db import models
|
||||
|
@ -2000,14 +2001,62 @@ def test_connection_should_succeed_if_last_higher_than_number_of_objects():
|
|||
assert result.data == expected
|
||||
|
||||
|
||||
def test_connection_should_call_resolver_function():
|
||||
resolver_mock = Mock(
|
||||
name="resolver",
|
||||
return_value=[
|
||||
Reporter(first_name="Some", last_name="One"),
|
||||
Reporter(first_name="John", last_name="Doe"),
|
||||
],
|
||||
)
|
||||
|
||||
class ReporterType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Reporter
|
||||
fields = "__all__"
|
||||
interfaces = [Node]
|
||||
|
||||
class Query(graphene.ObjectType):
|
||||
reporters = DjangoConnectionField(ReporterType, resolver=resolver_mock)
|
||||
|
||||
schema = graphene.Schema(query=Query)
|
||||
result = schema.execute(
|
||||
"""
|
||||
query {
|
||||
reporters {
|
||||
edges {
|
||||
node {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
resolver_mock.assert_called_once_with(None, ANY)
|
||||
assert not result.errors
|
||||
assert result.data == {
|
||||
"reporters": {
|
||||
"edges": [
|
||||
{"node": {"firstName": "Some", "lastName": "One"}},
|
||||
{"node": {"firstName": "John", "lastName": "Doe"}},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_should_query_nullable_foreign_key():
|
||||
class PetType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Pet
|
||||
fields = "__all__"
|
||||
|
||||
class PersonType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Person
|
||||
fields = "__all__"
|
||||
|
||||
class Query(graphene.ObjectType):
|
||||
pet = graphene.Field(PetType, name=graphene.String(required=True))
|
||||
|
@ -2022,10 +2071,8 @@ def test_should_query_nullable_foreign_key():
|
|||
schema = graphene.Schema(query=Query)
|
||||
|
||||
person = Person.objects.create(name="Jane")
|
||||
[
|
||||
Pet.objects.create(name="Stray dog", age=1),
|
||||
Pet.objects.create(name="Jane's dog", owner=person, age=1),
|
||||
]
|
||||
Pet.objects.create(name="Stray dog", age=1)
|
||||
Pet.objects.create(name="Jane's dog", owner=person, age=1)
|
||||
|
||||
query_pet = """
|
||||
query getPet($name: String!) {
|
||||
|
@ -2068,6 +2115,7 @@ def test_should_query_nullable_one_to_one_relation_with_custom_resolver():
|
|||
class FilmType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = Film
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
@ -2076,6 +2124,7 @@ def test_should_query_nullable_one_to_one_relation_with_custom_resolver():
|
|||
class FilmDetailsType(DjangoObjectType):
|
||||
class Meta:
|
||||
model = FilmDetails
|
||||
fields = "__all__"
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset, info):
|
||||
|
|
|
@ -10,3 +10,7 @@ omit = */tests/*
|
|||
[tool:pytest]
|
||||
DJANGO_SETTINGS_MODULE = examples.django_test_settings
|
||||
addopts = --random-order
|
||||
filterwarnings =
|
||||
error
|
||||
# we can't do anything about the DeprecationWarning about typing.ByteString in graphql
|
||||
default:'typing\.ByteString' is deprecated:DeprecationWarning:graphql\.pyutils\.is_iterable
|
||||
|
|
Loading…
Reference in New Issue
Block a user