From e036ff05ba86ea03ffa723da27b14775c6688617 Mon Sep 17 00:00:00 2001 From: codeliner Date: Mon, 9 Aug 2021 22:05:27 +0200 Subject: [PATCH] feat: Support JsonPointer in type name --- src/AbstractJsonSchema.php | 27 +++++++- tests/TypeSchemaReferenceTest.php | 111 ++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 tests/TypeSchemaReferenceTest.php diff --git a/src/AbstractJsonSchema.php b/src/AbstractJsonSchema.php index efaea99..822080e 100644 --- a/src/AbstractJsonSchema.php +++ b/src/AbstractJsonSchema.php @@ -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 { @@ -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); } @@ -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; + } } diff --git a/tests/TypeSchemaReferenceTest.php b/tests/TypeSchemaReferenceTest.php new file mode 100644 index 0000000..34a6844 --- /dev/null +++ b/tests/TypeSchemaReferenceTest.php @@ -0,0 +1,111 @@ +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()); + } + } +}