Skip to content

Commit

Permalink
Regression tests
Browse files Browse the repository at this point in the history
- test to check that sort argument is generated automatically for a SQLALchemyConnectionField that uses a SQLALchemyInterface.connection
- test for relationship filtering a model using a relationship to a table with joined table inheritance
  • Loading branch information
gbunkoczi committed Jan 22, 2024
1 parent 902fa93 commit f5e6d32
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 2 deletions.
40 changes: 40 additions & 0 deletions graphene_sqlalchemy/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,46 @@ class Employee(Person):
}


class Owner(Base):
id = Column(Integer(), primary_key=True)
name = Column(String())

accounts = relationship(lambda: Account, back_populates="owner", lazy="selectin")

__tablename__ = "owner"


class Account(Base):
id = Column(Integer(), primary_key=True)
type = Column(String())

owner_id = Column(Integer(), ForeignKey(Owner.__table__.c.id))
owner = relationship(Owner, back_populates="accounts")

balance = Column(Integer())

__tablename__ = "account"
__mapper_args__ = {
"polymorphic_on": type,
}


class CurrentAccount(Account):
overdraft = Column(Integer())

__mapper_args__ = {
"polymorphic_identity": "current",
}


class SavingsAccount(Account):
interest_rate = Column(Integer())

__mapper_args__ = {
"polymorphic_identity": "savings",
}


############################################
# Custom Test Models
############################################
Expand Down
23 changes: 22 additions & 1 deletion graphene_sqlalchemy/tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from graphene.relay import Connection, Node

from ..fields import SQLAlchemyConnectionField, UnsortedSQLAlchemyConnectionField
from ..types import SQLAlchemyObjectType
from ..types import SQLAlchemyInterface, SQLAlchemyObjectType
from .models import Editor as EditorModel
from .models import Employee as EmployeeModel
from .models import Person as PersonModel
from .models import Pet as PetModel


Expand All @@ -21,6 +23,18 @@ class Meta:
model = EditorModel


class Person(SQLAlchemyInterface):
class Meta:
model = PersonModel
use_connection = True


class Employee(SQLAlchemyObjectType):
class Meta:
model = EmployeeModel
interfaces = (Person, Node)


##
# SQLAlchemyConnectionField
##
Expand Down Expand Up @@ -91,3 +105,10 @@ def test_custom_sort():
def test_sort_init_raises():
with pytest.raises(TypeError, match="Cannot create sort"):
SQLAlchemyConnectionField(Connection)


def test_interface_required_sqlalachemy_connection():
field = SQLAlchemyConnectionField(Person.connection, required=True)
assert isinstance(field.type, NonNull)
assert issubclass(field.type.of_type, Connection)
assert field.type.of_type._meta.node is Person
152 changes: 151 additions & 1 deletion graphene_sqlalchemy/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@

from ..fields import SQLAlchemyConnectionField
from ..filters import FloatFilter
from ..types import ORMField, SQLAlchemyObjectType
from ..types import ORMField, SQLAlchemyInterface, SQLAlchemyObjectType
from .models import (
Account,
Article,
CurrentAccount,
Editor,
HairKind,
Image,
Owner,
Pet,
Reader,
Reporter,
SavingsAccount,
ShoppingCart,
ShoppingCartItem,
Tag,
Expand Down Expand Up @@ -1199,3 +1203,149 @@ async def test_additional_filters(session):
schema = graphene.Schema(query=Query)
result = await schema.execute_async(query, context_value={"session": session})
assert_and_raise_result(result, expected)


# Test relationship filter for interface fields
async def add_relationship_interface_test_data(session):
owner1 = Owner(name="John Doe")
owner2 = Owner(name="Jane Doe")
session.add_all([owner1, owner2])

o1_account1 = CurrentAccount(owner=owner1, balance=1000, overdraft=100)
o1_account2 = CurrentAccount(owner=owner1, balance=2000, overdraft=50)
o1_account3 = SavingsAccount(owner=owner1, balance=300, interest_rate=3)

o2_account1 = CurrentAccount(owner=owner2, balance=1000, overdraft=100)
o2_account2 = SavingsAccount(owner=owner2, balance=300, interest_rate=3)
session.add_all([o1_account1, o1_account2, o1_account3, o2_account1, o2_account2])

await eventually_await_session(session, "commit")


def create_relationship_interface_schema(session):
class OwnerType(SQLAlchemyObjectType):
class Meta:
model = Owner
interfaces = (relay.Node,)

class AccountType(SQLAlchemyInterface):
class Meta:
model = Account
use_connection = True

class CurrentAccountType(SQLAlchemyObjectType):
class Meta:
model = CurrentAccount
interfaces = (
AccountType,
relay.Node,
)

class SavingsAccountType(SQLAlchemyObjectType):
class Meta:
model = SavingsAccount
interfaces = (
AccountType,
relay.Node,
)

class Query(graphene.ObjectType):
node = relay.Node.Field()
owners = SQLAlchemyConnectionField(OwnerType.connection)
accounts = SQLAlchemyConnectionField(AccountType.connection)

return (Query, [CurrentAccountType, SavingsAccountType])


@pytest.mark.asyncio
async def test_filter_relationship_interface(session):
await add_relationship_interface_test_data(session)

(Query, types) = create_relationship_interface_schema(session)

query = """
query {
owners(filter: { accounts: { contains: [{balance: {gte: 2000}}]}}) {
edges {
node {
name
accounts {
edges {
node {
__typename
balance
}
}
}
}
}
}
}
"""
expected = {
"owners": {
"edges": [
{
"node": {
"name": "John Doe",
"accounts": {
"edges": [
{
"node": {
"__typename": "CurrentAccountType",
"balance": 1000,
},
},
{
"node": {
"__typename": "CurrentAccountType",
"balance": 2000,
},
},
{
"node": {
"__typename": "SavingsAccountType",
"balance": 300,
},
},
],
},
},
},
],
},
}
schema = graphene.Schema(query=Query, types=types)
result = await schema.execute_async(query, context_value={"session": session})
assert_and_raise_result(result, expected)

query = """
query {
owners(filter: { accounts: { contains: [{balance: {gte: 1000}}]}}) {
edges {
node {
name
}
}
}
}
"""
expected = {
"owners": {
"edges": [
{
"node": {
"name": "John Doe",
},
},
{
"node": {
"name": "Jane Doe",
},
},
]
},
}

result = await schema.execute_async(query, context_value={"session": session})
assert_and_raise_result(result, expected)

0 comments on commit f5e6d32

Please sign in to comment.