Skip to content

Commit

Permalink
[Slim4] Add Mock feature documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ybelenko committed Jan 14, 2020
1 parent 4ac8a1b commit c3083d6
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ public void processOpts() {
additionalProperties.put("interfacesSrcPath", "./" + toSrcPath(interfacesPackage, srcBasePath));
additionalProperties.put("interfacesTestPath", "./" + toSrcPath(interfacesPackage, testBasePath));

// external docs folder
additionalProperties.put("docsBasePath", "./" + docsBasePath);

if (additionalProperties.containsKey(PSR7_IMPLEMENTATION)) {
this.setPsr7Implementation((String) additionalProperties.get(PSR7_IMPLEMENTATION));
}
Expand Down Expand Up @@ -152,6 +155,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("openapi_data_mocker_test.mustache", toSrcPath(mockPackage, testBasePath), "OpenApiDataMockerTest.php"));
supportingFiles.add(new SupportingFile("openapi_data_mocker_middleware.mustache", toSrcPath(mockPackage, srcBasePath), "OpenApiDataMockerMiddleware.php"));
supportingFiles.add(new SupportingFile("openapi_data_mocker_middleware_test.mustache", toSrcPath(mockPackage, testBasePath), "OpenApiDataMockerMiddlewareTest.php"));
supportingFiles.add(new SupportingFile("mock_server.mustache", docsBasePath, "MockServer.md"));

// traits of ported utils
supportingFiles.add(new SupportingFile("string_utils_trait.mustache", toSrcPath(utilsPackage, srcBasePath), toTraitName("StringUtils") + ".php"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Command | Target
`$ composer test` | All tests
`$ composer test-apis` | Apis tests
`$ composer test-models` | Models tests
`$ composer test-mock` | Mock feature tests
`$ composer test-utils` | Utils tests

#### Config

Expand Down Expand Up @@ -110,6 +112,8 @@ Switch on option in `./index.php`:
+++ $app->addErrorMiddleware(true, true, true);
```

## [Mock Server Documentation]({{docsBasePath}}/MockServer.md)

{{#generateApiDocs}}
## API Endpoints

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# {{packageName}} - PHP Slim 4 Server library for {{appName}}

## Mock Server Documentation

### Mocker Options
To enable mock server uncomment these lines in `index.php` config file:

```php
/**
* Mocker Middleware options.
*/
$config['mockerOptions'] = [
'dataMocker' => new OpenApiDataMocker(),

'getMockResponseCallback' => function (ServerRequestInterface $request, array $responses) {
// check if client clearly asks for mocked response
if (
$request->hasHeader('X-{{invokerPackage}}-Mock')
&& $request->getHeader('X-{{invokerPackage}}-Mock')[0] === 'ping'
) {
if (array_key_exists('default', $responses)) {
return $responses['default'];
}

// return first response
return $responses[array_key_first($responses)];
}

return false;
},

'afterCallback' => function ($request, $response) {
// mark mocked response to distinguish real and fake responses
return $response->withHeader('X-{{invokerPackage}}-Mock', 'pong');
},
];
```

* `dataMocker` is mocker class instance. To create custom data mocker extend `{{mockPackage}}\{{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}}`.
* `getMockResponseCallback` is callback before mock data generation. Above example shows how to enable mock feature for only requests with `{{X-{{invokerPackage}}}}-mock: ping` HTTP header. Adjust requests filtering to fit your project requirements. This function must return single response schema from `$responses` array parameter. **Mock feature is disabled when callback returns anything beside array.**
* `afterCallback` is callback executed after mock data generation. Most obvious use case is append specific HTTP headers to distinguish real and fake responses. **This function must always return response instance.**

### Supported features

All data types supported except specific string formats: `email`, `uuid`, `password` which are poorly implemented.

#### Data Types Support

| Data Type | Data Format | Supported |
|:---------:|:-----------:|:------------------:|
| `integer` | `int32` | :white_check_mark: |
| `integer` | `int64` | :white_check_mark: |
| `number` | `float` | :white_check_mark: |
| `number` | `double` | |
| `string` | `byte` | :white_check_mark: |
| `string` | `binary` | :white_check_mark: |
| `boolean` | | :white_check_mark: |
| `string` | `date` | :white_check_mark: |
| `string` | `date-time` | :white_check_mark: |
| `string` | `password` | :white_check_mark: |
| `string` | `email` | :white_check_mark: |
| `string` | `uuid` | :white_check_mark: |

#### Data Options Support

| Data Type | Option | Supported |
|:-----------:|:----------------------:|:------------------:|
| `string` | `minLength` | :white_check_mark: |
| `string` | `maxLength` | :white_check_mark: |
| `string` | `enum` | :white_check_mark: |
| `string` | `pattern` | |
| `integer` | `minimum` | :white_check_mark: |
| `integer` | `maximum` | :white_check_mark: |
| `integer` | `exclusiveMinimum` | :white_check_mark: |
| `integer` | `exclusiveMaximum` | :white_check_mark: |
| `number` | `minimum` | :white_check_mark: |
| `number` | `maximum` | :white_check_mark: |
| `number` | `exclusiveMinimum` | :white_check_mark: |
| `number` | `exclusiveMaximum` | :white_check_mark: |
| `array` | `items` | :white_check_mark: |
| `array` | `additionalItems` | |
| `array` | `minItems` | :white_check_mark: |
| `array` | `maxItems` | :white_check_mark: |
| `array` | `uniqueItems` | |
| `object` | `properties` | :white_check_mark: |
| `object` | `maxProperties` | |
| `object` | `minProperties` | |
| `object` | `patternProperties` | |
| `object` | `additionalProperties` | |
| `object` | `required` | |
| `*` | `$ref` | :white_check_mark: |
| `*` | `allOf` | |
| `*` | `anyOf` | |
| `*` | `oneOf` | |
| `*` | `not` | |

### Known Limitations

Avoid circular refs in your schema. Schema below can cause infinite loop and `Out of Memory` PHP error:
```yml
# ModelA has reference to ModelB while ModelB has reference to ModelA.
# Mock server will produce huge nested JSON example and ended with `Out of Memory` error.
definitions:
ModelA:
type: object
properties:
model_b:
$ref: '#/definitions/ModelB'
ModelB:
type: array
items:
$ref: '#/definitions/ModelA'
```

Don't ref scalar types, because generator will not produce models which mock server can find. So schema below will cause error:
```yml
# generated build contains only `OuterComposite` model class which referenced to not existed `OuterNumber`, `OuterString`, `OuterBoolean` classes
# mock server cannot mock `OuterComposite` model and throws exception
definitions:
OuterComposite:
type: object
properties:
my_number:
$ref: '#/definitions/OuterNumber'
my_string:
$ref: '#/definitions/OuterString'
my_boolean:
$ref: '#/definitions/OuterBoolean'
OuterNumber:
type: number
OuterString:
type: string
OuterBoolean:
type: boolean
```

0 comments on commit c3083d6

Please sign in to comment.