Skip to content

Commit

Permalink
Make StreamField chooser blocks values nullable (#396)
Browse files Browse the repository at this point in the history
  • Loading branch information
JakubMastalerz authored Jun 20, 2024
1 parent 166e78a commit 1b29638
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

### Changed

- Make value fields nullable on `PageChooserBlock`, `SnippetChooserBlock`, `DocumentChooserBlock` and `ImageChooserBlock` ([#396](https://github.com/torchbox/wagtail-grapple/pull/396))

## [0.25.1] - 2024-04-21

### Changed
Expand Down
8 changes: 4 additions & 4 deletions grapple/types/streamfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ def register_streamfield_blocks():
from .snippets import SnippetTypes

class PageChooserBlock(graphene.ObjectType):
page = graphene.Field(get_page_interface(), required=True)
page = graphene.Field(get_page_interface(), required=False)

class Meta:
interfaces = (StreamFieldInterface,)
Expand All @@ -445,7 +445,7 @@ def resolve_page(self, info, **kwargs):
return self.value.specific

class DocumentChooserBlock(graphene.ObjectType):
document = graphene.Field(get_document_type(), required=True)
document = graphene.Field(get_document_type(), required=False)

class Meta:
interfaces = (StreamFieldInterface,)
Expand All @@ -454,7 +454,7 @@ def resolve_document(self, info, **kwargs):
return self.value

class ImageChooserBlock(graphene.ObjectType):
image = graphene.Field(get_image_type(), required=True)
image = graphene.Field(get_image_type(), required=False)

class Meta:
interfaces = (StreamFieldInterface,)
Expand All @@ -474,7 +474,7 @@ def resolve_image(self, info, **kwargs):
if SnippetObjectType is not None:

class SnippetChooserBlock(graphene.ObjectType):
snippet = graphene.Field(SnippetObjectType, required=True)
snippet = graphene.Field(SnippetObjectType, required=False)

class Meta:
interfaces = (StreamFieldInterface,)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_schema_for_page_with_graphql_interface(self):
[{"name": "CustomInterface"}, {"name": "PageInterface"}],
)

def test_schem_for_snippet_with_graphql_interface(self):
def test_schema_for_snippet_with_graphql_interface(self):
results = self.introspect_schema_by_type("Advert")
self.assertListEqual(
sorted(results["data"]["__type"]["interfaces"], key=lambda x: x["name"]),
Expand Down
60 changes: 60 additions & 0 deletions tests/test_models_types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import graphene

from django.test import TestCase
from wagtail.blocks.field_block import PageChooserBlock
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtail.snippets.blocks import SnippetChooserBlock

from grapple import registry
from grapple.actions import get_field_type
from grapple.exceptions import IllegalDeprecation
from grapple.models import (
Expand Down Expand Up @@ -183,3 +188,58 @@ def test_collection_field_required_deprecated(self):
required=True,
deprecation_reason=self.deprecation_reason,
)()


class ChooserBlocksTest(TestCase):
"""
Test that "Chooser" blocks take null values to ensure correct handling
of deleted objects referenced in these blocks.
"""

def test_snippet_chooser_block_value_field_not_required(self):
"""
Test that the SnippetChooserBlock snippet field is nullable in the
GraphQL schema.
"""
block = registry.registry.streamfield_blocks[SnippetChooserBlock]
field = block.snippet

# Check that field is not required by asserting type isn't `NonNull`
self.assertIsInstance(field, graphene.types.field.Field)
self.assertNotIsInstance(field.type, graphene.NonNull)

def test_document_chooser_block_value_field_not_required(self):
"""
Test that the DocumentChooserBlock document field is nullable in the
GraphQL schema.
"""
block = registry.registry.streamfield_blocks[DocumentChooserBlock]
field = block.document

# Check that field is not required by asserting type isn't `NonNull`
self.assertIsInstance(field, graphene.types.field.Field)
self.assertNotIsInstance(field.type, graphene.NonNull)

def test_image_chooser_block_value_field_not_required(self):
"""
Test that the ImageChooserBlock image field is nullable in the GraphQL
schema.
"""
block = registry.registry.streamfield_blocks[ImageChooserBlock]
field = block.image

# Check that field is not required by asserting type isn't `NonNull`
self.assertIsInstance(field, graphene.types.field.Field)
self.assertNotIsInstance(field.type, graphene.NonNull)

def test_page_chooser_block_value_field_not_required(self):
"""
Test that the PageChooserBlock page field is nullable in the GraphQL
schema.
"""
block = registry.registry.streamfield_blocks[PageChooserBlock]
field = block.page

# Check that field is not required by asserting type isn't `NonNull`
self.assertIsInstance(field, graphene.types.field.Field)
self.assertNotIsInstance(field.type, graphene.NonNull)

0 comments on commit 1b29638

Please sign in to comment.