Skip to content

Commit 9aba732

Browse files
authored
Disable some steps by setting operation attributes (#2944)
1 parent a235327 commit 9aba732

22 files changed

+728
-23
lines changed

features/graphql/collection.feature

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,35 @@ Feature: GraphQL collection support
517517
}
518518
"""
519519

520+
@createSchema
521+
Scenario: Custom collection query with read and serialize set to false
522+
Given there are 2 dummyCustomQuery objects
523+
When I send the following GraphQL request:
524+
"""
525+
{
526+
testCollectionNoReadAndSerializeDummyCustomQueries {
527+
edges {
528+
node {
529+
message
530+
}
531+
}
532+
}
533+
}
534+
"""
535+
Then the response status code should be 200
536+
And the response should be in JSON
537+
And the header "Content-Type" should be equal to "application/json"
538+
And the JSON should be equal to:
539+
"""
540+
{
541+
"data": {
542+
"testCollectionNoReadAndSerializeDummyCustomQueries": {
543+
"edges": []
544+
}
545+
}
546+
}
547+
"""
548+
520549
@createSchema
521550
Scenario: Custom collection query with custom arguments
522551
Given there are 2 dummyCustomQuery objects

features/graphql/mutation.feature

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ Feature: GraphQL mutation support
459459
And the header "Content-Type" should be equal to "application/json"
460460
And the JSON node "data.sumDummyCustomMutation.dummyCustomMutation.result" should be equal to "8"
461461

462-
Scenario: Execute a not persisted custom mutation
462+
Scenario: Execute a not persisted custom mutation (resolver returns null)
463463
When I send the following GraphQL request:
464464
"""
465465
mutation {
@@ -476,6 +476,40 @@ Feature: GraphQL mutation support
476476
And the header "Content-Type" should be equal to "application/json"
477477
And the JSON node "data.sumNotPersistedDummyCustomMutation.dummyCustomMutation" should be null
478478

479+
Scenario: Execute a not persisted custom mutation (write set to false) with custom result
480+
When I send the following GraphQL request:
481+
"""
482+
mutation {
483+
sumNoWriteCustomResultDummyCustomMutation(input: {id: "/dummy_custom_mutations/1", operandB: 5}) {
484+
dummyCustomMutation {
485+
id
486+
result
487+
}
488+
}
489+
}
490+
"""
491+
Then the response status code should be 200
492+
And the response should be in JSON
493+
And the header "Content-Type" should be equal to "application/json"
494+
And the JSON node "data.sumNoWriteCustomResultDummyCustomMutation.dummyCustomMutation.result" should be equal to "1234"
495+
496+
Scenario: Execute a custom mutation with read, deserialize, validate and serialize set to false
497+
When I send the following GraphQL request:
498+
"""
499+
mutation {
500+
sumOnlyPersistDummyCustomMutation(input: {id: "/dummy_custom_mutations/1", operandB: 5}) {
501+
dummyCustomMutation {
502+
id
503+
result
504+
}
505+
}
506+
}
507+
"""
508+
Then the response status code should be 200
509+
And the response should be in JSON
510+
And the header "Content-Type" should be equal to "application/json"
511+
And the JSON node "data.sumOnlyPersistDummyCustomMutation.dummyCustomMutation" should be null
512+
479513
Scenario: Execute a custom mutation with custom arguments
480514
When I send the following GraphQL request:
481515
"""

features/graphql/query.feature

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,27 @@ Feature: GraphQL query support
307307
}
308308
"""
309309

310+
Scenario: Custom item query with read and serialize set to false
311+
When I send the following GraphQL request:
312+
"""
313+
{
314+
testNoReadAndSerializeItemDummyCustomQuery(id: "/not_used") {
315+
message
316+
}
317+
}
318+
"""
319+
Then the response status code should be 200
320+
And the response should be in JSON
321+
And the header "Content-Type" should be equal to "application/json"
322+
And the JSON should be equal to:
323+
"""
324+
{
325+
"data": {
326+
"testNoReadAndSerializeItemDummyCustomQuery": null
327+
}
328+
}
329+
"""
330+
310331
Scenario: Custom item query
311332
Given there are 2 dummyCustomQuery objects
312333
When I send the following GraphQL request:

src/GraphQl/Resolver/Factory/CollectionResolverFactory.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,19 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
8585
$dataProviderContext['graphql'] = true;
8686
$normalizationContext['resource_class'] = $resourceClass;
8787

88-
if (isset($rootClass, $source[$rootProperty = $info->fieldName], $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY])) {
89-
$rootResolvedFields = $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY];
90-
$subresourceCollection = $this->getSubresource($rootClass, $rootResolvedFields, array_keys($rootResolvedFields), $rootProperty, $resourceClass, true, $dataProviderContext);
91-
if (!is_iterable($subresourceCollection)) {
92-
throw new \UnexpectedValueException('Expected subresource collection to be iterable');
88+
$collection = [];
89+
90+
if ($resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'read', true, true)) {
91+
if (isset($rootClass, $source[$rootProperty = $info->fieldName], $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY])) {
92+
$rootResolvedFields = $source[ItemNormalizer::ITEM_IDENTIFIERS_KEY];
93+
$subresourceCollection = $this->getSubresource($rootClass, $rootResolvedFields, array_keys($rootResolvedFields), $rootProperty, $resourceClass, true, $dataProviderContext);
94+
if (!is_iterable($subresourceCollection)) {
95+
throw new \UnexpectedValueException('Expected subresource collection to be iterable');
96+
}
97+
$collection = $subresourceCollection ?? [];
98+
} else {
99+
$collection = $this->collectionDataProvider->getCollection($resourceClass, null, $dataProviderContext);
93100
}
94-
$collection = $subresourceCollection ?? [];
95-
} else {
96-
$collection = $this->collectionDataProvider->getCollection($resourceClass, null, $dataProviderContext);
97101
}
98102

