refactor: make relay connections extendable

This commit is contained in:
Erik Wrede 2023-03-02 22:36:07 +01:00
parent 8596349405
commit 828e951c0e
2 changed files with 72 additions and 15 deletions

View File

@ -61,7 +61,8 @@ class Connection(ObjectType):
abstract = True abstract = True
@classmethod @classmethod
def __init_subclass_with_meta__(cls, node=None, name=None, **options): def __init_subclass_with_meta__(cls, node=None, name=None, _meta=None, **options):
if not _meta:
_meta = ConnectionOptions(cls) _meta = ConnectionOptions(cls)
assert node, f"You have to provide a node in {cls.__name__}.Meta" assert node, f"You have to provide a node in {cls.__name__}.Meta"
assert isinstance(node, NonNull) or issubclass( assert isinstance(node, NonNull) or issubclass(
@ -92,8 +93,14 @@ class Connection(ObjectType):
cls.Edge = edge cls.Edge = edge
options["name"] = name options["name"] = name
_meta.node = node _meta.node = node
_meta.fields = {
if not _meta.fields:
_meta.fields = {}
_meta.fields.update(
{
"page_info": Field( "page_info": Field(
PageInfo, PageInfo,
name="pageInfo", name="pageInfo",
@ -105,6 +112,7 @@ class Connection(ObjectType):
description="Contains the nodes in this connection.", description="Contains the nodes in this connection.",
), ),
} }
)
return super(Connection, cls).__init_subclass_with_meta__( return super(Connection, cls).__init_subclass_with_meta__(
_meta=_meta, **options _meta=_meta, **options
) )

View File

@ -1,7 +1,7 @@
from pytest import raises from pytest import raises
from ...types import Argument, Field, Int, List, NonNull, ObjectType, Schema, String from ...types import Argument, Field, Int, List, NonNull, ObjectType, Schema, String
from ..connection import Connection, ConnectionField, PageInfo from ..connection import Connection, ConnectionField, PageInfo, ConnectionOptions
from ..node import Node from ..node import Node
@ -51,6 +51,55 @@ def test_connection_inherit_abstracttype():
assert list(fields) == ["page_info", "edges", "extra"] assert list(fields) == ["page_info", "edges", "extra"]
def test_connection_extra_abstract_fields():
class ConnectionWithNodes(Connection):
class Meta:
abstract = True
@classmethod
def __init_subclass_with_meta__(cls, node=None, name=None, **options):
_meta = ConnectionOptions(cls)
_meta.fields = {
"nodes": Field(
NonNull(List(node)),
description="Contains all the nodes in this connection.",
),
}
return super(ConnectionWithNodes, cls).__init_subclass_with_meta__(
node=node, name=name, _meta=_meta, **options
)
class MyObjectConnection(ConnectionWithNodes):
class Meta:
node = MyObject
class Edge:
other = String()
assert MyObjectConnection._meta.name == "MyObjectConnection"
fields = MyObjectConnection._meta.fields
assert list(fields) == ["nodes", "page_info", "edges"]
edge_field = fields["edges"]
pageinfo_field = fields["page_info"]
nodes_field = fields["nodes"]
assert isinstance(edge_field, Field)
assert isinstance(edge_field.type, NonNull)
assert isinstance(edge_field.type.of_type, List)
assert edge_field.type.of_type.of_type == MyObjectConnection.Edge
assert isinstance(pageinfo_field, Field)
assert isinstance(pageinfo_field.type, NonNull)
assert pageinfo_field.type.of_type == PageInfo
assert isinstance(nodes_field, Field)
assert isinstance(nodes_field.type, NonNull)
assert isinstance(nodes_field.type.of_type, List)
assert nodes_field.type.of_type.of_type == MyObject
def test_connection_name(): def test_connection_name():
custom_name = "MyObjectCustomNameConnection" custom_name = "MyObjectCustomNameConnection"