Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
33 changes: 33 additions & 0 deletions tests/node_polymorphism_inheritancemanager/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from django.db import models
from model_utils.managers import InheritanceManager


class Project(models.Model):
topic = models.CharField(max_length=30)
dependencies = models.ManyToManyField(
"self", symmetrical=False, related_name="dependants", blank=True
)

base_objects = InheritanceManager()
objects = InheritanceManager()

class Meta:
base_manager_name = "base_objects"


class ArtProject(Project):
artist = models.CharField(max_length=30)
art_style = models.CharField(max_length=30)


class ResearchProject(Project):
supervisor = models.CharField(max_length=30)
research_notes = models.TextField()


class SoftwareProject(Project):
repository = models.CharField(max_length=255)


class EngineeringProject(Project):
lead_engineer = models.CharField(max_length=255)
76 changes: 76 additions & 0 deletions tests/node_polymorphism_inheritancemanager/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import strawberry
from strawberry.relay import Node

import strawberry_django
from strawberry_django import ListInput, NodeInput
from strawberry_django.optimizer import DjangoOptimizerExtension
from strawberry_django.relay import DjangoListConnection

from .models import (
ArtProject,
EngineeringProject,
Project,
ResearchProject,
SoftwareProject,
)


@strawberry_django.interface(Project)
class ProjectType(Node):
topic: strawberry.auto
dependencies: DjangoListConnection["ProjectType"] = strawberry_django.connection()
dependants: DjangoListConnection["ProjectType"] = strawberry_django.connection()


@strawberry_django.partial(Project)
class ProjectInputPartial(NodeInput):
topic: strawberry.auto = strawberry_django.field()
dependencies: ListInput[NodeInput] | None = strawberry_django.field()
dependants: ListInput[NodeInput] | None = strawberry_django.field()


@strawberry_django.type(ArtProject)
class ArtProjectType(ProjectType):
artist: strawberry.auto
art_style: strawberry.auto


@strawberry_django.type(ResearchProject)
class ResearchProjectType(ProjectType):
supervisor: strawberry.auto


@strawberry_django.type(SoftwareProject)
class SoftwareProjectType(ProjectType):
repository: strawberry.auto


@strawberry_django.type(EngineeringProject)
class EngineeringProjectType(ProjectType):
lead_engineer: strawberry.auto


@strawberry.type
class Query:
node: Node = strawberry.relay.node()
projects: DjangoListConnection[ProjectType] = strawberry_django.field()


@strawberry.type
class Mutation:
update_art_project: ArtProjectType = strawberry_django.mutations.update(
ProjectInputPartial
)


schema = strawberry.Schema(
query=Query,
mutation=Mutation,
types=[
ArtProjectType,
ResearchProjectType,
EngineeringProjectType,
SoftwareProjectType,
],
extensions=[DjangoOptimizerExtension],
)
169 changes: 169 additions & 0 deletions tests/node_polymorphism_inheritancemanager/test_optimizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import pytest
from strawberry.relay import GlobalID

from .models import (
ArtProject,
EngineeringProject,
ResearchProject,
SoftwareProject,
)
from .schema import schema


@pytest.mark.django_db(transaction=True)
def test_polymorphic_mutation_abstract_model_many_to_many_rel():
ap = ArtProject.objects.create(topic="Art", artist="Artist", art_style="Modern")
sp = SoftwareProject.objects.create(
topic="Software", repository="https://example.com"
)
ep = EngineeringProject.objects.create(
topic="Engineering", lead_engineer="Elara Voss"
)
rp = ResearchProject.objects.create(
topic="Research", supervisor="J. Hiles", research_notes="Important notes"
)

ap_node = GlobalID(type_name="ArtProjectType", node_id=str(ap.pk))
sp_node = GlobalID(type_name="SoftwareProjectType", node_id=str(sp.pk))
ep_node = GlobalID(type_name="EngineeringProjectType", node_id=str(ep.pk))
rp_node = GlobalID(type_name="ResearchProjectType", node_id=str(rp.pk))

query = f"""
query {{
node(id: "{ap_node}") {{
__typename
... on ArtProjectType {{
id
artist
artStyle
dependencies {{
totalCount
edges {{
node {{
__typename
id
}}
}}
}}
dependants {{
totalCount
edges {{
node {{
__typename
id
}}
}}
}}
}}
}}
}}
"""

mutation = f"""
mutation {{
updateArtProject(data: {{
id: "{ap_node}"
dependencies: {{ set: [ {{ id: "{sp_node}" }}, {{ id: "{ep_node}" }} ] }}
dependants: {{ set: [ {{ id: "{rp_node}" }} ] }}
}}) {{
__typename
... on ArtProjectType {{
id
artist
artStyle
dependencies {{
totalCount
edges {{
node {{
__typename
id
}}
}}
}}
dependants {{
totalCount
edges {{
node {{
__typename
id
}}
}}
}}
}}
}}
}}
"""

# Fetch the current project
result = schema.execute_sync(query)
assert not result.errors
assert result.data == {
"node": {
"__typename": "ArtProjectType",
"id": str(ap_node),
"artist": ap.artist,
"artStyle": ap.art_style,
"dependencies": {"totalCount": 0, "edges": []},
"dependants": {"totalCount": 0, "edges": []},
}
}

# Update with _new_ project dependencies
result = schema.execute_sync(mutation)
assert not result.errors
assert result.data == {
"updateArtProject": {
"__typename": "ArtProjectType",
"id": str(ap_node),
"artist": ap.artist,
"artStyle": ap.art_style,
"dependencies": {
"totalCount": 2,
"edges": [
{"node": {"__typename": "SoftwareProjectType", "id": str(sp_node)}},
{
"node": {
"__typename": "EngineeringProjectType",
"id": str(ep_node),
}
},
],
},
"dependants": {
"totalCount": 1,
"edges": [
{"node": {"__typename": "ResearchProjectType", "id": str(rp_node)}}
],
},
}
}

# Update _existing_ project dependencies (no change)
result = schema.execute_sync(mutation)
assert not result.errors
assert result.data == {
"updateArtProject": {
"__typename": "ArtProjectType",
"id": str(ap_node),
"artist": ap.artist,
"artStyle": ap.art_style,
"dependencies": {
"totalCount": 2, # The existing dependencies remain on the connection
"edges": [
{"node": {"__typename": "SoftwareProjectType", "id": str(sp_node)}},
{
"node": {
"__typename": "EngineeringProjectType",
"id": str(ep_node),
}
},
],
},
"dependants": {
"totalCount": 1, # The existing dependants remain on the connection
"edges": [
{"node": {"__typename": "ResearchProjectType", "id": str(rp_node)}}
],
},
}
}
Loading