Skip to content

Commit 7113a05

Browse files
authored
Implement the Relay Global Object Identification Specification (#1585)
1 parent cd7b8de commit 7113a05

File tree

19 files changed

+387
-205
lines changed

19 files changed

+387
-205
lines changed

features/graphql/collection.feature

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,92 @@
11
Feature: GraphQL collection support
2+
@createSchema
3+
@dropSchema
4+
Scenario: Retrieve a collection through a GraphQL query
5+
Given there is 4 dummy objects with relatedDummy and its thirdLevel
6+
When I send the following GraphQL request:
7+
"""
8+
{
9+
dummies {
10+
...dummyFields
11+
}
12+
}
13+
fragment dummyFields on DummyConnection {
14+
edges {
15+
node {
16+
id
17+
name
18+
relatedDummy {
19+
name
20+
thirdLevel {
21+
id
22+
level
23+
}
24+
}
25+
}
26+
}
27+
}
28+
"""
29+
Then the response status code should be 200
30+
And the response should be in JSON
31+
And the header "Content-Type" should be equal to "application/json"
32+
And the JSON node "data.dummies.edges[2].node.name" should be equal to "Dummy #3"
33+
And the JSON node "data.dummies.edges[2].node.relatedDummy.name" should be equal to "RelatedDummy #3"
34+
And the JSON node "data.dummies.edges[2].node.relatedDummy.thirdLevel.level" should be equal to "3"
35+
36+
@createSchema
37+
@dropSchema
38+
Scenario: Retrieve an nonexistent collection through a GraphQL query
39+
When I send the following GraphQL request:
40+
"""
41+
{
42+
dummies {
43+
edges {
44+
node {
45+
name
46+
}
47+
}
48+
pageInfo {
49+
endCursor
50+
hasNextPage
51+
}
52+
}
53+
}
54+
"""
55+
Then the response status code should be 200
56+
And the response should be in JSON
57+
And the header "Content-Type" should be equal to "application/json"
58+
And the JSON node "data.dummies.edges" should have 0 element
59+
And the JSON node "data.dummies.pageInfo.endCursor" should be null
60+
And the JSON node "data.dummies.pageInfo.hasNextPage" should be false
61+
62+
@createSchema
63+
@dropSchema
64+
Scenario: Retrieve a collection with a nested collection through a GraphQL query
65+
Given there is 4 dummy objects having each 3 relatedDummies
66+
When I send the following GraphQL request:
67+
"""
68+
{
69+
dummies {
70+
edges {
71+
node {
72+
name
73+
relatedDummies {
74+
edges {
75+
node {
76+
name
77+
}
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
"""
85+
Then the response status code should be 200
86+
And the response should be in JSON
87+
And the header "Content-Type" should be equal to "application/json"
88+
And the JSON node "data.dummies.edges[2].node.name" should be equal to "Dummy #3"
89+
And the JSON node "data.dummies.edges[2].node.relatedDummies.edges[1].node.name" should be equal to "RelatedDummy23"
290

391
@createSchema
492
@dropSchema

features/graphql/introspection.feature

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,91 @@ Feature: GraphQL introspection support
8383
And the JSON node "data.type3.fields[1].name" should be equal to "cursor"
8484
And the JSON node "data.type3.fields[0].type.name" should be equal to "DummyAggregateOffer"
8585

86+
Scenario: Retrieve the Relay's node interface
87+
When I send the following GraphQL request:
88+
"""
89+
{
90+
__type(name: "Node") {
91+
name
92+
kind
93+
fields {
94+
name
95+
type {
96+
kind
97+
ofType {
98+
name
99+
kind
100+
}
101+
}
102+
}
103+
}
104+
}
105+
"""
106+
Then the response status code should be 200
107+
And the response should be in JSON
108+
And the header "Content-Type" should be equal to "application/json"
109+
And the JSON should be deep equal to:
110+
"""
111+
{
112+
"data": {
113+
"__type": {
114+
"name": "Node",
115+
"kind": "INTERFACE",
116+
"fields": [
117+
{
118+
"name": "id",
119+
"type": {
120+
"kind": "NON_NULL",
121+
"ofType": {
122+
"name": "ID",
123+
"kind": "SCALAR"
124+
}
125+
}
126+
}
127+
]
128+
}
129+
}
130+
}
131+
"""
132+
133+
Scenario: Retrieve the Relay's node field
134+
When I send the following GraphQL request:
135+
"""
136+
{
137+
__schema {
138+
queryType {
139+
fields {
140+
name
141+
type {
142+
name
143+
kind
144+
}
145+
args {
146+
name
147+
type {
148+
kind
149+
ofType {
150+
name
151+
kind
152+
}
153+
}
154+
}
155+
}
156+
}
157+
}
158+
}
159+
"""
160+
Then the response status code should be 200
161+
And the response should be in JSON
162+
And the header "Content-Type" should be equal to "application/json"
163+
And the JSON node "data.__schema.queryType.fields[0].name" should be equal to "node"
164+
And the JSON node "data.__schema.queryType.fields[0].type.name" should be equal to "Node"
165+
And the JSON node "data.__schema.queryType.fields[0].type.kind" should be equal to "INTERFACE"
166+
And the JSON node "data.__schema.queryType.fields[0].args[0].name" should be equal to "id"
167+
And the JSON node "data.__schema.queryType.fields[0].args[0].type.kind" should be equal to "NON_NULL"
168+
And the JSON node "data.__schema.queryType.fields[0].args[0].type.ofType.name" should be equal to "ID"
169+
And the JSON node "data.__schema.queryType.fields[0].args[0].type.ofType.kind" should be equal to "SCALAR"
170+
86171
@dropSchema
87172
Scenario: Retrieve an item through a GraphQL query
88173
Given there is 4 dummy objects with relatedDummy

features/graphql/query.feature

Lines changed: 37 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
11
Feature: GraphQL query support
2-
32
@createSchema
4-
@dropSchema
5-
Scenario: Retrieve an item through a GraphQL query with variables
3+
Scenario: Execute a basic GraphQL query
64
Given there is 2 dummy objects with relatedDummy
5+
When I send the following GraphQL request:
6+
"""
7+
{
8+
dummy(id: "/dummies/1") {
9+
id
10+
name
11+
}
12+
}
13+
"""
14+
Then the response status code should be 200
15+
And the response should be in JSON
16+
And the header "Content-Type" should be equal to "application/json"
17+
And the JSON node "data.dummy.id" should be equal to "/dummies/1"
18+
And the JSON node "data.dummy.name" should be equal to "Dummy #1"
19+
20+
Scenario: Retrieve a Relay Node
21+
When I send the following GraphQL request:
22+
"""
23+
{
24+
node(id: "/dummies/1") {
25+
id
26+
... on Dummy {
27+
name
28+
}
29+
}
30+
}
31+
"""
32+
Then the response status code should be 200
33+
And the response should be in JSON
34+
And the header "Content-Type" should be equal to "application/json"
35+
And the JSON node "data.node.id" should be equal to "/dummies/1"
36+
And the JSON node "data.node.name" should be equal to "Dummy #1"
37+
38+
Scenario: Retrieve an item through a GraphQL query with variables
739
When I have the following GraphQL request:
840
"""
941
query DummyWithId($itemId: ID = "/dummies/1") {
@@ -17,7 +49,7 @@ Feature: GraphQL query support
1749
}
1850
}
1951
"""
20-
When I send the GraphQL request with variables:
52+
And I send the GraphQL request with variables:
2153
"""
2254
{
2355
"itemId": "/dummies/2"
@@ -31,10 +63,7 @@ Feature: GraphQL query support
3163
And the JSON node "data.dummyItem.relatedDummy.id" should be equal to "/related_dummies/2"
3264
And the JSON node "data.dummyItem.relatedDummy.name" should be equal to "RelatedDummy #2"
3365

34-
@createSchema
35-
@dropSchema
3666
Scenario: Run a specific operation through a GraphQL query
37-
Given there is 2 dummy objects
3867
When I have the following GraphQL request:
3968
"""
4069
query DummyWithId1 {
@@ -58,14 +87,12 @@ Feature: GraphQL query support
5887
And I send the GraphQL request with operation "DummyWithId1"
5988
And the JSON node "data.dummyItem.name" should be equal to "Dummy #1"
6089

61-
@createSchema
6290
@dropSchema
6391
Scenario: Retrieve an nonexistent item through a GraphQL query
64-
Given there is 1 dummy objects
6592
When I send the following GraphQL request:
6693
"""
6794
{
68-
dummy(id: "/dummies/2") {
95+
dummy(id: "/dummies/5") {
6996
name
7097
}
7198
}
@@ -74,92 +101,3 @@ Feature: GraphQL query support
74101
And the response should be in JSON
75102
And the header "Content-Type" should be equal to "application/json"
76103
And the JSON node "data.dummy" should be null
77-
78-
@createSchema
79-
@dropSchema
80-
Scenario: Retrieve a collection through a GraphQL query
81-
Given there is 4 dummy objects with relatedDummy and its thirdLevel
82-
When I send the following GraphQL request:
83-
"""
84-
{
85-
dummies {
86-
...dummyFields
87-
}
88-
}
89-
fragment dummyFields on DummyConnection {
90-
edges {
91-
node {
92-
id
93-
name
94-
relatedDummy {
95-
name
96-
thirdLevel {
97-
id
98-
level
99-
}
100-
}
101-
}
102-
}
103-
}
104-
"""
105-
Then the response status code should be 200
106-
And the response should be in JSON
107-
And the header "Content-Type" should be equal to "application/json"
108-
And the JSON node "data.dummies.edges[2].node.name" should be equal to "Dummy #3"
109-
And the JSON node "data.dummies.edges[2].node.relatedDummy.name" should be equal to "RelatedDummy #3"
110-
And the JSON node "data.dummies.edges[2].node.relatedDummy.thirdLevel.level" should be equal to "3"
111-
112-
@createSchema
113-
@dropSchema
114-
Scenario: Retrieve an nonexistent collection through a GraphQL query
115-
When I send the following GraphQL request:
116-
"""
117-
{
118-
dummies {
119-
edges {
120-
node {
121-
name
122-
}
123-
}
124-
pageInfo {
125-
endCursor
126-
hasNextPage
127-
}
128-
}
129-
}
130-
"""
131-
Then the response status code should be 200
132-
And the response should be in JSON
133-
And the header "Content-Type" should be equal to "application/json"
134-
And the JSON node "data.dummies.edges" should have 0 element
135-
And the JSON node "data.dummies.pageInfo.endCursor" should be null
136-
And the JSON node "data.dummies.pageInfo.hasNextPage" should be false
137-
138-
@createSchema
139-
@dropSchema
140-
Scenario: Retrieve a collection with a nested collection through a GraphQL query
141-
Given there is 4 dummy objects having each 3 relatedDummies
142-
When I send the following GraphQL request:
143-
"""
144-
{
145-
dummies {
146-
edges {
147-
node {
148-
name
149-
relatedDummies {
150-
edges {
151-
node {
152-
name
153-
}
154-
}
155-
}
156-
}
157-
}
158-
}
159-
}
160-
"""
161-
Then the response status code should be 200
162-
And the response should be in JSON
163-
And the header "Content-Type" should be equal to "application/json"
164-
And the JSON node "data.dummies.edges[2].node.name" should be equal to "Dummy #3"
165-
And the JSON node "data.dummies.edges[2].node.relatedDummies.edges[1].node.name" should be equal to "RelatedDummy23"

src/Bridge/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<!-- Resolvers -->
1111

12-
<service id="api_platform.graphql.resolver.collection_factory" class="ApiPlatform\Core\Graphql\Resolver\CollectionResolverFactory" public="false">
12+
<service id="api_platform.graphql.resolver.factory.collection" class="ApiPlatform\Core\Graphql\Resolver\Factory\CollectionResolverFactory" public="false">
1313
<argument type="service" id="api_platform.collection_data_provider" />
1414
<argument type="service" id="api_platform.subresource_data_provider" />
1515
<argument type="service" id="serializer" />
@@ -19,15 +19,15 @@
1919
<argument>%api_platform.collection.pagination.enabled%</argument>
2020
</service>
2121

22-
<service id="api_platform.graphql.resolver.item_factory" class="ApiPlatform\Core\Graphql\Resolver\ItemResolverFactory" public="false">
22+
<service id="api_platform.graphql.resolver.factory.item_mutation" class="ApiPlatform\Core\Graphql\Resolver\Factory\ItemMutationResolverFactory" public="false">
2323
<argument type="service" id="api_platform.iri_converter" />
24+
<argument type="service" id="api_platform.data_persister" />
2425
<argument type="service" id="serializer" />
2526
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
2627
</service>
2728

28-
<service id="api_platform.graphql.resolver.item_mutation_factory" class="ApiPlatform\Core\Graphql\Resolver\ItemMutationResolverFactory" public="false">
29+
<service id="api_platform.graphql.resolver.item" class="ApiPlatform\Core\Graphql\Resolver\ItemResolver" public="false">
2930
<argument type="service" id="api_platform.iri_converter" />
30-
<argument type="service" id="api_platform.data_persister" />
3131
<argument type="service" id="serializer" />
3232
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
3333
</service>
@@ -41,9 +41,9 @@
4141
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
4242
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
4343
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
44-
<argument type="service" id="api_platform.graphql.resolver.collection_factory" />
45-
<argument type="service" id="api_platform.graphql.resolver.item_factory" />
46-
<argument type="service" id="api_platform.graphql.resolver.item_mutation_factory" />
44+
<argument type="service" id="api_platform.graphql.resolver.factory.collection" />
45+
<argument type="service" id="api_platform.graphql.resolver.factory.item_mutation" />
46+
<argument type="service" id="api_platform.graphql.resolver.item" />
4747
<argument type="service" id="api_platform.graphql.resolver.resource_field" />
4848
<argument>%api_platform.collection.pagination.enabled%</argument>
4949
</service>

0 commit comments

Comments
 (0)