Skip to content

Commit 858f064

Browse files
authored
Merge pull request #5 from autorusltd/release/v1.4.0
v1.4.0
2 parents d563b05 + 00dcc23 commit 858f064

File tree

3 files changed

+165
-8
lines changed

3 files changed

+165
-8
lines changed

.scrutinizer.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
build:
2+
environment:
3+
php:
4+
version: '8.0'
5+
ini:
6+
'xdebug.mode': 'coverage'
27
nodes:
38
analysis:
49
tests:

src/ResponseFactoryAwareTrait.php

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
use Arus\Http\Response\Resource\Errors;
1010
use Psr\Http\Message\ResponseInterface;
1111
use Sunrise\Http\Message\ResponseFactory;
12-
use Symfony\Component\Validator\ConstraintViolationListInterface;
12+
use Symfony\Component\Validator\ConstraintViolationInterface;
13+
use InvalidArgumentException;
14+
15+
/**
16+
* Import functions
17+
*/
18+
use function is_array;
1319

1420
/**
1521
* ResponseFactoryAwareTrait
@@ -98,20 +104,48 @@ public function error(string $message, string $source = null, $code = null, int
98104
}
99105

100106
/**
101-
* @param ConstraintViolationListInterface $violations
107+
* @param iterable $violations
102108
* @param int $status
103109
*
104110
* @return ResponseInterface
111+
*
112+
* @throws InvalidArgumentException
105113
*/
106-
public function violations(ConstraintViolationListInterface $violations, int $status = 400) : ResponseInterface
114+
public function violations(iterable $violations, int $status = 400) : ResponseInterface
107115
{
108116
$errors = [];
109117
foreach ($violations as $violation) {
110-
$errors[] = new Error(
111-
$violation->getMessage(),
112-
$violation->getPropertyPath(),
113-
$violation->getCode()
114-
);
118+
if ($violation instanceof ConstraintViolationInterface) {
119+
$errors[] = new Error(
120+
$violation->getMessage(),
121+
$violation->getPropertyPath(),
122+
$violation->getCode()
123+
);
124+
125+
continue;
126+
}
127+
128+
if (is_array($violation) && isset($violation['message'], $violation['source'])) {
129+
$errors[] = new Error(
130+
$violation['message'],
131+
$violation['source'],
132+
$violation['code'] ?? null
133+
);
134+
135+
continue;
136+
}
137+
138+
if (is_array($violation) && isset($violation['message'], $violation['property'])) {
139+
$errors[] = new Error(
140+
$violation['message'],
141+
$violation['property'],
142+
$violation['code'] ?? null
143+
);
144+
145+
continue;
146+
}
147+
148+
throw new InvalidArgumentException('Unexpected violation');
115149
}
116150

117151
return $this->json(new Errors(...$errors), $status);

tests/ResponseFactoryTest.php

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Laminas\Diactoros\ResponseFactory as ZendResponseFactory;
1414
use Symfony\Component\Validator\ConstraintViolationList;
1515
use Symfony\Component\Validator\ConstraintViolation;
16+
use InvalidArgumentException;
1617

1718
/**
1819
* ResponseFactoryTest
@@ -308,4 +309,121 @@ public function testCreateJsonViolationsResponseWithCustomStatusCode() : void
308309

309310
$this->assertSame(500, $response->getStatusCode());
310311
}
312+
313+
/**
314+
* @return void
315+
*/
316+
public function testViolationsWithObjects() : void
317+
{
318+
$response = (new class () {
319+
use ResponseFactoryAwareTrait;
320+
})->violations([
321+
new ConstraintViolation('foo', null, [], null, 'bar', null, null, 'baz'),
322+
new ConstraintViolation('qux', null, [], null, 'quux', null, null, 'quuux'),
323+
]);
324+
325+
$this->assertSame(400, $response->getStatusCode());
326+
327+
$this->assertSame(
328+
'{"errors":[{"code":"baz","source":"bar","message":"foo"},' .
329+
'{"code":"quuux","source":"quux","message":"qux"}]}',
330+
$response->getBody()->__toString()
331+
);
332+
}
333+
334+
/**
335+
* @return void
336+
*/
337+
public function testViolationsWithSourceableArrays() : void
338+
{
339+
$response = (new class () {
340+
use ResponseFactoryAwareTrait;
341+
})->violations([
342+
['code' => 'foo', 'source' => 'bar', 'message' => 'baz'],
343+
['code' => 'bar', 'source' => 'baz', 'message' => 'qux'],
344+
]);
345+
346+
$this->assertSame(400, $response->getStatusCode());
347+
348+
$this->assertSame(
349+
'{"errors":[{"code":"foo","source":"bar","message":"baz"},' .
350+
'{"code":"bar","source":"baz","message":"qux"}]}',
351+
$response->getBody()->__toString()
352+
);
353+
}
354+
355+
/**
356+
* @return void
357+
*/
358+
public function testViolationsWithSourceableArraysWithoutCodes() : void
359+
{
360+
$response = (new class () {
361+
use ResponseFactoryAwareTrait;
362+
})->violations([
363+
['source' => 'bar', 'message' => 'baz'],
364+
['source' => 'baz', 'message' => 'qux'],
365+
]);
366+
367+
$this->assertSame(400, $response->getStatusCode());
368+
369+
$this->assertSame(
370+
'{"errors":[{"code":null,"source":"bar","message":"baz"},' .
371+
'{"code":null,"source":"baz","message":"qux"}]}',
372+
$response->getBody()->__toString()
373+
);
374+
}
375+
376+
/**
377+
* @return void
378+
*/
379+
public function testViolationsWithPropertyableArrays() : void
380+
{
381+
$response = (new class () {
382+
use ResponseFactoryAwareTrait;
383+
})->violations([
384+
['code' => 'foo', 'property' => 'bar', 'message' => 'baz'],
385+
['code' => 'bar', 'property' => 'baz', 'message' => 'qux'],
386+
]);
387+
388+
$this->assertSame(400, $response->getStatusCode());
389+
390+
$this->assertSame(
391+
'{"errors":[{"code":"foo","source":"bar","message":"baz"},' .
392+
'{"code":"bar","source":"baz","message":"qux"}]}',
393+
$response->getBody()->__toString()
394+
);
395+
}
396+
397+
/**
398+
* @return void
399+
*/
400+
public function testViolationsWithPropertyableArraysWithoutCodes() : void
401+
{
402+
$response = (new class () {
403+
use ResponseFactoryAwareTrait;
404+
})->violations([
405+
['property' => 'bar', 'message' => 'baz'],
406+
['property' => 'baz', 'message' => 'qux'],
407+
]);
408+
409+
$this->assertSame(400, $response->getStatusCode());
410+
411+
$this->assertSame(
412+
'{"errors":[{"code":null,"source":"bar","message":"baz"},' .
413+
'{"code":null,"source":"baz","message":"qux"}]}',
414+
$response->getBody()->__toString()
415+
);
416+
}
417+
418+
/**
419+
* @return void
420+
*/
421+
public function testViolationsWithInvalidData() : void
422+
{
423+
$this->expectException(InvalidArgumentException::class);
424+
425+
(new class () {
426+
use ResponseFactoryAwareTrait;
427+
})->violations([null]);
428+
}
311429
}

0 commit comments

Comments
 (0)