99103
$queryResolverId = $resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'collection_query');
@@ -109,6 +113,10 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
109113
], $operationName ?? 'query');
110114

111115
if (!$this->paginationEnabled) {
116+
if (!$resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'serialize', true, true)) {
117+
return [];
118+
}
119+
112120
$data = [];
113121
foreach ($collection as $index => $object) {
114122
$data[$index] = $this->normalizer->normalize($object, ItemNormalizer::FORMAT, $normalizationContext);
@@ -144,6 +152,11 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
144152
$offset = 0 > $offset ? 0 : $offset;
145153

146154
$data = ['totalCount' => 0., 'edges' => [], 'pageInfo' => ['startCursor' => null, 'endCursor' => null, 'hasNextPage' => false, 'hasPreviousPage' => false]];
155+
156+
if (!$resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'serialize', true, true)) {
157+
return $data;
158+
}
159+
147160
if ($collection instanceof PaginatorInterface && ($totalItems = $collection->getTotalItems()) > 0) {
148161
$data['totalCount'] = $totalItems;
149162
$data['pageInfo']['startCursor'] = base64_encode((string) $offset);

src/GraphQl/Resolver/Factory/ItemMutationResolverFactory.php

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
8989
$normalizationContext = $baseNormalizationContext;
9090
$normalizationContext['resource_class'] = $resourceClass;
9191

92-
if (isset($args['input']['id'])) {
92+
if (isset($args['input']['id']) && $resourceMetadata->getGraphqlAttribute($operationName, 'read', true, true)) {
9393
try {
9494
$item = $this->iriConverter->getItemFromIri($args['input']['id'], $baseNormalizationContext);
9595
} catch (ItemNotFoundException $e) {
@@ -123,10 +123,14 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
123123
'previous_object' => $previousItem,
124124
], $operationName);
125125

126-
$data[$wrapFieldName]['id'] = null;
127-
if ($item) {
126+
if ($item && $resourceMetadata->getGraphqlAttribute($operationName, 'write', true, true)) {
128127
$this->dataPersister->remove($item);
128+
}
129+
130+
if ($resourceMetadata->getGraphqlAttribute($operationName, 'serialize', true, true)) {
129131
$data[$wrapFieldName]['id'] = $args['input']['id'];
132+
133+
return $data;
130134
}
131135

132136
return $data;
@@ -137,7 +141,9 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
137141
$denormalizationContext['object_to_populate'] = $item;
138142
}
139143
$denormalizationContext += $resourceMetadata->getGraphqlAttribute($operationName, 'denormalization_context', [], true);
140-
$item = $this->normalizer->denormalize($args['input'], $inputClass ?: $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);
144+
if ($resourceMetadata->getGraphqlAttribute($operationName, 'deserialize', true, true)) {
145+
$item = $this->normalizer->denormalize($args['input'], $inputClass ?: $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);
146+
}
141147

142148
$mutationResolverId = $resourceMetadata->getGraphqlAttribute($operationName, 'mutation');
143149
if (null !== $mutationResolverId) {
@@ -155,15 +161,24 @@ public function __invoke(string $resourceClass = null, string $rootClass = null,
155161
], $operationName);
156162

157163
if (null !== $item) {
158-
$this->validate($item, $info, $resourceMetadata, $operationName);
164+
if ($resourceMetadata->getGraphqlAttribute($operationName, 'validate', true, true)) {
165+
$this->validate($item, $info, $resourceMetadata, $operationName);
166+
}
167+
168+
if ($resourceMetadata->getGraphqlAttribute($operationName, 'write', true, true)) {
169+
$persistResult = $this->dataPersister->persist($item, $denormalizationContext);
159170

160-
$persistResult = $this->dataPersister->persist($item, $denormalizationContext);
161-
if (!\is_object($persistResult)) {
162-
@trigger_error(sprintf('Not returning an object from %s::persist() is deprecated since API Platform 2.3 and will not be supported in API Platform 3.', DataPersisterInterface::class), E_USER_DEPRECATED);
171+
if (!\is_object($persistResult)) {
172+
@trigger_error(sprintf('Not returning an object from %s::persist() is deprecated since API Platform 2.3 and will not be supported in API Platform 3.', DataPersisterInterface::class), E_USER_DEPRECATED);
173+
}
163174
}
164175
}
165176

166-
return [$wrapFieldName => $this->normalizer->normalize($persistResult ?? $item, ItemNormalizer::FORMAT, $normalizationContext)] + $data;
177+
if ($resourceMetadata->getGraphqlAttribute($operationName, 'serialize', true, true)) {
178+
return [$wrapFieldName => $this->normalizer->normalize($persistResult ?? $item, ItemNormalizer::FORMAT, $normalizationContext)] + $data;
179+
}
180+
181+
return $data;
167182
};
168183
}
169184

src/GraphQl/Resolver/Factory/ItemResolverFactory.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,17 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
6464
return $source[$info->fieldName];
6565
}
6666

