Skip to content

Commit

Permalink
Fix JSON parsing for component references
Browse files Browse the repository at this point in the history
Resolves #38
  • Loading branch information
hotmeteor committed Apr 21, 2021
1 parent 8d56d2e commit f399e3a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 115 deletions.
29 changes: 26 additions & 3 deletions src/Validation/ResponseValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ protected function parseResponse(Response $response)
$schema = $response->content[$contentType]->schema;

$this->validateResponse(
$schema,
$this->body($contentType, $schema->type)
$schema, $this->body($contentType, $this->schemaType($schema))
);
}

Expand Down Expand Up @@ -114,6 +113,30 @@ protected function contentType()
return $this->response->headers->get('Content-Type');
}

/**
* @return ?string
*/
protected function schemaType(Schema $schema)
{
if($schema->type) {
return $schema->type;
}

if($schema->allOf) {
return 'allOf';
}

if($schema->anyOf) {
return 'anyOf';
}

if($schema->oneOf) {
return 'oneOf';
}

return null;
}

/**
* @param $contentType
* @param $schemaType
Expand All @@ -126,7 +149,7 @@ protected function body($contentType, $schemaType)
{
$body = $this->response->getContent();

if (in_array($schemaType, ['object', 'array'], true)) {
if (in_array($schemaType, ['object', 'array', 'allOf'], true)) {
if (in_array($contentType, ['application/json', 'application/vnd.api+json'])) {
return json_decode($body);
} else {
Expand Down
122 changes: 14 additions & 108 deletions tests/Fixtures/Components.v1.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"openapi": "3.1.0",
"info": {
"title": "Test.v1",
"title": "Components.v1",
"version": "1.0"
},
"servers": [
Expand All @@ -10,143 +10,49 @@
}
],
"paths": {
"/users": {
"/item": {
"get": {
"summary": "Get users",
"summary": "Get item",
"tags": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "User ID",
"example": 1
},
"name": {
"type": "string",
"description": "User name",
"example": "Adam Campbell"
},
"email": {
"type": "string",
"description": "User email address",
"format": "email",
"example": "[email protected]"
}
}
}
"$ref": "#/components/schemas/ExtendedItem"
},
"examples": {
"example-1": {
"value": [
{
"id": 1,
"name": "Adam Campbell",
"email": "[email protected]"
}
]
}
}
}
}
}
},
"operationId": "get-users",
"parameters": [
{
"schema": {
"type": "string",
"enum": [
"name",
"email"
]
},
"in": "query",
"name": "order",
"allowEmptyValue": true
}
]
},
"post": {
"summary": "Create user",
"tags": [],
"responses": {
"201": {
"description": "Created"
}
},
"operationId": "post-users",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "Adam Campbell"
},
"email": {
"type": "string",
"format": "email",
"example": "[email protected]"
}
},
"required": [
"name",
"email"
]
}
}
}
}
}
},
"/path-without-operationId": {
"get": {
"summary": "Get route without operationId",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"int": {
"type": "integer"
"value": {
"name": "Table",
"type": 1,
"description": "Furniture"
}
}
}
}
}
}
}
},
"operationId": "get-item"
}
}
},
"components": {
"schemas": {
"Name": {
"Item": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"MySchema": {
"title": "MySchema",
"ExtendedItem": {
"allOf": [
{
"$ref": "#/components/schemas/Name"
"$ref": "#/components/schemas/Item"
},
{
"type": "object",
Expand Down
26 changes: 22 additions & 4 deletions tests/ResponseValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ public function test_handle_nullables(
$version,
$state,
$is_valid
) {
)
{
Spectator::using("Nullable.{$version}.json");

Route::get('/users/{user}', function () use ($state) {
Expand Down Expand Up @@ -274,13 +275,30 @@ public function test_handles_invalid_spec()
->assertValidationMessage('The spec file is invalid. Please lint it using spectral (https://github.com/stoplightio/spectral) before trying again.');
}

// https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/
public function test_handles_components_allOf()
{
Spectator::using('Components.v1.yaml');
Spectator::using('Components.v1.json');

Route::get('/users')->middleware(Middleware::class);
Route::get('/item', function () {
return [
'name' => 'Table'
];
})->middleware(Middleware::class);

$this->getJson('/')
$this->getJson('/item')
->assertValidRequest()
->assertInvalidResponse();

Route::get('/item', function () {
return [
'name' => 'Table',
'type' => 1234,
'description' => 'Furniture'
];
})->middleware(Middleware::class);

$this->getJson('/item')
->assertValidRequest()
->assertValidResponse();
}
Expand Down

0 comments on commit f399e3a

Please sign in to comment.