Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
strategy:
matrix:
php-version:
- "8.4"
- "8.3"
- "8.2"
- "8.1"
Expand Down
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 0,
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
Expand All @@ -61,7 +61,7 @@
"request": "launch",
"program": "${workspaceFolder}/vendor/bin/phpunit",
"cwd": "${workspaceFolder}",
"port": 0,
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
# PHP Swagger Test

[![Build Status](https://github.com/byjg/php-swagger-test/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-swagger-test/actions/workflows/phpunit.yml)
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-swagger-test/)
[![GitHub license](https://img.shields.io/github/license/byjg/php-swagger-test.svg)](https://opensource.byjg.com/opensource/licensing.html)
[![GitHub release](https://img.shields.io/github/release/byjg/php-swagger-test.svg)](https://github.com/byjg/php-swagger-test/releases/)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/byjg/php-swagger-test/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/byjg/php-swagger-test/?branch=master)

# PHP Swagger Test

A set of tools for testing your REST calls based on the OpenApi specification using PHPUnit.
Currently, this library supports the OpenApi specifications `2.0` (formerly swagger) and `3.0`.
Some features like callbacks, links and references to external documents/objects weren't implemented.

PHP Swagger Test can help you to test your REST Api. You can use this tool both for Unit Tests or Functional Tests.
Some features of the OpenAPI specification are not fully implemented:

- Callbacks (OpenAPI 3.0)
- Links (OpenAPI 3.0)
- References to external documents/objects
- Complex schema validations

For details on the schema classes and their specific features, see [Schema Classes](docs/schema-classes.md).

PHP Swagger Test can help you to test your REST API. You can use this tool both for Unit Tests or Functional Tests.

This tool reads a previously Swagger JSON file (not YAML) and enables you to test the request and response.
This tool reads an OpenAPI/Swagger specification in JSON format (not YAML) and enables you to test the request and
response.
You can use the tool "[https://github.com/zircote/swagger-php](https://github.com/zircote/swagger-php)" for creating the JSON file when you are developing your
rest API.
REST API.

The ApiTestCase's assertion process is based on throwing exceptions if some validation or test failed.

Expand All @@ -27,6 +36,7 @@ You can use the Swagger Test library as:
- [Contract test cases](docs/contract-tests.md)
- [Runtime parameters validator](docs/runtime-parameters-validator.md)
- [Mocking Requests and Validate your specification](docs/mock-requests.md)
- [Working with different schema versions](docs/schema-classes.md)

Who is using this library?

Expand Down Expand Up @@ -64,4 +74,4 @@ flowchart TD
byjg/swagger-test --> byjg/webrequest
```
----
[Open source ByJG](http://opensource.byjg.com)
[Open source ByJG](http://opensource.byjg.com)
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
"prefer-stable": true,
"license": "MIT",
"require": {
"php": ">=8.1 <8.4",
"php": ">=8.1 <8.5",
"ext-json": "*",
"byjg/webrequest": "^5.0"
"byjg/webrequest": "^6.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6",
"byjg/restserver": "^5.0",
"vimeo/psalm": "^5.9"
"phpunit/phpunit": "^10.5|^11.5",
"byjg/restserver": "^6.0",
"vimeo/psalm": "^5.9|^6.2"
},
"autoload": {
"psr-4": {
Expand Down
29 changes: 28 additions & 1 deletion docs/contract-tests.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
sidebar_position: 2
---

# Contract Tests

Sometimes, you want to run functional tests without making the actual HTTP
Expand Down Expand Up @@ -29,7 +33,30 @@ You now use an instance of this class in place of the `ApiRequester` class from
Of course, if you need to apply changes to the request, or the response in order
to fit your framework, this is exactly the right place to do it.

@todo: Explain in the Docs sections the `RestServer` component
## Using with RestServer component

The [byjg/restserver](https://github.com/byjg/php-restserver) component can be used to create a server that handles
requests based on OpenAPI/Swagger specifications. This is useful for testing your API without setting up a full web
server.

```php
<?php
use ByJG\RestServer\HttpRequestHandler;
use ByJG\RestServer\Route\OpenApiRouteList;

// Load the OpenAPI/Swagger specification
$specification = '/path/to/specification.json';

// Create a route definition based on the specification
$routeDefinition = new OpenApiRouteList($specification);

// Create a request handler and handle the routes
$restServer = new HttpRequestHandler();
$restServer->handle($routeDefinition);
```

This code will create a server that handles requests according to the routes defined in your OpenAPI/Swagger
specification.

## Using it as Unit Test cases

Expand Down
4 changes: 4 additions & 0 deletions docs/functional-tests.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
sidebar_position: 1
---

# Functional Test cases

Swagger Test provides the class `ApiTestCase` for you extend and create a PHPUnit test case. The code will try to
Expand Down
4 changes: 4 additions & 0 deletions docs/mock-requests.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
sidebar_position: 4
---

# Mock Requests

PHP Swagger has the class `MockRequester` with exact the same functionalities of `ApiRequester` class. The only
Expand Down
4 changes: 4 additions & 0 deletions docs/runtime-parameters-validator.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
sidebar_position: 3
---

# Runtime parameters validator

This tool was not developed only for unit and functional tests. You can use to validate if the required body
Expand Down
95 changes: 95 additions & 0 deletions docs/schema-classes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
sidebar_position: 5
---

# Schema Classes

PHP Swagger Test provides two main schema classes for working with different versions of the OpenAPI specification:

- `SwaggerSchema` - For OpenAPI 2.0 (formerly known as Swagger)
- `OpenApiSchema` - For OpenAPI 3.0

Both classes extend the abstract `Schema` class and provide specific implementations for their respective specification
versions.

## Creating Schema Instances

You can create a schema instance using the static `getInstance` method, which automatically determines the schema type
based on the provided data:

```php
<?php
// From a JSON string
$jsonString = file_get_contents('/path/to/specification.json');
$schema = \ByJG\ApiTools\Base\Schema::getInstance($jsonString);

// From an array
$schemaArray = json_decode(file_get_contents('/path/to/specification.json'), true);
$schema = \ByJG\ApiTools\Base\Schema::getInstance($schemaArray);
```

## SwaggerSchema Specific Features

The `SwaggerSchema` class provides specific methods for working with OpenAPI 2.0 (Swagger) specifications:

### Handling Null Values

OpenAPI 2.0 doesn't explicitly describe null values. The `SwaggerSchema` class provides a way to configure whether null
values should be allowed in responses:

```php
<?php
// When creating the schema
$schema = new \ByJG\ApiTools\Swagger\SwaggerSchema($data, true); // Allow null values

// Or after creation
$schema->setAllowNullValues(true); // Allow null values
$schema->setAllowNullValues(false); // Don't allow null values
```

## OpenApiSchema Specific Features

The `OpenApiSchema` class provides specific methods for working with OpenAPI 3.0 specifications:

### Server Variables

OpenAPI 3.0 allows defining server URLs with variables. The `OpenApiSchema` class provides a way to set these variables:

```php
<?php
// Example OpenAPI 3.0 specification with server variables
$openApiSpec = [
'openapi' => '3.0.0',
'servers' => [
[
'url' => 'https://{environment}.example.com/v1',
'variables' => [
'environment' => [
'default' => 'api',
'enum' => ['api', 'api.dev', 'api.staging']
]
]
]
]
];

$schema = new \ByJG\ApiTools\OpenApi\OpenApiSchema($openApiSpec);

// Set a server variable
$schema->setServerVariable('environment', 'api.dev');

// Now getServerUrl() will return 'https://api.dev.example.com/v1'
echo $schema->getServerUrl();
```

## Common Methods

Both schema classes provide the following common methods:

- `getServerUrl()` - Get the server URL from the specification
- `getBasePath()` - Get the base path from the specification
- `getPathDefinition($path, $method)` - Get the definition for a specific path and method
- `getRequestParameters($path, $method)` - Get the request parameters for a specific path and method
- `getResponseParameters($path, $method, $status)` - Get the response parameters for a specific path, method, and status
code
- `getDefinition($name)` - Get a definition by name
30 changes: 15 additions & 15 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ and open the template in the editor.
-->

<!-- see http://www.phpunit.de/wiki/Documentation -->
<phpunit bootstrap="./vendor/autoload.php"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="./vendor/autoload.php"
colors="true"
testdox="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
convertDeprecationsToExceptions="true"
stopOnFailure="false">
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnPhpunitDeprecations="true"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd">

<php>
<ini name="display_errors" value="On" />
<ini name="display_errors" value="On"/>
<ini name="display_startup_errors" value="On" />
<ini name="error_reporting" value="E_ALL" />
</php>

<filter>
<whitelist>
<directory>./src</directory>
</whitelist>
</filter>

<source>
<include>
<directory>./src/</directory>
</include>
</source>
<testsuites>
<testsuite name="Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>

</phpunit>
6 changes: 3 additions & 3 deletions src/AbstractRequester.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
use ByJG\ApiTools\Exception\PathNotFoundException;
use ByJG\ApiTools\Exception\RequiredArgumentNotFound;
use ByJG\ApiTools\Exception\StatusCodeNotMatchedException;
use ByJG\Util\Uri;
use ByJG\WebRequest\Exception\MessageException;
use ByJG\WebRequest\Exception\RequestException;
use ByJG\WebRequest\Psr7\Request;
use ByJG\Util\Uri;
use ByJG\WebRequest\Psr7\MemoryStream;
use ByJG\WebRequest\Psr7\Request;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -126,7 +126,7 @@ public function withRequestHeader(string|array $requestHeader): self
* @param array|null $query
* @return $this
*/
public function withQuery(array $query = null): self
public function withQuery(?array $query = null): self
{
$uri = $this->psr7Request->getUri();

Expand Down
2 changes: 2 additions & 0 deletions src/ApiRequester.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use ByJG\WebRequest\Exception\NetworkException;
use ByJG\WebRequest\Exception\RequestException;
use ByJG\WebRequest\HttpClient;
use Override;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -36,6 +37,7 @@ public function __construct()
* @throws NetworkException
* @throws RequestException
*/
#[Override]
protected function handleRequest(RequestInterface $request): ResponseInterface
{
$request = $request->withHeader("User-Agent", "ByJG Swagger Test");
Expand Down
Loading