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()); }
/** * DataModel generator with custom schemas for validation * To use on a ->map() * @param array $schemas ['http://my.com/model.json', 'file://...'] * @return \Closure */ public function factory($schemas = []) { $deReferencedSchemas = []; // DeReference once for this factory foreach ($schemas as $schema) { $deReferencedSchemas[$schema] = $this->deReferencer->dereference($schema); } return function ($data) use($deReferencedSchemas) { $data = $this->toStdClass($data); $model = clone $this; $model->setPayload($data); $model->schemas = $deReferencedSchemas; $closure = $model->validate(); $closure($data); return $model; }; }
/** * Get the schema from the swagger doc * * @param string $path * @param string $operation * @param int $response * @return stdClass * @throws InvalidArgumentException */ public function getSchema($path, $operation, $response) { $dereferencer = new Dereferencer(); $swagger = $dereferencer->dereference($this->swaggerFile); $basePath = $this->getProperty($swagger, 'basePath', ''); $path = str_replace($basePath, '', $path); $paths = $this->getProperty($swagger, 'paths'); $pathObject = $this->findInPaths($paths, $path, $operation); $operationObject = $this->getProperty($pathObject, $operation); $operationResponses = $this->getProperty($operationObject, 'responses'); $operationResponse = null; if ($this->hasProperty($operationResponses, $response)) { $operationResponse = $this->getProperty($operationResponses, $response); } else { $operationResponse = $this->getProperty($operationResponses, 'default'); } $schema = new stdClass(); if (null !== $operationResponse && $this->hasProperty($operationResponse, 'schema')) { $schema = $this->getProperty($operationResponse, 'schema'); } return $schema; }
/** * @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 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; }