67-
$baseNormalizationContext = ['attributes' => $this->fieldsToAttributes($info)];
68-
$item = $this->getItem($args, $baseNormalizationContext);
67+
$item = null;
6968
$resourceClass = $this->getResourceClass($item, $resourceClass, $info);
69+
$resourceMetadata = $resourceClass ? $this->resourceMetadataFactory->create($resourceClass) : null;
70+
$baseNormalizationContext = ['attributes' => $this->fieldsToAttributes($info)];
7071

71-
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
72+
if (!$resourceMetadata || $resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'read', true, true)) {
73+
$item = $this->getItem($args, $baseNormalizationContext);
74+
75+
$resourceClass = $this->getResourceClass($item, $resourceClass, $info);
76+
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
77+
}
7278

7379
$queryResolverId = $resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'item_query');
7480
if (null !== $queryResolverId) {
@@ -86,7 +92,11 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
8692
$normalizationContext = $resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'normalization_context', [], true);
8793
$normalizationContext['resource_class'] = $resourceClass;
8894

89-
return $this->normalizer->normalize($item, ItemNormalizer::FORMAT, $normalizationContext + $baseNormalizationContext);
95+
if ($resourceMetadata->getGraphqlAttribute($operationName ?? 'query', 'serialize', true, true)) {
96+
return $this->normalizer->normalize($item, ItemNormalizer::FORMAT, $normalizationContext + $baseNormalizationContext);
97+
}
98+
99+
return null;
90100
};
91101
}
92102

