Skip to content

Commit 0a6d61d

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

File tree

80 files changed

+2030
-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

+2030
-317
lines changed

features/bootstrap/DoctrineContext.php

Lines changed: 26 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,30 @@ 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+
$this->thereAreNbDummyCustomDto(1);
1193+
}
1194+
1195+
/**
1196+
* @Given there are :nb DummyCustomDto
1197+
*/
1198+
public function thereAreNbDummyCustomDto($nb)
1199+
{
1200+
for ($i = 0; $i < $nb; ++$i) {
1201+
$dto = $this->isOrm() ? new DummyDtoCustom() : new DummyDtoCustomDocument();
1202+
$dto->lorem = 'test';
1203+
$dto->ipsum = (string) $i + 1;
1204+
$this->manager->persist($dto);
1205+
}
1206+
1207+
$this->manager->flush();
1208+
$this->manager->clear();
1209+
}
1210+
11851211
private function isOrm(): bool
11861212
{
11871213
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 a 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": 1
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+
When 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+
@!mongodb
155+
@createSchema
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+
When 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+
"""

features/main/table_inheritance.feature

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -292,34 +292,38 @@ Feature: Table inheritance
292292
}
293293
"""
294294

295-
Scenario: Get the parent interface collection
296-
When I send a "GET" request to "/resource_interfaces"
297-
Then the response status code should be 200
298-
And the response should be in JSON
299-
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
300-
And the JSON should be valid according to this schema:
301-
"""
302-
{
303-
"type": "object",
304-
"properties": {
305-
"hydra:member": {
306-
"type": "array",
307-
"items": {
308-
"type": "object",
309-
"properties": {
310-
"@type": {
311-
"type": "string",
312-
"pattern": "^ResourceInterface$"
313-
},
314-
"foo": {
315-
"type": "string",
316-
"required": "true"
317-
}
318-
}
319-
},
320-
"minItems": 1
321-
}
322-
},
323-
"required": ["hydra:member"]
324-
}
325-
"""
295+
Scenario: Get the parent interface collection
296+
When I send a "GET" request to "/resource_interfaces"
297+
Then the response status code should be 200
298+
And the response should be in JSON
299+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
300+
And the JSON should be valid according to this schema:
301+
"""
302+
{
303+
"type": "object",
304+
"properties": {
305+
"hydra:member": {
306+
"type": "array",
307+
"items": {
308+
"type": "object",
309+
"properties": {
310+
"@type": {
311+
"type": "string",
312+
"pattern": "^ResourceInterface$"
313+
},
314+
"@id": {
315+
"type": "string",
316+
"pattern": "^_:"
317+
},
318+
"foo": {
319+
"type": "string",
320+
"required": "true"
321+
}
322+
}
323+
},
324+
"minItems": 1
325+
}
326+
},
327+
"required": ["hydra:member"]
328+
}
329+
"""

0 commit comments

Comments
 (0)