Skip to content

Commit 0ec68c0

Browse files
authored
Merge pull request #1732 from antograssiot/custom-operation-configuration
Ease custom operation configuration
2 parents 8be05ae + 142b23d commit 0ec68c0

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

features/main/custom_operation.feature

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,45 @@ Feature: Custom operation
2626
"foo": "foo"
2727
}
2828
"""
29+
30+
Scenario: Custom normalization operation with shorthand configuration
31+
When I send a "POST" request to "/short_custom/denormalization"
32+
And I add "Content-Type" header equal to "application/ld+json"
33+
Then the JSON should be equal to:
34+
"""
35+
{
36+
"@context": "/contexts/CustomActionDummy",
37+
"@id": "/custom_action_dummies/2",
38+
"@type": "CustomActionDummy",
39+
"id": 2,
40+
"foo": "short declaration"
41+
}
42+
"""
43+
44+
Scenario: Custom normalization operation with shorthand configuration
45+
When I send a "GET" request to "/short_custom/2/normalization"
46+
Then the JSON should be equal to:
47+
"""
48+
{
49+
"id": 2,
50+
"foo": "short"
51+
}
52+
"""
53+
54+
Scenario: Custom collection name without specific route
55+
When I send a "GET" request to "/custom_action_collection_dummies"
56+
Then the response status code should be 200
57+
Then the JSON node "hydra:member" should have 2 elements
58+
59+
Scenario: Custom operation name without specific route
60+
When I send a "GET" request to "/custom_action_collection_dummies/1"
61+
Then the JSON should be equal to:
62+
"""
63+
{
64+
"@context": "/contexts/CustomActionDummy",
65+
"@id": "/custom_action_dummies/1",
66+
"@type": "CustomActionDummy",
67+
"id": 1,
68+
"foo": "custom!"
69+
}
70+
"""

src/Metadata/Resource/Factory/OperationResourceMetadataFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ private function normalize(bool $collection, ResourceMetadata $resourceMetadata,
121121

122122
if ($supported && !isset($operation['method']) && !isset($operation['route_name'])) {
123123
$operation['method'] = $upperOperationName;
124+
} elseif (!$supported && !isset($operation['method']) && !isset($operation['route_name'])) {
125+
$operation['route_name'] = $operationName;
124126
}
125127

126128
$newOperations[$operationName] = $operation;

tests/Fixtures/TestBundle/Controller/CustomActionController.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,43 @@ public function customDenormalizationAction(Request $request)
6262

6363
return $object;
6464
}
65+
66+
/**
67+
* @Route(
68+
* name="short_custom_normalization",
69+
* path="/short_custom/{id}/normalization",
70+
* defaults={"_api_resource_class"=CustomActionDummy::class, "_api_item_operation_name"="custom_normalization"}
71+
* )
72+
* @Method("GET")
73+
*/
74+
public function shortCustomNormalizationAction(CustomActionDummy $data)
75+
{
76+
$data->setFoo('short');
77+
78+
return $this->json($data);
79+
}
80+
81+
/**
82+
* @Route(
83+
* name="short_custom_denormalization",
84+
* path="/short_custom/denormalization",
85+
* defaults={
86+
* "_api_resource_class"=CustomActionDummy::class,
87+
* "_api_collection_operation_name"="custom_denormalization",
88+
* "_api_receive"=false
89+
* }
90+
* )
91+
* @Method("POST")
92+
*/
93+
public function shortCustomDenormalizationAction(Request $request)
94+
{
95+
if ($request->attributes->has('data')) {
96+
throw new \RuntimeException('The "data" attribute must not be set.');
97+
}
98+
99+
$object = new CustomActionDummy();
100+
$object->setFoo('short declaration');
101+
102+
return $object;
103+
}
65104
}

tests/Fixtures/TestBundle/Entity/CustomActionDummy.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020
* @ORM\Entity
2121
* @ApiResource(itemOperations={
2222
* "get",
23-
* "custom_normalization"={"route_name"="custom_normalization"}
23+
* "get_custom"={"method"="GET", "path"="custom_action_collection_dummies/{id}"},
24+
* "custom_normalization"={"route_name"="custom_normalization"},
25+
* "short_custom_normalization",
2426
* }, collectionOperations={
2527
* "get",
26-
* "custom_denormalization"={"route_name"="custom_denormalization"}
28+
* "get_custom"={"method"="GET", "path"="custom_action_collection_dummies"},
29+
* "custom_denormalization"={"route_name"="custom_denormalization"},
30+
* "short_custom_denormalization",
2731
* })
2832
*
2933
* @author Kévin Dunglas <[email protected]>

tests/Metadata/Resource/Factory/OperationResourceMetadataFactoryTest.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ public function getMetadata()
4646
[new ResourceMetadata(null, null, null, ['get'], [], null, [], []), new ResourceMetadata(null, null, null, ['get' => ['method' => 'GET']], [], null, [], [])],
4747
[new ResourceMetadata(null, null, null, ['put'], [], null, [], []), new ResourceMetadata(null, null, null, ['put' => ['method' => 'PUT']], [], null, [], [])],
4848
[new ResourceMetadata(null, null, null, ['delete'], [], null, [], []), new ResourceMetadata(null, null, null, ['delete' => ['method' => 'DELETE']], [], null, [], [])],
49-
[new ResourceMetadata(null, null, null, ['patch'], [], null, [], []), new ResourceMetadata(null, null, null, ['patch' => []], [], null, [], [])],
49+
[new ResourceMetadata(null, null, null, ['patch'], [], null, [], []), new ResourceMetadata(null, null, null, ['patch' => ['route_name' => 'patch']], [], null, [], [])],
5050
[new ResourceMetadata(null, null, null, ['patch'], [], null, [], []), new ResourceMetadata(null, null, null, ['patch' => ['method' => 'PATCH']], [], null, [], []), $jsonapi],
51+
[new ResourceMetadata(null, null, null, ['untouched' => ['method' => 'GET']], [], null, [], []), new ResourceMetadata(null, null, null, ['untouched' => ['method' => 'GET']], [], null, [], []), $jsonapi],
52+
[new ResourceMetadata(null, null, null, ['untouched_custom' => ['route_name' => 'custom_route']], [], null, [], []), new ResourceMetadata(null, null, null, ['untouched_custom' => ['route_name' => 'custom_route']], [], null, [], []), $jsonapi],
5153

5254
// Collection operations
5355
[new ResourceMetadata(null, null, null, [], null, null, [], []), new ResourceMetadata(null, null, null, [], ['get' => ['method' => 'GET'], 'post' => ['method' => 'POST']], null, [], [])],
5456
[new ResourceMetadata(null, null, null, [], ['get'], null, [], []), new ResourceMetadata(null, null, null, [], ['get' => ['method' => 'GET']], null, [], [])],
5557
[new ResourceMetadata(null, null, null, [], ['post'], null, [], []), new ResourceMetadata(null, null, null, [], ['post' => ['method' => 'POST']], null, [], [])],
56-
[new ResourceMetadata(null, null, null, [], ['options'], null, [], []), new ResourceMetadata(null, null, null, [], ['options' => []], null, [], [])],
58+
[new ResourceMetadata(null, null, null, [], ['options'], null, [], []), new ResourceMetadata(null, null, null, [], ['options' => ['route_name' => 'options']], null, [], [])],
59+
[new ResourceMetadata(null, null, null, [], ['untouched' => ['method' => 'GET']], null, [], []), new ResourceMetadata(null, null, null, [], ['untouched' => ['method' => 'GET']], null, [], [])],
60+
[new ResourceMetadata(null, null, null, [], ['untouched_custom' => ['route_name' => 'custom_route']], null, [], []), new ResourceMetadata(null, null, null, [], ['untouched_custom' => ['route_name' => 'custom_route']], null, [], [])],
5761
];
5862
}
5963
}

0 commit comments

Comments
 (0)