diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 410a8b9..685a9c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,8 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@v2 + with: + php-version: "8.0" - name: Install composer dependencies uses: ramsey/composer-install@v2 @@ -35,6 +37,8 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@v2 + with: + php-version: "8.0" - name: Install composer dependencies uses: ramsey/composer-install@v2 diff --git a/src/ValidatorBuilder.php b/src/ValidatorBuilder.php index 6d6f1d4..aa52482 100644 --- a/src/ValidatorBuilder.php +++ b/src/ValidatorBuilder.php @@ -5,10 +5,11 @@ namespace Osteel\OpenApi\Testing; use cebe\openapi\Reader; +use cebe\openapi\ReferenceContext; use InvalidArgumentException; use League\OpenAPIValidation\PSR7\ValidatorBuilder as BaseValidatorBuilder; -use Osteel\OpenApi\Testing\Adapters\MessageAdapterInterface; use Osteel\OpenApi\Testing\Adapters\HttpFoundationAdapter; +use Osteel\OpenApi\Testing\Adapters\MessageAdapterInterface; use Osteel\OpenApi\Testing\Cache\CacheAdapterInterface; use Osteel\OpenApi\Testing\Cache\Psr16Adapter; @@ -34,9 +35,9 @@ public function __construct(private BaseValidatorBuilder $validatorBuilder) */ public static function fromYaml(string $definition): ValidatorBuilderInterface { - $method = self::isUrl($definition) || is_file($definition) ? 'readFromYamlFile' : 'readFromYaml'; - - return self::fromMethod($method, $definition); + return self::isUrl($definition) || is_file($definition) + ? self::fromYamlFile($definition) + : self::fromYamlString($definition); } /** @@ -46,9 +47,9 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface */ public static function fromJson(string $definition): ValidatorBuilderInterface { - $method = self::isUrl($definition) || is_file($definition) ? 'readFromJsonFile' : 'readFromJson'; - - return self::fromMethod($method, $definition); + return self::isUrl($definition) || is_file($definition) + ? self::fromJsonFile($definition) + : self::fromJsonString($definition); } private static function isUrl(string $value): bool @@ -89,7 +90,7 @@ public static function fromJsonFile(string $definition): ValidatorBuilderInterfa */ public static function fromYamlString(string $definition): ValidatorBuilderInterface { - return self::fromMethod('readFromYaml', $definition); + return self::fromMethod('readFromYaml', $definition, resolveReferences: true); } /** @@ -99,18 +100,22 @@ public static function fromYamlString(string $definition): ValidatorBuilderInter */ public static function fromJsonString(string $definition): ValidatorBuilderInterface { - return self::fromMethod('readFromJson', $definition); + return self::fromMethod('readFromJson', $definition, resolveReferences: true); } /** * Create a Validator object based on an OpenAPI definition. * - * @param string $method the ValidatorBuilder object's method to use - * @param string $definition the OpenAPI definition + * @param string $method the ValidatorBuilder object's method to use + * @param string $definition the OpenAPI definition + * @param bool $resolveReferences whether to resolve references in the definition */ - private static function fromMethod(string $method, string $definition): ValidatorBuilderInterface + private static function fromMethod(string $method, string $definition, bool $resolveReferences = false): ValidatorBuilderInterface { $specObject = Reader::{$method}($definition); + + $resolveReferences && $specObject->resolveReferences(new ReferenceContext($specObject, '/')); + $builder = (new BaseValidatorBuilder())->fromSchema($specObject); return new ValidatorBuilder($builder); diff --git a/tests/stubs/example.json b/tests/stubs/example.json index c0cca51..4735156 100644 --- a/tests/stubs/example.json +++ b/tests/stubs/example.json @@ -18,16 +18,7 @@ "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "foo" - ], - "properties": { - "foo": { - "type": "string", - "example": "bar" - } - } + "$ref": "#/components/schemas/Test" } } } @@ -135,5 +126,21 @@ } } } + }, + "components": { + "schemas": { + "Test": { + "type": "object", + "required": [ + "foo" + ], + "properties": { + "foo": { + "type": "string", + "example": "bar" + } + } + } + } } } diff --git a/tests/stubs/example.yaml b/tests/stubs/example.yaml index 11964d4..2005c8a 100644 --- a/tests/stubs/example.yaml +++ b/tests/stubs/example.yaml @@ -16,13 +16,7 @@ paths: content: application/json: schema: - type: object - required: - - foo - properties: - foo: - type: string - example: bar + $ref: '#/components/schemas/Test' post: requestBody: content: @@ -81,3 +75,14 @@ paths: responses: '204': description: No content + +components: + schemas: + Test: + type: object + required: + - foo + properties: + foo: + type: string + example: bar \ No newline at end of file