public function testToc() { $file = file_get_contents(__DIR__ . '/../docs/toc.json'); $json = json_decode($file); $this->assertEquals(JSON_ERROR_NONE, json_last_error()); $deref = new Dereferencer(); $schema = $deref->dereference(json_decode(file_get_contents(sprintf(self::SCHEMA_PATH, __DIR__, 'toc.json.schema')))); $validator = new Validator($json, $schema); $this->assertFalse($validator->fails()); }
public function __invoke($schema, OutputInterface $output) { $schema = Util::loadJson($schema); $metaSchema = (new Dereferencer())->dereference('file://' . Util::schemaPath('draft4.json')); $validator = new Validator($schema, $metaSchema); if ($validator->passes()) { $output->writeln('<info>✓ Valid draft-04 JSON Schema</info>'); } else { $output->writeln('<error>✗ Invalid draft-04 JSON Schema</error>'); Util::renderErrorTable($output, $validator->errors()); } }
public function __invoke($data, $schema, OutputInterface $output) { $schema = Util::loadJson($schema); $data = Util::loadJson($data); $schema = (new Dereferencer())->dereference($schema); $validator = new Validator($data, $schema); if ($validator->passes()) { $output->writeln('<info>✓ Validation passed</info>'); } else { $output->writeln('<error>✗ Validation failed</error>'); Util::renderErrorTable($output, $validator->errors()); } }
/** * Validation sugar to use on a flatMap * Validate against schemas of the constructors * @return \Closure */ public function validate() { return function ($payload) { // validate foreach ($this->schemas as $schema) { $validator = new Validator($payload, $schema); foreach ($this->formatExtensions as $format => $class) { $validator->registerFormatExtension($format, new $class()); } if ($validator->fails()) { foreach ($validator->errors() as $error) { /* @var ValidationError $error */ print_r($error->toArray()); } } } }; }
/** * @param string $value * @param string $schema * * @throws \RREST\Exception\InvalidJSONException * @throws \RREST\Exception\InvalidResponsePayloadBodyException */ public function assertResponseJSON($value, $schema) { $assertInvalidJSONException = function () { if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidJSONException([new Error(ucfirst(json_last_error_msg()), 'invalid-response-payloadbody-json')]); } }; //validate JSON format $schemaJSON = json_decode($schema); $assertInvalidJSONException(); //validate JsonSchema $deref = new JsonGuard\Dereferencer(); $schema = $deref->dereference($schemaJSON); $validator = new JsonGuard\Validator($value, $schema); if ($validator->fails()) { $errors = $validator->errors(); $jsonPointer = new JsonGuard\Pointer($value); $invalidBodyError = []; foreach ($validator->errors() as $jsonError) { $error = $jsonError->toArray(); $propertyValue = null; try { $propertyValue = $jsonPointer->get($error['pointer']); } catch (NonexistentValueReferencedException $e) { //don't care if we can't have the value here, it's just //for the context } $context = new \stdClass(); $context->jsonPointer = $error['pointer']; $context->value = $propertyValue; $context->constraints = $error['constraints']; $invalidBodyError[] = new Error(strtolower($error['pointer'] . ': ' . $error['message']), strtolower($error['code']), $context); } if (empty($invalidBodyError) == false) { throw new InvalidResponsePayloadBodyException($invalidBodyError); } } }
/** * @param stdClass $paths * @param string $path * @param string $operation * @return stdClass * @throws InvalidArgumentException */ private function findInPaths(stdClass $paths, $path, $operation) { $path = explode('?', $path)[0]; $pathsArray = get_object_vars($paths); if (array_key_exists($path, $pathsArray)) { return $pathsArray[$path]; } $pathParts = explode('/', $path); $foundPath = null; foreach ($pathsArray as $pathKey => $value) { // assume we found it $foundPath = $value; $pathKeyParts = explode('/', $pathKey); if (count($pathParts) !== count($pathKeyParts)) { $foundPath = null; continue; } if (false === strpos($pathKey, '{')) { $foundPath = null; continue; } // skip if we don't have the right operation if (!$this->hasProperty($value, $operation)) { $foundPath = null; continue; } $operationProperty = $this->getProperty($value, $operation); // skip if there aren't any parameters if (!$this->hasProperty($operationProperty, 'parameters')) { $foundPath = null; continue; } $parameters = $this->getProperty($operationProperty, 'parameters'); foreach ($pathKeyParts as $index => $part) { // if the key we're checking doesn't exist, exit if (!array_key_exists($index, $pathParts)) { $foundPath = null; break; } if (0 === strpos($part, '{')) { $name = substr($part, 1, -1); foreach ($parameters as $parameter) { if ($parameter instanceof Reference) { $parameter = $parameter->resolve(); } $inProperty = $this->getProperty($parameter, 'in', ''); if ($inProperty !== 'path') { $foundPath = null; continue; } $nameProperty = $this->getProperty($parameter, 'name', ''); if ($name !== $nameProperty) { $foundPath = null; continue; } // required is not valid in v4 of json schema if ($this->hasProperty($parameter, 'required')) { unset($parameter->required); } $validator = new Validator($pathParts[$index], $parameter); if ($validator->fails()) { $foundPath = null; break; } else { $foundPath = $value; break; } } } else { // if they're not equal, exit if ($part !== $pathParts[$index]) { $foundPath = null; break; } } } if (null !== $foundPath) { break; } } if (null === $foundPath) { throw new InvalidArgumentException('Could not find swagger path'); } return $foundPath; }
/** * @param string $value * @param string $schema * * @throws \RREST\Exception\InvalidJSONException * @throws \RREST\Exception\InvalidRequestPayloadBodyException */ protected function assertHTTPPayloadBodyJSON($value, $schema) { $assertInvalidJSONException = function () { if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidJSONException([new Error(ucfirst(json_last_error_msg()), 'invalid-request-payloadbody-json')]); } }; //validate JSON format $valueJSON = json_decode($value); $assertInvalidJSONException(); $schemaJSON = json_decode($schema); $assertInvalidJSONException(); //validate JsonSchema $deref = new JsonGuard\Dereferencer(); $schema = $deref->dereference($schemaJSON); $validator = new JsonGuard\Validator($valueJSON, $schema); if ($validator->fails()) { $errors = $validator->errors(); $jsonPointer = new JsonGuard\Pointer($value); $invalidBodyError = []; foreach ($validator->errors() as $jsonError) { $error = $jsonError->toArray(); $propertyValue = null; $pointer = empty($error['pointer']) ? null : $error['pointer']; if (empty($pointer) === false) { try { $propertyValue = $jsonPointer->get($pointer); } catch (NonexistentValueReferencedException $e) { //don't care if we can't have the value here, it's just //for the context } } $context = new \stdClass(); $context->jsonPointer = $pointer; $context->value = $propertyValue; $context->constraints = $error['constraints']; //$context->jsonSource = $valueJSON; $message = strtolower($error['message']); if (empty($pointer) === false) { $message = strtolower($pointer . ': ' . $error['message']); } //TODO: having RREST message error //special case for required to have a better message if ($error['code'] === JsonGuard\ErrorCode::MISSING_REQUIRED) { $message = strtolower($error['message'] . ' (' . implode(', ', $context->constraints['required']) . ')'); } $invalidBodyError[] = new Error(strtolower($message), strtolower($error['code']), $context); } if (empty($invalidBodyError) == false) { throw new InvalidRequestPayloadBodyException($invalidBodyError); } } $this->hintedPayloadBody = $valueJSON; }