Skip to content

Commit 995fc20

Browse files
committed
Implement input/output with data transformers
Move data transform to normalizers
1 parent bb30d60 commit 995fc20

File tree

80 files changed

+2041
-317
lines changed

Some content is hidden

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

80 files changed

+2041
-317
lines changed

features/bootstrap/DoctrineContext.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyCar as DummyCarDocument;
2222
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyCarColor as DummyCarColorDocument;
2323
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyDate as DummyDateDocument;
24+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyDtoCustom as DummyDtoCustomDocument;
2425
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyDtoNoInput as DummyDtoNoInputDocument;
2526
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyDtoNoOutput as DummyDtoNoOutputDocument;
2627
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyFriend as DummyFriendDocument;
@@ -59,6 +60,7 @@
5960
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCar;
6061
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCarColor;
6162
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyDate;
63+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyDtoCustom;
6264
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyDtoNoInput;
6365
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyDtoNoOutput;
6466
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyFriend;
@@ -1182,6 +1184,36 @@ public function thereIsAMaxDepthDummyWithLevelOfDescendants(int $level)
11821184
$this->manager->flush();
11831185
}
11841186

1187+
/**
1188+
* @Given there is a DummyCustomDto
1189+
*/
1190+
public function thereIsADummyCustomDto()
1191+
{
1192+
$dto = $this->isOrm() ? new DummyDtoCustom() : new DummyDtoCustomDocument();
1193+
$dto->lorem = 'test';
1194+
$dto->ipsum = '0';
1195+
$this->manager->persist($dto);
1196+
1197+
$this->manager->flush();
1198+
$this->manager->clear();
1199+
}
1200+
1201+
/**
1202+
* @Given there are :nb DummyCustomDto
1203+
*/
1204+
public function thereAreNbDummyCustomDto($nb)
1205+
{
1206+
for ($i = 1; $i <= $nb; ++$i) {
1207+
$dto = $this->isOrm() ? new DummyDtoCustom() : new DummyDtoCustomDocument();
1208+
$dto->lorem = 'test';
1209+
$dto->ipsum = (string) $i;
1210+
$this->manager->persist($dto);
1211+
}
1212+
1213+
$this->manager->flush();
1214+
$this->manager->clear();
1215+
}
1216+
11851217
private function isOrm(): bool
11861218
{
11871219
return null !== $this->schemaTool;

features/graphql/mutation.feature

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Feature: GraphQL mutation support
2727
And the response should be in JSON
2828
And the header "Content-Type" should be equal to "application/json"
2929
And the JSON node "data.__type.fields[0].name" should contain "delete"
30-
And the JSON node "data.__type.fields[0].description" should match '/^Deletes a [A-z0-9]+\.$/'
30+
And the JSON node "data.__type.fields[0].description" should match '/^Deletes a [A-z0-9]+.$/'
3131
And the JSON node "data.__type.fields[0].type.name" should match "/^delete[A-z0-9]+Payload$/"
3232
And the JSON node "data.__type.fields[0].type.kind" should be equal to "OBJECT"
3333
And the JSON node "data.__type.fields[0].args[0].name" should be equal to "input"
@@ -310,7 +310,7 @@ Feature: GraphQL mutation support
310310
When I send the following GraphQL request:
311311
"""
312312
mutation {
313-
createDummyDtoNoInput(input: {foo: "A new one", bar: 3, clientMutationId: "myId"}) {
313+
createDummyDtoNoInput(input: {lorem: "A new one", ipsum: 3, clientMutationId: "myId"}) {
314314
clientMutationId
315315
}
316316
}
@@ -323,7 +323,19 @@ Feature: GraphQL mutation support
323323
{
324324
"errors": [
325325
{
326-
"message": "Field \"foo\" is not defined by type createDummyDtoNoInputInput.",
326+
"message": "Field createDummyDtoNoInputInput.id of required type ID! was not provided.",
327+
"extensions": {
328+
"category": "graphql"
329+
},
330+
"locations": [
331+
{
332+
"line": 2,
333+
"column": 32
334+
}
335+
]
336+
},
337+
{
338+
"message": "Field \"lorem\" is not defined by type createDummyDtoNoInputInput.",
327339
"extensions": {
328340
"category": "graphql"
329341
},
@@ -335,14 +347,14 @@ Feature: GraphQL mutation support
335347
]
336348
},
337349
{
338-
"message": "Field \"bar\" is not defined by type createDummyDtoNoInputInput.",
350+
"message": "Field \"ipsum\" is not defined by type createDummyDtoNoInputInput.",
339351
"extensions": {
340352
"category": "graphql"
341353
},
342354
"locations": [
343355
{
344356
"line": 2,
345-
"column": 51
357+
"column": 53
346358
}
347359
]
348360
}

features/jsonapi/related-resouces-inclusion.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,11 @@ Feature: JSON API Inclusion of Related Resources
363363
"dummyDate": null,
364364
"dummyBoolean": null,
365365
"embeddedDummy": {
366-
"dummyName": null,
367366
"dummyBoolean": null,
368367
"dummyDate": null,
369368
"dummyFloat": null,
370369
"dummyPrice": null,
370+
"dummyName": null,
371371
"symfony": null
372372
},
373373
"_id": 1,

features/main/input_output.feature

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
Feature: DTO input and output
2+
In order to use an hypermedia API
3+
As a client software developer
4+
I need to be able to use DTOs on my resources as Input or Output objects.
5+
6+
@createSchema
7+
Scenario: Create a resource with a custom Input.
8+
When I add "Content-Type" header equal to "application/ld+json"
9+
And I send a "POST" request to "/dummy_dto_customs" with body:
10+
"""
11+
{
12+
"foo": "test",
13+
"bar": 1
14+
}
15+
"""
16+
Then the response status code should be 201
17+
And the response should be in JSON
18+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
19+
And the JSON should be equal to:
20+
"""
21+
{
22+
"@context": "/contexts/DummyDtoCustom",
23+
"@id": "/dummy_dto_customs/1",
24+
"@type": "DummyDtoCustom",
25+
"lorem": "test",
26+
"ipsum": "1",
27+
"id": 1
28+
}
29+
"""
30+
31+
@createSchema
32+
Scenario: Get an item with a custom output
33+
Given there is a DummyCustomDto
34+
When I send a "GET" request to "/dummy_dto_custom_output/1"
35+
Then the response status code should be 200
36+
And the response should be in JSON
37+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
38+
And the JSON should be a superset of:
39+
"""
40+
{
41+
"@context": {
42+
"@vocab": "http://example.com/docs.jsonld#",
43+
"hydra": "http://www.w3.org/ns/hydra/core#",
44+
"foo": {
45+
"@type": "@id"
46+
},
47+
"bar": {
48+
"@type": "@id"
49+
}
50+
},
51+
"@type": "CustomOutputDto",
52+
"foo": "test",
53+
"bar": 0
54+
}
55+
"""
56+
57+
@createSchema
58+
Scenario: Get a collection with a custom output
59+
Given there are 2 DummyCustomDto
60+
When I send a "GET" request to "/dummy_dto_custom_output"
61+
Then the response status code should be 200
62+
And the response should be in JSON
63+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
64+
And the JSON should be a superset of:
65+
"""
66+
{
67+
"@context": "/contexts/DummyDtoCustom",
68+
"@id": "/dummy_dto_customs",
69+
"@type": "hydra:Collection",
70+
"hydra:member": [
71+
{
72+
"foo": "test",
73+
"bar": 1
74+
},
75+
{
76+
"foo": "test",
77+
"bar": 2
78+
}
79+
],
80+
"hydra:totalItems": 2
81+
}
82+
"""
83+
84+
@createSchema
85+
Scenario: Create a DummyCustomDto object without output
86+
When I add "Content-Type" header equal to "application/ld+json"
87+
And I send a "POST" request to "/dummy_dto_custom_post_without_output" with body:
88+
"""
89+
{
90+
"lorem": "test",
91+
"ipsum": "1"
92+
}
93+
"""
94+
Then the response status code should be 201
95+
And the response should be empty
96+
97+
@createSchema
98+
Scenario: Create and update a DummyInputOutput
99+
When I add "Content-Type" header equal to "application/ld+json"
100+
And I send a "POST" request to "/dummy_dto_input_outputs" with body:
101+
"""
102+
{
103+
"foo": "test",
104+
"bar": 1
105+
}
106+
"""
107+
Then the response status code should be 201
108+
And the JSON should be a superset of:
109+
"""
110+
{
111+
"@context": {
112+
"@vocab": "http://example.com/docs.jsonld#",
113+
"hydra": "http://www.w3.org/ns/hydra/core#",
114+
"baz": {
115+
"@type": "@id"
116+
},
117+
"bat": {
118+
"@type": "@id"
119+
}
120+
},
121+
"@type": "OutputDto",
122+
"baz": 1,
123+
"bat": "test"
124+
}
125+
"""
126+
Then I add "Content-Type" header equal to "application/ld+json"
127+
And I send a "PUT" request to "/dummy_dto_input_outputs/1" with body:
128+
"""
129+
{
130+
"foo": "test",
131+
"bar": 2
132+
}
133+
"""
134+
Then the response status code should be 200
135+
And the JSON should be a superset of:
136+
"""
137+
{
138+
"@context": {
139+
"@vocab": "http:\/\/example.com\/docs.jsonld#",
140+
"hydra": "http:\/\/www.w3.org\/ns\/hydra\/core#",
141+
"baz": {
142+
"@type": "@id"
143+
},
144+
"bat": {
145+
"@type": "@id"
146+
}
147+
},
148+
"@type": "OutputDto",
149+
"baz": 2,
150+
"bat": "test"
151+
}
152+
"""
153+
154+
@createSchema
155+
@!mongodb
156+
Scenario: Use DTO with relations on User
157+
When I add "Content-Type" header equal to "application/ld+json"
158+
And I send a "POST" request to "/users" with body:
159+
"""
160+
{
161+
"username": "soyuka",
162+
"plainPassword": "a real password",
163+
"email": "soyuka@example.com"
164+
}
165+
"""
166+
Then the response status code should be 201
167+
Then I add "Content-Type" header equal to "application/ld+json"
168+
And I send a "PUT" request to "/users/recover/1" with body:
169+
"""
170+
{
171+
"user": "/users/1"
172+
}
173+
"""
174+
Then the response status code should be 200
175+
And the JSON should be a superset of:
176+
"""
177+
{
178+
"@context": {
179+
"@vocab": "http://example.com/docs.jsonld#",
180+
"hydra": "http://www.w3.org/ns/hydra/core#",
181+
"dummy": {
182+
"@type": "@id"
183+
}
184+
},
185+
"@type": "RecoverPasswordOutput",
186+
"dummy": "/dummies/1"
187+
}
188+
"""
189+
190+
@!mongodb
191+
@createSchema
192+
Scenario: Create a resource that has a non-resource DTO relation.
193+
When I add "Content-Type" header equal to "application/ld+json"
194+
And I send a "POST" request to "/non_relation_resources" with body:
195+
"""
196+
{"relation": {"foo": "test"}}
197+
"""
198+
Then the response status code should be 201
199+
And the response should be in JSON
200+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
201+
And the JSON should be equal to:
202+
"""
203+
{
204+
"@context": "/contexts/NonRelationResource",
205+
"@id": "/non_relation_resources/1",
206+
"@type": "NonRelationResource",
207+
"relation": {
208+
"foo": "test"
209+
},
210+
"id": 1
211+
}
212+
"""

0 commit comments

Comments
 (0)