-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Serializer; | ||
|
||
/** | ||
* CircularReferenceHandler. | ||
*/ | ||
class CircularReferenceHandler | ||
{ | ||
/** | ||
* @param mixed $object | ||
* | ||
* @return callable | ||
*/ | ||
public function __invoke($object): callable | ||
{ | ||
return static function () use ($object) { | ||
return $object->getId(); | ||
}; | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
Serializer/Normalizer/ConstraintViolationListNormalizer.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Serializer\Normalizer; | ||
|
||
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer as SymfonyConstraintViolationListNormalizer; | ||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||
use Symfony\Component\Validator\ConstraintViolationListInterface; | ||
|
||
/** | ||
* ConstraintViolationListNormalizer. | ||
*/ | ||
class ConstraintViolationListNormalizer implements NormalizerInterface | ||
{ | ||
private SymfonyConstraintViolationListNormalizer $symfonyConstraintViolationListNormalizer; | ||
|
||
/** | ||
* @param SymfonyConstraintViolationListNormalizer $symfonyConstraintViolationListNormalizer | ||
*/ | ||
public function __construct(SymfonyConstraintViolationListNormalizer $symfonyConstraintViolationListNormalizer) | ||
{ | ||
$this->symfonyConstraintViolationListNormalizer = $symfonyConstraintViolationListNormalizer; | ||
} | ||
|
||
/** | ||
* @param mixed $data | ||
* @param string|null $format | ||
* | ||
* @return bool | ||
*/ | ||
public function supportsNormalization($data, string $format = null): bool | ||
{ | ||
return $data instanceof ConstraintViolationListInterface; | ||
} | ||
|
||
/** | ||
* Clear the "detail" field from prefixed property paths. | ||
* | ||
* From the parent class: | ||
* { | ||
* "detail": "propertyPath1: Error description 1\npropertyPath2: Error description 2", | ||
* } | ||
* After additional processing: | ||
* { | ||
* "detail": "Error description 1\nError description 2", | ||
* } | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function normalize($object, string $format = null, array $context = []) | ||
{ | ||
$result = $this->symfonyConstraintViolationListNormalizer->normalize($object, $format, $context); | ||
|
||
if (\is_array($result) && \array_key_exists('detail', $result) && $result['detail']) { | ||
$messages = explode("\n", $result['detail']); | ||
|
||
foreach ($messages as &$message) { | ||
$position = mb_strpos($message, ': '); | ||
if (\is_int($position)) { | ||
$message = mb_substr($message, $position + 2); | ||
} | ||
} | ||
unset($message); | ||
|
||
$result['detail'] = implode("\n", $messages); | ||
} | ||
|
||
return $result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Serializer\Normalizer; | ||
|
||
use JsonSchema\Validator as JsonSchemaValidator; | ||
use StfalconStudio\ApiBundle\Exception\RuntimeException; | ||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||
|
||
/** | ||
* JsonSchemaErrorNormalizer. | ||
*/ | ||
class JsonSchemaErrorNormalizer implements NormalizerInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function supportsNormalization($data, string $format = null): bool | ||
{ | ||
return $data instanceof JsonSchemaValidator; | ||
} | ||
|
||
/** | ||
* @param JsonSchemaValidator|mixed $object | ||
* @param string|null $format | ||
* @param array $context | ||
* | ||
* @return array | ||
*/ | ||
public function normalize($object, string $format = null, array $context = []): array | ||
{ | ||
if (!$object instanceof JsonSchemaValidator) { | ||
throw new RuntimeException(sprintf('Object of class %s is not instance of %s', \get_class($object), JsonSchemaValidator::class)); | ||
} | ||
|
||
$data = []; | ||
|
||
foreach ($object->getErrors() as ['constraint' => $constraint, 'property' => $property, 'message' => $message]) { | ||
$data[$constraint][] = [ | ||
$property => $message, | ||
]; | ||
} | ||
|
||
return $data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Tests\Serializer; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use StfalconStudio\ApiBundle\Model\UUID\UuidInterface; | ||
use StfalconStudio\ApiBundle\Serializer\CircularReferenceHandler; | ||
|
||
final class CircularReferenceHandlerTest extends TestCase | ||
{ | ||
public function testHandleById(): void | ||
{ | ||
$handler = new CircularReferenceHandler(); | ||
|
||
$object = $this | ||
->getMockBuilder(UuidInterface::class) | ||
->disableOriginalConstructor() | ||
->onlyMethods(['getId']) | ||
->getMock() | ||
; | ||
|
||
$object | ||
->expects(self::once()) | ||
->method('getId') | ||
; | ||
|
||
$handler($object)(); // Execute callback | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
Tests/Serializer/Normalizer/ConstraintViolationListNormalizerTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
/* | ||
* This file is part of the StfalconApiBundle. | ||
* | ||
* (c) Stfalcon LLC <stfalcon.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace StfalconStudio\ApiBundle\Tests\Serializer\Normalizer; | ||
|
||
use PHPUnit\Framework\MockObject\MockObject; | ||
use PHPUnit\Framework\TestCase; | ||
use StfalconStudio\ApiBundle\Serializer\Normalizer\ConstraintViolationListNormalizer; | ||
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer as SymfonyConstraintViolationListNormalizer; | ||
use Symfony\Component\Validator\ConstraintViolationListInterface; | ||
|
||
final class ConstraintViolationListNormalizerTest extends TestCase | ||
{ | ||
/** @var SymfonyConstraintViolationListNormalizer|MockObject */ | ||
private $symfonyNormalizer; | ||
|
||
private ConstraintViolationListNormalizer $normalizer; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->symfonyNormalizer = $this->createMock(SymfonyConstraintViolationListNormalizer::class); | ||
$this->normalizer = new ConstraintViolationListNormalizer($this->symfonyNormalizer); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
unset( | ||
$this->symfonyNormalizer, | ||
$this->normalizer, | ||
); | ||
} | ||
|
||
/** | ||
* @param string $originDetail | ||
* @param string $resultDetail | ||
* | ||
* @dataProvider dataProviderForTestNormalize | ||
*/ | ||
public function testNormalize(string $originDetail, string $resultDetail): void | ||
{ | ||
$object = new \stdClass(); | ||
$format = 'json'; | ||
$context = ['some']; | ||
|
||
$this->symfonyNormalizer | ||
->expects(self::once()) | ||
->method('normalize') | ||
->with($object, $format, $context) | ||
->willReturn(['detail' => $originDetail]) | ||
; | ||
|
||
$result = (array) $this->normalizer->normalize($object, $format, $context); | ||
|
||
self::assertArrayHasKey('detail', $result); | ||
self::assertSame($resultDetail, $result['detail']); | ||
} | ||
|
||
public static function dataProviderForTestNormalize(): iterable | ||
{ | ||
yield [ | ||
'origin_detail' => 'field1: Error description.', | ||
'result_detail' => 'Error description.', | ||
]; | ||
yield [ | ||
'origin_detail' => "field1: Error description 1.\nfield2: Error description 2.", | ||
'result_detail' => "Error description 1.\nError description 2.", | ||
]; | ||
yield [ | ||
'origin_detail' => 'Error description.', | ||
'result_detail' => 'Error description.', | ||
]; | ||
yield [ | ||
'origin_detail' => "field1: Error :description 1.\nfield2: Error :description 2.", | ||
'result_detail' => "Error :description 1.\nError :description 2.", | ||
]; | ||
} | ||
|
||
public function testNotSupportsNormalization(): void | ||
{ | ||
self::assertFalse($this->normalizer->supportsNormalization(new \stdClass())); | ||
} | ||
|
||
public function testSupportsNormalization(): void | ||
{ | ||
$error = $this->createMock(ConstraintViolationListInterface::class); | ||
|
||
self::assertTrue($this->normalizer->supportsNormalization($error)); | ||
} | ||
} |
Oops, something went wrong.