tests/Fixtures/TestBundle/Document/DummyCustomMutation.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@
3232
* "normalization_context"={"groups"={"result"}},
3333
* "denormalization_context"={"groups"={"sum"}}
3434
* },
35+
* "sumNoWriteCustomResult"={
36+
* "mutation"="app.graphql.mutation_resolver.dummy_custom_no_write_custom_result",
37+
* "normalization_context"={"groups"={"result"}},
38+
* "denormalization_context"={"groups"={"sum"}},
39+
* "write"=false
40+
* },
41+
* "sumOnlyPersist"={
42+
* "mutation"="app.graphql.mutation_resolver.dummy_custom_only_persist_document",
43+
* "normalization_context"={"groups"={"result"}},
44+
* "denormalization_context"={"groups"={"sum"}},
45+
* "read"=false,
46+
* "deserialize"=false,
47+
* "validate"=false,
48+
* "serialize"=false
49+
* },
3550
* "testCustomArguments"={
3651
* "mutation"="app.graphql.mutation_resolver.dummy_custom",
3752
* "args"={"operandC"={"type"="Int!"}}

tests/Fixtures/TestBundle/Document/DummyCustomQuery.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
* "item_query"="app.graphql.query_resolver.dummy_custom_not_retrieved_item_document",
3030
* "args"={}
3131
* },
32+
* "testNoReadAndSerializeItem"={
33+
* "item_query"="app.graphql.query_resolver.dummy_custom_item_no_read_and_serialize_document",
34+
* "read"=false,
35+
* "serialize"=false
36+
* },
3237
* "testItemCustomArguments"={
3338
* "item_query"="app.graphql.query_resolver.dummy_custom_item",
3439
* "args"={
@@ -45,6 +50,11 @@
4550
* "testCollection"={
4651
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection"
4752
* },
53+
* "testCollectionNoReadAndSerialize"={
54+
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection_no_read_and_serialize",
55+
* "read"=false,
56+
* "serialize"=false
57+
* },
4858
* "testCollectionCustomArguments"={
4959
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection",
5060
* "args"={

tests/Fixtures/TestBundle/Entity/DummyCustomMutation.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@
3232
* "normalization_context"={"groups"={"result"}},
3333
* "denormalization_context"={"groups"={"sum"}}
3434
* },
35+
* "sumNoWriteCustomResult"={
36+
* "mutation"="app.graphql.mutation_resolver.dummy_custom_no_write_custom_result",
37+
* "normalization_context"={"groups"={"result"}},
38+
* "denormalization_context"={"groups"={"sum"}},
39+
* "write"=false
40+
* },
41+
* "sumOnlyPersist"={
42+
* "mutation"="app.graphql.mutation_resolver.dummy_custom_only_persist",
43+
* "normalization_context"={"groups"={"result"}},
44+
* "denormalization_context"={"groups"={"sum"}},
45+
* "read"=false,
46+
* "deserialize"=false,
47+
* "validate"=false,
48+
* "serialize"=false
49+
* },
3550
* "testCustomArguments"={
3651
* "mutation"="app.graphql.mutation_resolver.dummy_custom",
3752
* "args"={"operandC"={"type"="Int!"}}

tests/Fixtures/TestBundle/Entity/DummyCustomQuery.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
* "item_query"="app.graphql.query_resolver.dummy_custom_not_retrieved_item",
3030
* "args"={}
3131
* },
32+
* "testNoReadAndSerializeItem"={
33+
* "item_query"="app.graphql.query_resolver.dummy_custom_item_no_read_and_serialize",
34+
* "read"=false,
35+
* "serialize"=false
36+
* },
3237
* "testItemCustomArguments"={
3338
* "item_query"="app.graphql.query_resolver.dummy_custom_item",
3439
* "args"={
@@ -45,6 +50,11 @@
4550
* "testCollection"={
4651
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection"
4752
* },
53+
* "testCollectionNoReadAndSerialize"={
54+
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection_no_read_and_serialize",
55+
* "read"=false,
56+
* "serialize"=false
57+
* },
4858
* "testCollectionCustomArguments"={
4959
* "collection_query"="app.graphql.query_resolver.dummy_custom_collection",
5060
* "args"={

0 commit comments

Comments
 (0)