Skip to content

Commit 90af6b1

Browse files
authored
[Fusion] Added requirement tests (#9117)
1 parent bc5a190 commit 90af6b1

File tree

50 files changed

+6098
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+6098
-1
lines changed

src/HotChocolate/Fusion-vnext/src/Fusion.Execution.Types/Directives/FieldDirectiveParser.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,19 @@ public static FieldDirective Parse(DirectiveNode directive)
3434
break;
3535

3636
case "provides":
37-
provides = Utf8GraphQLParser.Syntax.ParseSelectionSet(((StringValueNode)argument.Value).Value);
37+
var providesValue = ((StringValueNode)argument.Value).Value;
38+
provides = ParseProvidesSelectionSet(providesValue);
3839
break;
3940

4041
case "external":
4142
isExternal = ((BooleanValueNode)argument.Value).Value;
4243
break;
4344

45+
case "partial":
46+
// `partial` is the composition-time encoding for external source fields.
47+
isExternal = ((BooleanValueNode)argument.Value).Value;
48+
break;
49+
4450
default:
4551
throw new DirectiveParserException(
4652
$"The argument `{argument.Name.Value}` is not supported on @field.");
@@ -56,6 +62,20 @@ public static FieldDirective Parse(DirectiveNode directive)
5662
return new FieldDirective(new SchemaKey(schemaKey), sourceName, sourceType, provides, isExternal);
5763
}
5864

65+
private static SelectionSetNode ParseProvidesSelectionSet(string value)
66+
{
67+
try
68+
{
69+
// Fusion schemas can encode provides either as a raw selection set (`{ id }`) or as
70+
// the legacy field-set form (`id`).
71+
return Utf8GraphQLParser.Syntax.ParseSelectionSet(value);
72+
}
73+
catch (SyntaxException)
74+
{
75+
return Utf8GraphQLParser.Syntax.ParseSelectionSet($"{{ {value} }}");
76+
}
77+
}
78+
5979
public static ImmutableArray<FieldDirective> Parse(
6080
IReadOnlyList<DirectiveNode> directiveNodes)
6181
{
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
using HotChocolate.Fusion.Types;
2+
3+
namespace HotChocolate.Fusion.Planning;
4+
5+
public class EntityChainTests : FusionTestBase
6+
{
7+
[Fact]
8+
public void Complex_Entity_Call()
9+
{
10+
// arrange
11+
var schema = CreateComplexEntityCallSchema();
12+
13+
// act
14+
var plan = PlanOperation(
15+
schema,
16+
"""
17+
{
18+
topProducts {
19+
products {
20+
id
21+
price {
22+
price
23+
}
24+
}
25+
}
26+
}
27+
""");
28+
29+
// assert
30+
MatchSnapshot(plan);
31+
}
32+
33+
[Fact]
34+
public void Parent_Entity_Call_Complex()
35+
{
36+
// arrange
37+
var schema = CreateParentEntityCallComplexSchema();
38+
39+
// act
40+
var plan = PlanOperation(
41+
schema,
42+
"""
43+
query {
44+
productFromD(id: "1") {
45+
id
46+
name
47+
category {
48+
id
49+
name
50+
details
51+
}
52+
}
53+
}
54+
""");
55+
56+
// assert
57+
MatchSnapshot(plan);
58+
}
59+
60+
private static FusionSchemaDefinition CreateComplexEntityCallSchema()
61+
{
62+
return ComposeSchema(
63+
"""
64+
# name: products
65+
schema {
66+
query: Query
67+
}
68+
69+
type Query {
70+
topProducts: ProductList!
71+
}
72+
73+
type ProductList {
74+
products: [Product!]!
75+
}
76+
77+
type Product @key(fields: "id") {
78+
id: ID!
79+
category: Category! @shareable
80+
}
81+
82+
type Category {
83+
id: ID! @shareable
84+
tag: String @shareable
85+
}
86+
""",
87+
"""
88+
# name: link
89+
schema {
90+
query: Query
91+
}
92+
93+
type Query {
94+
productById(id: ID! @is(field: "id")): Product @lookup @internal
95+
}
96+
97+
type Product @key(fields: "id") {
98+
id: ID!
99+
pid: ID! @shareable
100+
}
101+
""",
102+
"""
103+
# name: price
104+
schema {
105+
query: Query
106+
}
107+
108+
type Query {
109+
productByIdPidAndCategory(
110+
id: ID! @is(field: "id")
111+
pid: ID! @is(field: "pid")
112+
categoryId: ID! @is(field: "category.id")
113+
categoryTag: String @is(field: "category.tag")): Product @lookup @internal
114+
}
115+
116+
type Product @key(fields: "id pid category { id tag }") {
117+
id: ID!
118+
pid: ID! @shareable
119+
category: Category! @shareable
120+
price: Price
121+
}
122+
123+
type Category {
124+
id: ID! @shareable
125+
tag: String @shareable
126+
}
127+
128+
type Price {
129+
price: Float!
130+
}
131+
""");
132+
}
133+
134+
private static FusionSchemaDefinition CreateParentEntityCallComplexSchema()
135+
{
136+
return ComposeSchema(
137+
"""
138+
# name: a
139+
schema {
140+
query: Query
141+
}
142+
143+
type Query {
144+
productById(id: ID! @is(field: "id")): Product @lookup @internal
145+
}
146+
147+
type Product @key(fields: "id") {
148+
id: ID!
149+
category: Category @shareable
150+
}
151+
152+
type Category {
153+
details: String
154+
}
155+
""",
156+
"""
157+
# name: b
158+
schema {
159+
query: Query
160+
}
161+
162+
type Query {
163+
productById(id: ID! @is(field: "id")): Product @lookup @internal
164+
}
165+
166+
type Product @key(fields: "id") {
167+
id: ID!
168+
category: Category @shareable
169+
}
170+
171+
type Category @key(fields: "id") {
172+
id: ID!
173+
}
174+
""",
175+
"""
176+
# name: c
177+
schema {
178+
query: Query
179+
}
180+
181+
type Query {
182+
categoryById(id: ID! @is(field: "id")): Category @lookup @internal
183+
}
184+
185+
type Category @key(fields: "id") {
186+
id: ID!
187+
name: String
188+
}
189+
""",
190+
"""
191+
# name: d
192+
schema {
193+
query: Query
194+
}
195+
196+
type Query {
197+
productFromD(id: ID!): Product
198+
productById(id: ID! @is(field: "id")): Product @lookup @internal
199+
}
200+
201+
type Product @key(fields: "id") {
202+
id: ID!
203+
name: String
204+
}
205+
""");
206+
}
207+
}

0 commit comments

Comments
 (0)