Skip to content

Commit

Permalink
Move openapi build logic out of constructor (#469)
Browse files Browse the repository at this point in the history
* Move openapi build logic out of constructor #454

* set phptsan to version ^1.8.5 to resolve false-positives

* update readme
  • Loading branch information
cnizzardini authored Sep 17, 2022
1 parent 267100c commit e961188
Show file tree
Hide file tree
Showing 32 changed files with 118 additions and 94 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ to SwaggerUI (or Redoc) in your web browser.
- You can also generate OpenAPI programmatically:

```php
$swagger = (new \SwaggerBake\Lib\SwaggerFactory())->create();
$swagger = (new \SwaggerBake\Lib\SwaggerFactory())->create()->build();
$swagger->getArray(); # returns swagger array
$swagger->toString(); # returns swagger json
$swagger->writeFile('/full/path/to/your/swagger.json'); # writes swagger.json
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"friendsofcake/search": "^6.0",
"cakephp/authentication": "^2.0",
"cakephp/cakephp-codesniffer": "^4.2",
"phpstan/phpstan": "^1.0",
"phpstan/phpstan": "^1.8.5",
"phpmd/phpmd": "^2.10",
"cakephp/bake": "^2.1"
},
Expand Down
3 changes: 2 additions & 1 deletion src/Lib/Service/OpenApiBakerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ class OpenApiBakerService
* @param string $filePath The file path to write the openapi json to
* @return string
* @throws \SwaggerBake\Lib\Exception\SwaggerBakeRunTimeException
* @throws \ReflectionException
*/
public function bake(Swagger $swagger, string $filePath): string
{
$swagger->writeFile($filePath);
$swagger->build()->writeFile($filePath);
foreach ($swagger->getOperationsWithNoHttp20x() as $operation) {
$this->warnings[] = 'Operation ' . $operation->getOperationId() . ' does not have a HTTP 20x response';
}
Expand Down
3 changes: 2 additions & 1 deletion src/Lib/Service/OpenApiControllerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public function __construct(
* Rebuilds OpenAPI if hot reload is enabled and logs warnings if debug is enabled
*
* @return void
* @throws \ReflectionException
*/
public function build(): void
{
if ($this->config->isHotReload()) {
$output = $this->config->getJson();
$this->swagger->writeFile($output);
$this->swagger->build()->writeFile($output);
}
}

Expand Down
41 changes: 25 additions & 16 deletions src/Lib/Swagger.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,47 @@ class Swagger

private array $array = [];

private Configuration $config;

private FileUtility $fileUtility;

/**
* @param \SwaggerBake\Lib\Model\ModelScanner $modelScanner ModelScanner instance
* @param \SwaggerBake\Lib\Configuration $configuration Configuration instance
* @param \SwaggerBake\Lib\Configuration $config Configuration instance
* @param \SwaggerBake\Lib\Utility\FileUtility|null $fileUtility FileUtility will be created automatically if
* argument is null.
* @throws \ReflectionException
*/
public function __construct(
ModelScanner $modelScanner,
Configuration $configuration,
?FileUtility $fileUtility = null
private ModelScanner $modelScanner,
private Configuration $config,
private ?FileUtility $fileUtility = null
) {
$this->config = $configuration;
$this->fileUtility = $fileUtility ?? new FileUtility();
}

/**
* Builds an OpenAPI array that can be converted to JSON.
*
* @return \SwaggerBake\Lib\Swagger
* @throws \ReflectionException
*/
public function build()
{
$this->array = (new OpenApiFromYaml())->build(Yaml::parseFile($this->config->getYml()));

EventManager::instance()->dispatch(
new Event('SwaggerBake.initialize', $this)
);

$xSwaggerBake = Yaml::parseFile(self::ASSETS . 'x-swagger-bake.yaml');

$this->array['x-swagger-bake'] = array_merge_recursive(
$xSwaggerBake['x-swagger-bake'],
$this->array['x-swagger-bake'] ?? []
);

$this->array = (new OpenApiSchemaGenerator($modelScanner))->generate($this->array);
$this->array = (new OpenApiPathGenerator($this, $modelScanner->getRouteScanner(), $this->config))
EventManager::instance()->dispatch(
new Event('SwaggerBake.initialize', $this)
);

$this->array = (new OpenApiSchemaGenerator($this->modelScanner))->generate($this->array);
$this->array = (new OpenApiPathGenerator($this, $this->modelScanner->getRouteScanner(), $this->config))
->generate($this->array);

return $this;
}

/**
Expand All @@ -87,7 +93,10 @@ public function getArray(): array
}
}

ksort($this->array['paths'], SORT_STRING);
if (is_array($this->array['paths'])) {
ksort($this->array['paths'], SORT_STRING);
}

if (is_array($this->array['components']['schemas'])) {
uksort($this->array['components']['schemas'], function ($a, $b) {
return strcasecmp(
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/Lib/Attribute/OpenApiDtoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function setUp(): void
public function test_openapi_dto_query(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);
$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);


Expand All @@ -101,7 +101,7 @@ public function test_openapi_dto_query(): void
public function test_openapi_dto_post(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);
$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function test_entity_attribute(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();

$arr = json_decode($swagger->toString(), true);

Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function test_open_api_form(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$operation = $arr['paths']['/employees/custom-post']['post'];
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiHeaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function test(): void
$this->__setUp();
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$this->assertArrayHasKey('/employees/custom-get', $arr['paths']);
Expand Down
14 changes: 7 additions & 7 deletions tests/TestCase/Lib/Attribute/OpenApiOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,45 +85,45 @@ public function setUp(): void

$configuration = new Configuration($this->config, SWAGGER_BAKE_TEST_APP);
$cakeRoute = new RouteScanner($this->router, $configuration);
$this->swagger = new Swagger(new ModelScanner($cakeRoute, $configuration), $configuration);
$this->swagger = (new Swagger(new ModelScanner($cakeRoute, $configuration), $configuration))->build();
}

public function test_descriptions(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertEquals('summary...', $arr['paths']['/operations/descriptions']['get']['summary']);
$this->assertEquals('desc...', $arr['paths']['/operations/descriptions']['get']['description']);
}

public function test_is_visible(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertArrayNotHasKey('/operations/is-visible', $arr['paths']);
}

public function test_operation_tags_names_should_take_precedence(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertCount(4, $arr['paths']['/operations/tag-names']['get']['tags']);
}

public function test_is_deprecated(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertTrue($arr['paths']['/operations/deprecated']['get']['deprecated']);
}

public function test_external_docs(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$externalDocs = $arr['paths']['/operations/external-docs']['get']['externalDocs'];
$this->assertEquals('http://localhost', $externalDocs['url']);
$this->assertEquals('desc...', $externalDocs['description']);
}

public function test_path_tags_should_take_precedence(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertCount(2, $arr['paths']['/operations/deprecated']['get']['tags']);
$this->assertCount(2, $arr['paths']['/operations/external-docs']['get']['tags']);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiPaginatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function test_paginator(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$this->assertArrayHasKey('/departments', $arr['paths']);
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiPathParamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function test(): void

$cakeRoute = new RouteScanner($router, $config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $config), $config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $config), $config))->build();
$arr = json_decode($swagger->toString(), true);

$params = $arr['paths']['/operation-path/path-parameter/{id}']['get']['parameters'];
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/Lib/Attribute/OpenApiPathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function test_summary_and_description(): void

$cakeRoute = new RouteScanner($this->router, $config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $config), $config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $config), $config))->build();

$arr = json_decode($swagger->toString(), true);
$employees = $arr['paths']['/employees'];
Expand All @@ -72,7 +72,7 @@ public function test_invisible(): void

$cakeRoute = new RouteScanner($this->router, $config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $config), $config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $config), $config))->build();

$arr = json_decode($swagger->toString(), true);

Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiQueryParamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function test_openapi_query(): void
$this->__setUp();
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$this->assertArrayHasKey('/departments', $arr['paths']);
Expand Down
8 changes: 4 additions & 4 deletions tests/TestCase/Lib/Attribute/OpenApiRequestBodyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function test_open_api_request_body(): void
{
$routeScanner = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($routeScanner, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($routeScanner, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$operation = $arr['paths']['/employees/custom-post']['post'];
Expand All @@ -98,7 +98,7 @@ public function test_request_body_content(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$operation = $arr['paths']['/request-body/text-plain']['post'];
Expand All @@ -110,7 +110,7 @@ public function test_multiple_mime_types(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$operation = $arr['paths']['/request-body/multiple-mime-types']['post'];
Expand All @@ -122,7 +122,7 @@ public function test_use_mime_types_from_config(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$operation = $arr['paths']['/request-body/use-config-defaults']['post'];
Expand Down
10 changes: 5 additions & 5 deletions tests/TestCase/Lib/Attribute/OpenApiResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ public function setUp(): void
], SWAGGER_BAKE_TEST_APP);

$cakeRoute = new RouteScanner($router, $config);
$this->swagger = new Swagger(new ModelScanner($cakeRoute, $config), $config);
$this->swagger = (new Swagger(new ModelScanner($cakeRoute, $config), $config))->build();
}

public function test_openapi_response_ref(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);

$operation = $arr['paths']['/employees/custom-response-ref']['get'];

Expand All @@ -99,7 +99,7 @@ public function test_openapi_response_ref(): void

public function test_openapi_response_schema(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$operation = $arr['paths']['/employees/custom-response-schema']['get'];
$schema = $operation['responses'][200]['content']['application/json']['schema'];
$this->assertEquals('Custom Title', $schema['title']);
Expand All @@ -109,7 +109,7 @@ public function test_openapi_response_schema(): void

public function test_openapi_response_schema_public(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$this->assertArrayHasKey('CustomResponseSchemaPublic', $arr['components']['schemas']);
$properties = $arr['components']['schemas']['CustomResponseSchemaPublic']['properties'];
$this->assertArrayHasKey('name', $properties);
Expand All @@ -122,7 +122,7 @@ public function test_openapi_response_schema_public(): void

public function test_openapi_response_schema_public_array(): void
{
$arr = json_decode($this->swagger->toString(), true);
$arr = json_decode($this->swagger->build()->toString(), true);
$operation = $arr['paths']['/employees/custom-response-schema-public-array']['get'];
$ref = $operation['responses'][200]['content']['application/json']['schema']['items']['$ref'];
$this->assertEquals('#/components/schemas/CustomResponseSchemaPublic', $ref);
Expand Down
8 changes: 4 additions & 4 deletions tests/TestCase/Lib/Attribute/OpenApiSchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function test_entity_exists(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();

$arr = json_decode($swagger->toString(), true);

Expand All @@ -74,7 +74,7 @@ public function test_schema_never_visible(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();

$arr = json_decode($swagger->toString(), true);

Expand All @@ -89,7 +89,7 @@ public function test_schema_is_hidden(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();

$arr = json_decode($swagger->toString(), true);

Expand All @@ -101,7 +101,7 @@ public function test_entity_attribute(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();

$arr = json_decode($swagger->toString(), true);

Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Attribute/OpenApiSecurityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function test_swag_security(): void
{
$cakeRoute = new RouteScanner($this->router, $this->config);

$swagger = new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
$arr = json_decode($swagger->toString(), true);

$this->assertArrayHasKey('/employees/custom-get', $arr['paths']);
Expand Down
2 changes: 1 addition & 1 deletion tests/TestCase/Lib/Extension/CakeSearch/ExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function test_search_parameters_exist_in_openapi_output(): void
$configuration = new Configuration($this->config, SWAGGER_BAKE_TEST_APP);

$cakeRoute = new RouteScanner($this->router, $configuration);
$swagger = new Swagger(new ModelScanner($cakeRoute, $configuration), $configuration);
$swagger = (new Swagger(new ModelScanner($cakeRoute, $configuration), $configuration))->build();

$arr = json_decode($swagger->toString(), true);

Expand Down
Loading

0 comments on commit e961188

Please sign in to comment.