A PHP library for validating Symfony application requests and responses against OpenAPI specifications. This library provides PHPUnit integration through traits and automatic test case generation.
- 🚀 Easy PHPUnit Integration: Use the
OpenApiValidationTraitin your test classes - 🔄 Automatic Test Generation: Generate test cases from OpenAPI specifications
- 🎯 Request/Response Validation: Validate both HTTP requests and responses
- 🗺️ Path Mapping: Map OpenAPI paths to your actual application routes
- 🧪 Symfony Integration: Works seamlessly with Symfony's test client
Install via Composer:
composer require --dev gpht/openapi-symfony-validator- PHP ^8.4
- Symfony ^6.0|^7.0
- PHPUnit ^10.0|^11.0
The easiest way to use this library is with the OpenApiValidationTrait:
<?php
declare(strict_types=1);
namespace App\Tests\Imperative;
use Gpht\OpenapiSymfonyValidator\OpenApiValidationTrait;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\Security\Core\User\OidcUser;
final class OpenApiValidationTest extends ImperativeTestCase
{
use OpenApiValidationTrait;
public function client(): KernelBrowser
{
$user = new OidcUser(
userIdentifier: 'test-user-123',
roles: ['ROLE_USER'],
sub: 'test-user-123',
email: 'test@example.com',
);
return self::$client->loginUser($user);
}
public static function openApiPath(): string
{
return __DIR__ . '/../../api/sync/public/openapi.yaml';
}
public static function apiMap(): array
{
return [
'/workflow-service/product' => '/public/product',
'/workflow-service/favorite-photos/update-favorite-photo/{guestAccessId}/{photoId}/{role}' => '/public/favorite-photos/update-favorite-photo/{guestAccessId}/{photoId}/{role}',
'/workflow-service/favorite-photos/get-favorite-for-access-code/{guestAccessId}' => '/public/favorite-photos/get-favorite-for-access-code/{guestAccessId}',
];
}
}The trait will automatically:
- Generate test cases from your OpenAPI specification
- Create PHPUnit data providers
- Execute tests for each endpoint with the configured client
- Validate both requests and responses against the OpenAPI schema
Important: All parameters in your OpenAPI specification must have either an example or default value. The library uses these values to generate test requests.
paths:
/products:
get:
summary: Get products
parameters:
- name: category
in: query
description: Filter products by category
schema:
type: string
example: "prints"
- name: page
in: query
description: Page number for pagination
schema:
type: integer
default: 1
example: 1
- name: limit
in: query
description: Number of items per page
schema:
type: integer
default: 10
example: 25
- name: userId
in: path
description: User identifier
required: true
schema:
type: string
example: "user-123"The apiMap() method maps OpenAPI paths to your actual application routes:
- Key: The path as defined in your OpenAPI specification
- Value: The actual route path in your Symfony application
public static function apiMap(): array
{
return [
// OpenAPI path => Actual application path
'/api/users/{id}' => '/public/users/{id}',
'/api/products' => '/internal/products',
];
}For complex validation scenarios, you can use the OpenApiValidator class directly or fall back to the underlying league/openapi-psr7-validator library:
use Gpht\OpenapiSymfonyValidator\OpenApiValidator;
use League\OpenAPIValidation\PSR7\ValidatorBuilder;
// Using OpenApiValidator directly
$validator = new OpenApiValidator('/path/to/openapi.yaml', $pathMappings);
$validator->validateRequestResponse($client, 'GET', '/actual/path', '/openapi/path', [], [], null);
// Using league/openapi-psr7-validator directly for complex cases
$validatorBuilder = new ValidatorBuilder();
$requestValidator = $validatorBuilder->fromYamlFile('/path/to/openapi.yaml')->getRequestValidator();
$responseValidator = $validatorBuilder->getResponseValidator();
// Custom validation logic...This project uses Mago for code formatting and linting, plus Psalm for static analysis:
# Format code
composer format
# Check formatting
composer format-check
# Run linter
composer lint
# Run static analysis
composer psalm
# Run all checks
composer format-check && composer lint && composer psalmRun the test suite:
composer testThe project includes a comprehensive CI pipeline that runs:
- Mago formatting checks
- Mago linting
- Psalm static analysis
- PHPUnit tests
MIT
- Fork the repository
- Create a feature branch
- Make your changes
- Run the code quality checks:
composer format-check && composer lint && composer psalm - Run tests:
composer test - Submit a pull request
- All parameters must have
exampleordefaultvalues - Path parameters are automatically replaced in both OpenAPI and actual paths
- Query parameters without values will be excluded from minimal test cases
- The library supports all standard HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)