Skip to content

Commit

Permalink
Merge pull request #595 from ergebnis/feature/schema-validator
Browse files Browse the repository at this point in the history
Enhancement: Use `SchemaValidator` provided by `ergebnis/json-schema-validator`
  • Loading branch information
localheinz committed Dec 29, 2021
2 parents 5e923b8 + c19d763 commit 4509b71
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 131 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For a full diff see [`1.0.3...main`][1.0.3...main].
- Dropped support for PHP 7.2 ([#564]), by [@localheinz]
- Dropped support for PHP 7.3 ([#573]), by [@localheinz]
- Renamed `Format::__toString()`, `Indent::__toString()`, and `Json::__toString()` to `Format::toString()`, `Indent::toString()`, and `Json::toString()`, requiring consumers to explicitly invoke methods instead of allowing to cast to `string` ([#589]), by [@localheinz]
- Started using the `SchemaValidator` provided by `ergebnis/json-schema-validator` ([#595]), by [@localheinz]

### Fixed

Expand Down Expand Up @@ -427,6 +428,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0].
[#573]: https://github.com/ergebnis/json-normalizer/pull/573
[#589]: https://github.com/ergebnis/json-normalizer/pull/589
[#590]: https://github.com/ergebnis/json-normalizer/pull/590
[#595]: https://github.com/ergebnis/json-normalizer/pull/595

[@BackEndTea]: https://github.com/BackEndTea
[@dependabot]: https://github.com/dependabot
Expand Down
2 changes: 1 addition & 1 deletion infection.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"text": ".build/infection/infection-log.txt"
},
"minCoveredMsi": 88,
"minMsi": 88,
"minMsi": 87,
"phpUnit": {
"configDir": "test\/Unit"
},
Expand Down
6 changes: 2 additions & 4 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
<MissingParamType occurrences="1">
<code>$data</code>
</MissingParamType>
<MixedArgument occurrences="7">
<code>$data</code>
<MixedArgument occurrences="6">
<code>$item</code>
<code>$item</code>
<code>$itemSchema</code>
Expand Down Expand Up @@ -138,12 +137,11 @@
<code>$normalizedFile</code>
<code>$normalizedFile</code>
</MixedArgument>
<MixedAssignment occurrences="5">
<MixedAssignment occurrences="4">
<code>$decoded</code>
<code>$fileInfo</code>
<code>$normalizedFile</code>
<code>$schemaDecoded</code>
<code>$schemaDecoded</code>
</MixedAssignment>
<MixedInferredReturnType occurrences="1">
<code>\Generator&lt;array&lt;string&gt;&gt;</code>
Expand Down
41 changes: 22 additions & 19 deletions src/SchemaNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Ergebnis\Json\Normalizer;

use Ergebnis\Json\SchemaValidator;
use JsonSchema\Exception\InvalidSchemaMediaTypeException;
use JsonSchema\Exception\JsonDecodingException;
use JsonSchema\Exception\ResourceNotFoundException;
Expand All @@ -23,12 +24,12 @@ final class SchemaNormalizer implements NormalizerInterface
{
private string $schemaUri;
private SchemaStorage $schemaStorage;
private Validator\SchemaValidatorInterface $schemaValidator;
private SchemaValidator\SchemaValidator $schemaValidator;

public function __construct(
string $schemaUri,
SchemaStorage $schemaStorage,
Validator\SchemaValidatorInterface $schemaValidator
SchemaValidator\SchemaValidator $schemaValidator
) {
$this->schemaUri = $schemaUri;
$this->schemaStorage = $schemaStorage;
Expand All @@ -37,8 +38,6 @@ public function __construct(

public function normalize(Json $json): Json
{
$decoded = $json->decoded();

try {
/** @var \stdClass $schema */
$schema = $this->schemaStorage->getSchema($this->schemaUri);
Expand All @@ -53,38 +52,41 @@ public function normalize(Json $json): Json
}

$resultBeforeNormalization = $this->schemaValidator->validate(
$decoded,
$schema,
SchemaValidator\Json::fromString($json->encoded()),
SchemaValidator\Json::fromString(\json_encode($schema)),
SchemaValidator\JsonPointer::empty(),
);

if (!$resultBeforeNormalization->isValid()) {
throw Exception\OriginalInvalidAccordingToSchemaException::fromSchemaUriAndErrors(
$this->schemaUri,
...$resultBeforeNormalization->errors(),
...\array_map(static function (SchemaValidator\ValidationError $error): string {
return $error->message()->toString();
}, $resultBeforeNormalization->errors()),
);
}

$normalized = $this->normalizeData(
$decoded,
$normalized = Json::fromEncoded(\json_encode($this->normalizeData(
$json->decoded(),
$schema,
);
)));

$resultAfterNormalization = $this->schemaValidator->validate(
$normalized,
$schema,
SchemaValidator\Json::fromString($normalized->encoded()),
SchemaValidator\Json::fromString(\json_encode($schema)),
SchemaValidator\JsonPointer::empty(),
);

if (!$resultAfterNormalization->isValid()) {
throw Exception\NormalizedInvalidAccordingToSchemaException::fromSchemaUriAndErrors(
$this->schemaUri,
...$resultAfterNormalization->errors(),
...\array_map(static function (SchemaValidator\ValidationError $error): string {
return $error->message()->toString();
}, $resultAfterNormalization->errors()),
);
}

/** @var string $encoded */
$encoded = \json_encode($normalized);

return Json::fromEncoded($encoded);
return $normalized;
}

/**
Expand Down Expand Up @@ -229,8 +231,9 @@ private function resolveSchema(
) {
foreach ($schema->oneOf as $oneOfSchema) {
$result = $this->schemaValidator->validate(
$data,
$oneOfSchema,
SchemaValidator\Json::fromString(\json_encode($data)),
SchemaValidator\Json::fromString(\json_encode($oneOfSchema)),
SchemaValidator\JsonPointer::empty(),
);

if ($result->isValid()) {
Expand Down
4 changes: 2 additions & 2 deletions src/Vendor/Composer/ComposerJsonNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
namespace Ergebnis\Json\Normalizer\Vendor\Composer;

use Ergebnis\Json\Normalizer;
use Ergebnis\Json\SchemaValidator;
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;

final class ComposerJsonNormalizer implements Normalizer\NormalizerInterface
{
Expand All @@ -27,7 +27,7 @@ public function __construct(string $schemaUri)
new Normalizer\SchemaNormalizer(
$schemaUri,
new SchemaStorage(),
new Normalizer\Validator\SchemaValidator(new Validator()),
new SchemaValidator\SchemaValidator(),
),
new BinNormalizer(),
new ConfigHashNormalizer(),
Expand Down
112 changes: 7 additions & 105 deletions test/Unit/SchemaNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
use Ergebnis\Json\Normalizer\Exception;
use Ergebnis\Json\Normalizer\Json;
use Ergebnis\Json\Normalizer\SchemaNormalizer;
use Ergebnis\Json\Normalizer\Validator\Result;
use Ergebnis\Json\Normalizer\Validator\SchemaValidator;
use Ergebnis\Json\Normalizer\Validator\SchemaValidatorInterface;
use Ergebnis\Json\SchemaValidator;
use JsonSchema\Exception\InvalidSchemaMediaTypeException;
use JsonSchema\Exception\JsonDecodingException;
use JsonSchema\Exception\ResourceNotFoundException;
use JsonSchema\Exception\UriResolverException;
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;

/**
* @internal
Expand Down Expand Up @@ -67,7 +64,7 @@ public function testNormalizeThrowsSchemaUriCouldNotBeResolvedExceptionWhenSchem
$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$this->createStub(SchemaValidatorInterface::class),
new SchemaValidator\SchemaValidator(),
);

$this->expectException(Exception\SchemaUriCouldNotBeResolvedException::class);
Expand Down Expand Up @@ -99,7 +96,7 @@ public function testNormalizeThrowsSchemaUriCouldNotBeReadExceptionWhenSchemaUri
$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$this->createStub(SchemaValidatorInterface::class),
new SchemaValidator\SchemaValidator(),
);

$this->expectException(Exception\SchemaUriCouldNotBeReadException::class);
Expand Down Expand Up @@ -131,7 +128,7 @@ public function testNormalizeThrowsSchemaUriReferencesDocumentWithInvalidMediaTy
$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$this->createStub(SchemaValidatorInterface::class),
new SchemaValidator\SchemaValidator(),
);

$this->expectException(Exception\SchemaUriReferencesDocumentWithInvalidMediaTypeException::class);
Expand Down Expand Up @@ -163,7 +160,7 @@ public function testNormalizeThrowsRuntimeExceptionIfSchemaUriReferencesResource
$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$this->createStub(SchemaValidatorInterface::class),
new SchemaValidator\SchemaValidator(),
);

$this->expectException(Exception\SchemaUriReferencesInvalidJsonDocumentException::class);
Expand Down Expand Up @@ -202,112 +199,17 @@ public function testNormalizeThrowsOriginalInvalidAccordingToSchemaExceptionWhen
->with(self::identicalTo($schemaUri))
->willReturn($schemaDecoded);

$schemaValidator = $this->createMock(SchemaValidatorInterface::class);

$schemaValidator
->expects(self::once())
->method('validate')
->with(
self::identicalTo($json->decoded()),
self::identicalTo($schemaDecoded),
)
->willReturn(Result::create(
$faker->sentence(),
$faker->sentence(),
$faker->sentence(),
));

$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$schemaValidator,
new SchemaValidator\SchemaValidator(),
);

$this->expectException(Exception\OriginalInvalidAccordingToSchemaException::class);

$normalizer->normalize($json);
}

public function testNormalizeThrowsNormalizedInvalidAccordingToSchemaExceptionWhenNormalizedNotValidAccordingToSchema(): void
{
$faker = self::faker();

$json = Json::fromEncoded(
<<<'JSON'
{
"url": "https://localheinz.com",
"name": "Andreas M枚ller"
}
JSON
);

$schemaUri = $faker->url();

$schema = <<<'JSON'
{
"type": "object",
"additionalProperties": false,
"properties": {
"name" : {
"type" : "string"
},
"role" : {
"type" : "string"
}
}
}
JSON;

$normalized = Json::fromEncoded(
<<<'JSON'
{
"name": "Andreas M枚ller",
"url": "https://localheinz.com"
}
JSON
);

$schemaDecoded = \json_decode($schema);

$schemaStorage = $this->createMock(SchemaStorage::class);

$schemaStorage
->expects(self::once())
->method('getSchema')
->with(self::identicalTo($schemaUri))
->willReturn($schemaDecoded);

$schemaValidator = $this->createMock(SchemaValidatorInterface::class);

$schemaValidator
->expects(self::exactly(2))
->method('validate')
->withConsecutive(
[
self::identicalTo($json->decoded()),
self::identicalTo($schemaDecoded),
],
[
self::equalTo($normalized->decoded()),
self::identicalTo($schemaDecoded),
],
)
->willReturnOnConsecutiveCalls(
Result::create(),
Result::create($faker->sentence()),
);

$normalizer = new SchemaNormalizer(
$schemaUri,
$schemaStorage,
$schemaValidator,
);

$this->expectException(Exception\NormalizedInvalidAccordingToSchemaException::class);

$normalizer->normalize($json);
}

/**
* @dataProvider provideExpectedEncodedAndSchemaUri
*/
Expand All @@ -318,7 +220,7 @@ public function testNormalizeNormalizes(string $expected, string $encoded, strin
$normalizer = new SchemaNormalizer(
$schemaUri,
new SchemaStorage(),
new SchemaValidator(new Validator()),
new SchemaValidator\SchemaValidator(),
);

$normalized = $normalizer->normalize($json);
Expand Down

0 comments on commit 4509b71

Please sign in to comment.