Skip to content

Commit f5820d1

Browse files
committed
Restore full branch coverage for DeferStreamDirectiveOnRootField rule
Replace the unreachable final isinstance branch with an else clause and add tests for the previously uncovered branches (unrelated directives on a root field, undefined fragment spreads, inline fragments without defer, and operations whose schema lacks a matching root type).
1 parent 0b08cf3 commit f5820d1

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

src/graphql/validation/rules/defer_stream_directive_on_root_field.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING, Any
5+
from typing import TYPE_CHECKING, Any, cast
66

77
from ...error import GraphQLError
88
from ...language import (
@@ -103,8 +103,9 @@ def forbid_defer_stream(
103103
visited_fragments,
104104
)
105105
visited_fragments.add(fragment_name)
106-
elif isinstance(selection, InlineFragmentNode):
107-
defer = get_directive(selection, GraphQLDeferDirective.name)
106+
else: # the only remaining selection kind is an inline fragment
107+
inline_fragment = cast("InlineFragmentNode", selection)
108+
defer = get_directive(inline_fragment, GraphQLDeferDirective.name)
108109
if defer:
109110
self.report_error(
110111
GraphQLError(
@@ -117,6 +118,6 @@ def forbid_defer_stream(
117118
operation_type,
118119
root_type,
119120
fragments,
120-
selection.selection_set,
121+
inline_fragment.selection_set,
121122
visited_fragments,
122123
)

tests/validation/test_defer_stream_directive_on_root_field.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,57 @@ def stream_field_on_fragment_on_root_subscription_field():
341341
},
342342
],
343343
)
344+
345+
def other_directive_on_root_mutation_field():
346+
assert_valid(
347+
"""
348+
mutation {
349+
mutationField @foo {
350+
body
351+
}
352+
}
353+
"""
354+
)
355+
356+
def defer_fragment_spread_on_undefined_fragment():
357+
assert_valid(
358+
"""
359+
mutation {
360+
...undefinedFragment @defer
361+
}
362+
"""
363+
)
364+
365+
def inline_fragment_without_defer_on_root_mutation_field():
366+
assert_valid(
367+
"""
368+
mutation {
369+
... {
370+
mutationField {
371+
body
372+
}
373+
}
374+
}
375+
"""
376+
)
377+
378+
def defer_on_mutation_without_mutation_root_type():
379+
query_only_schema = build_schema(
380+
"""
381+
type Query {
382+
message: String
383+
}
384+
"""
385+
)
386+
assert_validation_errors(
387+
DeferStreamDirectiveOnRootField,
388+
"""
389+
mutation {
390+
... @defer {
391+
message
392+
}
393+
}
394+
""",
395+
[],
396+
schema=query_only_schema,
397+
)

0 commit comments

Comments
 (0)