Skip to content

Commit

Permalink
feat: Support JsonPointer in type name
Browse files Browse the repository at this point in the history
  • Loading branch information
codeliner committed Aug 9, 2021
1 parent eaa0083 commit e036ff0
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/AbstractJsonSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
use EventEngine\Schema\Schema;
use EventEngine\Schema\TypeSchemaMap;
use EventEngine\Util\VariableType;
use function array_key_exists;
use function exp;
use function explode;
use function var_dump;

abstract class AbstractJsonSchema implements Schema
{
Expand All @@ -34,7 +38,7 @@ public function assertPayload(string $messageName, array $payload, PayloadSchema
{
$this->assertPayloadSchema($messageName, $payloadSchema);

$payloadSchemaArr = array_merge($payloadSchema->toArray(), [JsonSchema::DEFINITIONS => $typeSchemaMap->toArray()]);
$payloadSchemaArr = array_merge($payloadSchema->toArray(), [JsonSchema::DEFINITIONS => $this->convertTypeSchemaMapToDefinitions($typeSchemaMap)]);

$this->assert("$messageName payload", $payload, $payloadSchemaArr);
}
Expand Down Expand Up @@ -123,7 +127,26 @@ public function buildMessageBoxSchema(CommandMap $commandMap, EventMap $eventMap
'events' => $eventSchemas,
'queries' => $querySchemas,
],
'definitions' => $typeSchemaMap->toArray(),
'definitions' => $this->convertTypeSchemaMapToDefinitions($typeSchemaMap),
];
}

private function convertTypeSchemaMapToDefinitions(TypeSchemaMap $typeSchemaMap): array
{
$definitions = [];

foreach ($typeSchemaMap->toArray() as $jsonPointer => $typeSchema) {
$temp = &$definitions;
foreach(explode("/", $jsonPointer) as $key) {
if(!array_key_exists($key, $temp)) {
$temp[$key] = [];
}
$temp = &$temp[$key];
}
$temp = $typeSchema;
unset($temp);
}

return $definitions;
}
}
111 changes: 111 additions & 0 deletions tests/TypeSchemaReferenceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);

namespace EventEngineTest\JsonSchema;

use EventEngine\JsonSchema\Exception\JsonValidationError;
use EventEngine\JsonSchema\JsonSchema;
use EventEngine\JsonSchema\JsonSchemaArray;
use EventEngine\JsonSchema\OpisJsonSchema;
use EventEngine\Schema\TypeSchemaMap;
use function json_decode;

final class TypeSchemaReferenceTest extends BasicTestCase
{
private function schema(): array
{
$schema = <<<'JSON'
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"$ref": "#/definitions/Name"
},
"hasValue": {"type": "boolean"},
"age": {"type": "number"},
"subObject": {
"type": "object",
"properties": {
"p1": {
"$ref": "#/definitions/SubObject/P1"
},
"p2": {
"$ref": "#/definitions/SubObject/P2"
}
},
"required": ["p1", "p2"],
"additionalProperties": false
},
"type": {
"enum": ["Foo", "Bar", "Baz"]
}
},
"required": ["name", "hasValue", "age", "type", "subObject"],
"additionalProperties": false
}
JSON;
return json_decode($schema, true);
}

private function typeSchemaMap(): TypeSchemaMap
{
$typeSchemaMap = new TypeSchemaMap();

$typeSchemaMap->add('Name', JsonSchema::string(['minLength' => 3]));
$typeSchemaMap->add('SubObject/P1', JsonSchema::string(['minLength' => 3]));
$typeSchemaMap->add('SubObject/P2', JsonSchema::boolean());

return $typeSchemaMap;
}

private function validData(): array
{
return [
'name' => 'Tester',
'hasValue' => true,
'age' => 40,
'type' => 'Bar',
'subObject' => [
'p1' => 'a sub str',
'p2' => true
]
];
}

/**
* @test
*/
public function it_validates_payload_schema(): void
{
$data = $this->validData();

$cut = new OpisJsonSchema();
$cut->assertPayload('TestMessage', $data, new JsonSchemaArray($this->schema()), $this->typeSchemaMap());
$this->assertTrue(true);
}

/**
* @test
*/
public function it_throws_json_validation_error_exception(): void
{
$data = $this->validData();
$data['subObject']['p1'] = 'to';

$expectedMessage = <<<'Msg'
Validation of "TestMessage payload" failed: field "subObject.p1" [minLength] {
"min": 3,
"length": 2
}
Msg;

$cut = new OpisJsonSchema();
try {
$cut->assertPayload('TestMessage', $data, new JsonSchemaArray($this->schema()), $this->typeSchemaMap());
} catch (JsonValidationError $e) {
$this->assertSame(400, $e->getCode());
$this->assertStringStartsWith($expectedMessage, $e->getMessage());
}
}
}

0 comments on commit e036ff0

Please sign in to comment.