diff --git a/README.md b/README.md
index 446c9ff8..dc04ca36 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,9 @@ build the following from your existing routes and models without additional effo
- Sub resources
- Schema
-SwaggerBake works with your existing YML definitions and will not overwrite anything.
+SwaggerBake works with your existing YML definitions and will not overwrite anything. By default, it uses
+components > schemas > Exception as your Swagger documentations Exception schema. See the default
+[swagger.yml](assets/swagger.yml) and `exceptionSchema` in [swagger_bake.php](assets/swagger_bake.php) for more info.
## Doc Blocks
@@ -123,7 +125,7 @@ Method level annotation for adding query parameters.
```php
/**
- * @Swag\SwagQuery(name="queryParamName", type="string", required=false)
+ * @Swag\SwagQuery(name="queryParamName", type="string", description="string", required=false)
*/
public function index() {}
```
@@ -133,7 +135,7 @@ Method level annotation for adding form data fields.
```php
/**
- * @Swag\SwagForm(name="fieldName", type="string", required=false)
+ * @Swag\SwagForm(name="fieldName", type="string", description="string", required=false)
*/
public function index() {}
```
@@ -143,7 +145,7 @@ Method level annotation for adding header parameters.
```php
/**
- * @Swag\SwagHeader(name="X-HEAD-ATTRIBUTE", type="string", required=false)
+ * @Swag\SwagHeader(name="X-HEAD-ATTRIBUTE", type="string", description="string", required=false)
*/
public function index() {}
```
@@ -183,8 +185,7 @@ Method level annotation for describing custom content in request body.
```php
/**
- * @Swag\SwagRequestBodyContent(refEntity="#/components/schemas/Lead", mimeType="application/x-www-form-urlencoded")
- * @Swag\SwagRequestBodyContent(refEntity="", mimeType="text/plain")
+ * @Swag\SwagRequestBodyContent(refEntity="#/components/schemas/Lead", mimeType="application/json")
*/
public function index() {}
```
@@ -225,7 +226,7 @@ Class level annotation for customizing Schema Attributes with @SwagEntityAttribu
```php
/**
- * @Swag\SwagEntityAttribute(name="modified", type="string", readOnly=true, required=false)
+ * @Swag\SwagEntityAttribute(name="modified", type="string", description="string", readOnly=true, required=false)
*/
class Employee extends Entity {
```
@@ -343,6 +344,11 @@ paths using CakePHPs route resource functionality. Read the
[Cake Routing documentation](https://book.cakephp.org/4/en/development/routing.html) which describes in detail how to
add, remove, modify, and alter routes.
+#### Missing CSRF token body
+
+Either disable CSRF protection on your main route in `config/routes.php` or enable CSRF protection in Swagger
+UI. The library does not currently support adding this in for you.
+
## Reporting Issues
This is a new library so please take some steps before reporting issues. You can copy & paste the JSON SwaggerBake
diff --git a/assets/swagger.yml b/assets/swagger.yml
index 94ca3730..ad5d65dc 100644
--- a/assets/swagger.yml
+++ b/assets/swagger.yml
@@ -9,3 +9,18 @@ servers:
paths:
definitions:
+
+components:
+ schemas:
+ Exception:
+ type: object
+ properties:
+ code:
+ type: integer
+ example: 500
+ url:
+ type: string
+ example: /url/path
+ message:
+ type: string
+ example: Internal Error
diff --git a/assets/swagger_bake.php b/assets/swagger_bake.php
index b13e3759..e9fb2412 100644
--- a/assets/swagger_bake.php
+++ b/assets/swagger_bake.php
@@ -13,6 +13,8 @@
*
* @var string $docType: Options are swagger and redoc, defaults: swagger
*
+ * @var string $exceptionSchema: The name of your Exception schema in your swagger.yml definition file.
+ *
* @var array $namespaces: Can be used if your controllers or entities exist in non-standard namespace such as a plugin
*/
return [
@@ -21,13 +23,17 @@
'yml' => '/config/swagger.yml',
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
- 'hotReload' => false,
+ 'hotReload' => \Cake\Core\Configure::read('debug'),
+ /** optional configurations below: **/
+ /*
'docType' => 'swagger',
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\App\\'],
'entities' => ['\App\\'],
'tables' => ['\App\\']
]
+ */
]
];
diff --git a/src/Command/ModelCommand.php b/src/Command/ModelCommand.php
index 305d4404..8400df3d 100644
--- a/src/Command/ModelCommand.php
+++ b/src/Command/ModelCommand.php
@@ -25,7 +25,9 @@ class ModelCommand extends Command
*/
public function execute(Arguments $args, ConsoleIo $io)
{
- $io->out("Running...");
+ $io->hr();
+ $io->out("| SwaggerBake is checking your models...");
+ $io->hr();
ValidateConfiguration::validate();
@@ -36,7 +38,11 @@ public function execute(Arguments $args, ConsoleIo $io)
$models = $cakeModel->getModels();
if (empty($models)) {
- return $io->warning('No models found');
+ $io->out();
+ $io->warning('No models were found that are associated with: ' . $config->getPrefix());
+ $io->out("Have you added RESTful routes? Do you have models associated with those routes?");
+ $io->out();
+ return;
}
$header = ['Attribute','Data Type', 'Swagger Type','Default','Primary Key'];
diff --git a/src/Command/RouteCommand.php b/src/Command/RouteCommand.php
index e8d620bf..70131d3b 100644
--- a/src/Command/RouteCommand.php
+++ b/src/Command/RouteCommand.php
@@ -25,12 +25,14 @@ class RouteCommand extends Command
*/
public function execute(Arguments $args, ConsoleIo $io)
{
- $io->out("Running...");
+ $io->hr();
+ $io->out("| SwaggerBake is checking your routes...");
+ $io->hr();
ValidateConfiguration::validate();
$output = [
- ['Route name', 'URI template', 'Defaults'],
+ ['Route name', 'URI template', 'Method(s)', 'Controller', 'Action', 'Plugin'],
];
$config = new Configuration();
@@ -39,15 +41,22 @@ public function execute(Arguments $args, ConsoleIo $io)
$routes = $cakeRoute->getRoutes();
if (empty($routes)) {
- $io->out("No routes were found for: $prefix");
- $io->out('https://book.cakephp.org/4/en/development/routing.html#restful-routing');
+ $io->out();
+ $io->warning("No routes were found for: $prefix");
+ $io->out("Have you added RESTful routes? Do you have models associated with those routes?");
+ $io->out();
return;
}
foreach ($routes as $route) {
- $name = $route->options['_name'] ?? $route->getName();
- ksort($route->defaults);
- $output[] = [$name, $route->template, json_encode($route->defaults)];
+ $output[] = [
+ $route->getName(),
+ $route->getTemplate(),
+ implode(', ', $route->getMethods()),
+ $route->getController(),
+ $route->getAction(),
+ $route->getPlugin(),
+ ];
}
$io->helper('table')->output($output);
diff --git a/src/Lib/AbstractParameter.php b/src/Lib/AbstractParameter.php
index 8bbb3b1e..e2d86531 100644
--- a/src/Lib/AbstractParameter.php
+++ b/src/Lib/AbstractParameter.php
@@ -2,10 +2,10 @@
namespace SwaggerBake\Lib;
-use Cake\Routing\Route\Route;
use Doctrine\Common\Annotations\AnnotationReader;
use ReflectionClass;
use SwaggerBake\Lib\Exception\SwaggerBakeRunTimeException;
+use SwaggerBake\Lib\Model\ExpressiveRoute;
class AbstractParameter
{
@@ -18,14 +18,13 @@ class AbstractParameter
protected $reflectionMethods;
protected $config;
- public function __construct(Route $route, Configuration $config)
+ public function __construct(ExpressiveRoute $route, Configuration $config)
{
$this->config = $config;
$this->route = $route;
- $defaults = (array) $this->route->defaults;
- $this->actionName = $defaults['action'];
- $this->className = $defaults['controller'] . 'Controller';
+ $this->actionName = $this->route->getAction();
+ $this->className = $this->route->getController() . 'Controller';
$this->controller = $this->getControllerFromNamespaces($this->className);
$instance = new $this->controller;
diff --git a/src/Lib/Annotation/SwagEntity.php b/src/Lib/Annotation/SwagEntity.php
index 4ec8f2e9..00bf514e 100644
--- a/src/Lib/Annotation/SwagEntity.php
+++ b/src/Lib/Annotation/SwagEntity.php
@@ -13,6 +13,7 @@
*/
class SwagEntity
{
+ /** @var bool **/
public $isVisible;
public function __construct(array $values)
diff --git a/src/Lib/Annotation/SwagEntityAttribute.php b/src/Lib/Annotation/SwagEntityAttribute.php
index f4c9a41b..7a020970 100644
--- a/src/Lib/Annotation/SwagEntityAttribute.php
+++ b/src/Lib/Annotation/SwagEntityAttribute.php
@@ -10,6 +10,7 @@
* @Attributes({
* @Attribute("name", type = "string"),
* @Attribute("type", type = "string"),
+ * @Attribute("description", type = "string"),
* @Attribute("readOnly", type = "bool"),
* @Attribute("writeOnly", type = "bool"),
* @Attribute("required", type = "bool"),
@@ -17,10 +18,22 @@
*/
class SwagEntityAttribute
{
+ /** @var string */
public $name;
+
+ /** @var string */
public $type;
+
+ /** @var string */
+ public $description;
+
+ /** @var bool */
public $readOnly;
+
+ /** @var bool */
public $writeOnly;
+
+ /** @var bool */
public $required;
public function __construct(array $values)
@@ -30,12 +43,13 @@ public function __construct(array $values)
}
$values = array_merge(
- ['type' => 'string', 'readOnly' => false, 'writeOnly' => false, 'required' => false],
+ ['type' => 'string', 'description' => '', 'readOnly' => false, 'writeOnly' => false, 'required' => false],
$values
);
$this->name = $values['name'];
$this->type = $values['type'];
+ $this->description = $values['description'];
$this->readOnly = $values['readOnly'];
$this->writeOnly = $values['writeOnly'];
$this->required = $values['required'];
diff --git a/src/Lib/Annotation/SwagEntityAttributeHandler.php b/src/Lib/Annotation/SwagEntityAttributeHandler.php
index d4a9ee96..d9e8e35b 100644
--- a/src/Lib/Annotation/SwagEntityAttributeHandler.php
+++ b/src/Lib/Annotation/SwagEntityAttributeHandler.php
@@ -11,6 +11,7 @@ public function getSchemaProperty(SwagEntityAttribute $annotation) : SchemaPrope
$schemaProperty = new SchemaProperty();
$schemaProperty
->setName($annotation->name)
+ ->setDescription($annotation->description)
->setType($annotation->type)
->setReadOnly($annotation->readOnly)
->setWriteOnly($annotation->writeOnly)
diff --git a/src/Lib/Annotation/SwagForm.php b/src/Lib/Annotation/SwagForm.php
index 33f146de..b5c14a9a 100644
--- a/src/Lib/Annotation/SwagForm.php
+++ b/src/Lib/Annotation/SwagForm.php
@@ -12,13 +12,22 @@
* @Attributes({
* @Attribute("name", type = "string"),
* @Attribute("type", type = "string"),
- * @Attribute("required", type = "bool"),
+ * @Attribute("description", type="string"),
+ * @Attribute("required", type="boolean"),
* })
*/
class SwagForm
{
+ /** @var string */
public $name;
+
+ /** @var string */
public $type;
+
+ /** @var string */
+ public $description;
+
+ /** @var bool */
public $required;
public function __construct(array $values)
@@ -27,7 +36,7 @@ public function __construct(array $values)
throw new InvalidArgumentException('Name parameter is required');
}
- $values = array_merge(['type' => 'string', 'required' => false], $values);
+ $values = array_merge(['type' => 'string', 'description' => '', 'required' => false], $values);
if (!in_array($values['type'], OpenApiDataType::TYPES)) {
$type = $values['type'];
@@ -42,6 +51,7 @@ public function __construct(array $values)
$this->name = $values['name'];
$this->type = $values['type'];
- $this->required = $values['required'];
+ $this->description = $values['description'];
+ $this->required = (bool) $values['required'];
}
}
\ No newline at end of file
diff --git a/src/Lib/Annotation/SwagFormHandler.php b/src/Lib/Annotation/SwagFormHandler.php
index 4348ecea..c9a11328 100644
--- a/src/Lib/Annotation/SwagFormHandler.php
+++ b/src/Lib/Annotation/SwagFormHandler.php
@@ -10,6 +10,7 @@ public function getSchemaProperty(SwagForm $annotation) : SchemaProperty
{
$schemaProperty = new SchemaProperty();
$schemaProperty
+ ->setDescription($annotation->description)
->setName($annotation->name)
->setType($annotation->type)
->setRequired($annotation->required)
diff --git a/src/Lib/Annotation/SwagHeader.php b/src/Lib/Annotation/SwagHeader.php
index b242ce51..c7f725fd 100644
--- a/src/Lib/Annotation/SwagHeader.php
+++ b/src/Lib/Annotation/SwagHeader.php
@@ -10,13 +10,22 @@
* @Attributes({
* @Attribute("name", type = "string"),
* @Attribute("type", type = "string"),
+ * @Attribute("description", type = "string"),
* @Attribute("required", type = "bool"),
* })
*/
class SwagHeader
{
+ /** @var string */
public $name;
+
+ /** @var string */
public $type;
+
+ /** @var string */
+ public $description;
+
+ /** @var bool */
public $required;
public function __construct(array $values)
@@ -25,10 +34,11 @@ public function __construct(array $values)
throw new InvalidArgumentException('Name parameter is required');
}
- $values = array_merge(['type' => 'string', 'required' => false], $values);
+ $values = array_merge(['type' => 'string', 'description' => '', 'required' => false], $values);
$this->name = $values['name'];
$this->type = $values['type'];
- $this->required = $values['required'];
+ $this->description = $values['description'];
+ $this->required = (bool) $values['required'];
}
}
\ No newline at end of file
diff --git a/src/Lib/Annotation/SwagHeaderHandler.php b/src/Lib/Annotation/SwagHeaderHandler.php
index f09b2b3b..7a31b0a9 100644
--- a/src/Lib/Annotation/SwagHeaderHandler.php
+++ b/src/Lib/Annotation/SwagHeaderHandler.php
@@ -12,6 +12,7 @@ public function getHeaderParameters(SwagHeader $annotation) : Parameter
$parameter = new Parameter();
$parameter
->setName($annotation->name)
+ ->setDescription($annotation->description)
->setAllowEmptyValue(false)
->setDeprecated(false)
->setRequired($annotation->required)
diff --git a/src/Lib/Annotation/SwagOperation.php b/src/Lib/Annotation/SwagOperation.php
index 568a4563..251dada4 100644
--- a/src/Lib/Annotation/SwagOperation.php
+++ b/src/Lib/Annotation/SwagOperation.php
@@ -13,6 +13,7 @@
*/
class SwagOperation
{
+ /** @var bool */
public $isVisible;
public function __construct(array $values)
diff --git a/src/Lib/Annotation/SwagPath.php b/src/Lib/Annotation/SwagPath.php
index 0b36dd97..7ab93281 100644
--- a/src/Lib/Annotation/SwagPath.php
+++ b/src/Lib/Annotation/SwagPath.php
@@ -13,6 +13,7 @@
*/
class SwagPath
{
+ /** @var bool */
public $isVisible;
public function __construct(array $values)
diff --git a/src/Lib/Annotation/SwagQuery.php b/src/Lib/Annotation/SwagQuery.php
index c9f9cc5e..a9357518 100644
--- a/src/Lib/Annotation/SwagQuery.php
+++ b/src/Lib/Annotation/SwagQuery.php
@@ -12,13 +12,22 @@
* @Attributes({
* @Attribute("name", type="string"),
* @Attribute("type", type="string"),
+ * @Attribute("description", type="string"),
* @Attribute("required", type="boolean"),
* })
*/
class SwagQuery
{
+ /** @var string */
public $name;
+
+ /** @var string */
public $type;
+
+ /** @var string */
+ public $description;
+
+ /** @var bool */
public $required;
public function __construct(array $values)
@@ -27,7 +36,7 @@ public function __construct(array $values)
throw new InvalidArgumentException('Name parameter is required');
}
- $values = array_merge(['type' => 'string', 'required' => false], $values);
+ $values = array_merge(['type' => 'string', 'description' => '', 'required' => false], $values);
if (!in_array($values['type'], OpenApiDataType::TYPES)) {
$type = $values['type'];
@@ -40,6 +49,7 @@ public function __construct(array $values)
$this->name = $values['name'];
$this->type = $values['type'];
- $this->required = $values['required'];
+ $this->description = $values['description'];
+ $this->required = (bool) $values['required'];
}
}
\ No newline at end of file
diff --git a/src/Lib/Annotation/SwagQueryHandler.php b/src/Lib/Annotation/SwagQueryHandler.php
index f80c3ec2..b5eaf05f 100644
--- a/src/Lib/Annotation/SwagQueryHandler.php
+++ b/src/Lib/Annotation/SwagQueryHandler.php
@@ -12,6 +12,7 @@ public function getQueryParameter(SwagQuery $annotation) : Parameter
$parameter = new Parameter();
$parameter
->setName($annotation->name)
+ ->setDescription($annotation->description)
->setAllowEmptyValue(false)
->setDeprecated(false)
->setRequired($annotation->required)
diff --git a/src/Lib/Annotation/SwagRequestBody.php b/src/Lib/Annotation/SwagRequestBody.php
index f0db8d64..4e3ea667 100644
--- a/src/Lib/Annotation/SwagRequestBody.php
+++ b/src/Lib/Annotation/SwagRequestBody.php
@@ -15,8 +15,13 @@
*/
class SwagRequestBody
{
+ /** @var string */
public $description;
+
+ /** @var bool */
public $required;
+
+ /** @var bool */
public $ignoreCakeSchema;
public function __construct(array $values)
diff --git a/src/Lib/Annotation/SwagRequestBodyContent.php b/src/Lib/Annotation/SwagRequestBodyContent.php
index 1d43244c..9a2b30ba 100644
--- a/src/Lib/Annotation/SwagRequestBodyContent.php
+++ b/src/Lib/Annotation/SwagRequestBodyContent.php
@@ -14,14 +14,16 @@
*/
class SwagRequestBodyContent
{
+ /** @var string */
public $refEntity;
+
+ /** @var string */
public $mimeType;
- public $ignoreCakeSchema;
public function __construct(array $values)
{
$values = array_merge(['refEntity' => '', 'mimeType' => 'text/plain'], $values);
$this->refEntity = $values['refEntity'];
- $this->mimeType = (bool) $values['mimeType'];
+ $this->mimeType = $values['mimeType'];
}
}
\ No newline at end of file
diff --git a/src/Lib/Annotation/SwagResponseSchema.php b/src/Lib/Annotation/SwagResponseSchema.php
index fe7a034a..5e705866 100644
--- a/src/Lib/Annotation/SwagResponseSchema.php
+++ b/src/Lib/Annotation/SwagResponseSchema.php
@@ -15,8 +15,13 @@
*/
class SwagResponseSchema
{
+ /** @var string */
public $refEntity;
+
+ /** @var int */
public $httpCode = 200;
+
+ /** @var string */
public $description;
public function __construct(array $values)
diff --git a/src/Lib/Annotation/SwagSecurity.php b/src/Lib/Annotation/SwagSecurity.php
index 8eea45be..793dc1b5 100644
--- a/src/Lib/Annotation/SwagSecurity.php
+++ b/src/Lib/Annotation/SwagSecurity.php
@@ -14,7 +14,10 @@
*/
class SwagSecurity
{
+ /** @var string */
public $name;
+
+ /** @var string */
public $scopes;
public function __construct(array $values)
diff --git a/src/Lib/CakeModel.php b/src/Lib/CakeModel.php
index ebabf374..fcc2a794 100644
--- a/src/Lib/CakeModel.php
+++ b/src/Lib/CakeModel.php
@@ -18,8 +18,13 @@
*/
class CakeModel
{
+ /** @var CakeRoute */
private $cakeRoute;
+
+ /** @var string */
private $prefix;
+
+ /** @var Configuration */
private $config;
public function __construct(CakeRoute $cakeRoute, Configuration $config)
@@ -29,6 +34,11 @@ public function __construct(CakeRoute $cakeRoute, Configuration $config)
$this->config = $config;
}
+ /**
+ * Gets an array of ExpressiveModel
+ *
+ * @return ExpressiveModel[]
+ */
public function getModels() : array
{
$return = [];
@@ -105,11 +115,10 @@ private function getTablesFromRoutes(array $routes) : array
{
$return = [];
foreach ($routes as $route) {
- $controllerName = $this->cakeRoute->getControllerFromRoute($route);
- if (empty($controllerName)) {
+ if (empty($route->getController())) {
continue;
}
- $return[] = Inflector::underscore($controllerName);
+ $return[] = Inflector::underscore($route->getController());
}
return array_unique($return);
}
diff --git a/src/Lib/CakeRoute.php b/src/Lib/CakeRoute.php
index d252a619..dfc15696 100644
--- a/src/Lib/CakeRoute.php
+++ b/src/Lib/CakeRoute.php
@@ -1,9 +1,8 @@
router = $router;
$this->prefix = $config->getPrefix();
+ $this->prefixLength = strlen($this->prefix);
}
+ /**
+ * Gets an array of Route
+ *
+ * @return ExpressiveRoute[]
+ */
public function getRoutes() : array
{
if (empty($this->prefix) || !filter_var('http://foo.com' . $this->prefix, FILTER_VALIDATE_URL)) {
throw new InvalidArgumentException('route prefix is invalid');
}
- $length = strlen($this->prefix);
-
- return array_filter($this->router::routes(), function ($route) use ($length) {
- if (substr($route->template, 0, $length) != $this->prefix) {
- return null;
- }
- if (substr($route->template, $length) == '') {
- return null;
- }
- return true;
+ $filteredRoutes = array_filter($this->router::routes(), function ($route) {
+ return $this->isRouteAllowed($route);
});
+
+ $routes = [];
+
+ foreach ($filteredRoutes as $route) {
+ $routes[$route->getName()] = $this->createExpressiveRouteFromRoute($route);
+ }
+
+ ksort($routes);
+
+ return $routes;
}
- public function getControllerFromRoute(Route $route) : ?string
+ private function createExpressiveRouteFromRoute(Route $route) : ExpressiveRoute
{
$defaults = (array) $route->defaults;
- if (!isset($defaults['controller'])) {
- return null;
+ $methods = $defaults['_method'];
+ if (!is_array($defaults['_method'])) {
+ $methods = explode(', ', $defaults['_method']);
+ }
+
+ return (new ExpressiveRoute())
+ ->setPlugin($defaults['plugin'])
+ ->setController($defaults['controller'])
+ ->setName($route->getName())
+ ->setAction($defaults['action'])
+ ->setMethods($methods)
+ ->setTemplate($route->template)
+ ;
+ }
+
+ private function isRouteAllowed(Route $route) : bool
+ {
+ if (substr($route->template, 0, $this->prefixLength) != $this->prefix) {
+ return false;
+ }
+ if (substr($route->template, $this->prefixLength) == '') {
+ return false;
+ }
+
+ $defaults = (array) $route->defaults;
+
+ if (!isset($defaults['_method']) || empty($defaults['_method'])) {
+ return false;
+ }
+
+ if (isset($defaults['plugin']) && in_array($defaults['plugin'], self::EXCLUDED_PLUGINS)) {
+ return false;
}
- return $defaults['controller'];
+ return true;
}
}
diff --git a/src/Lib/Configuration.php b/src/Lib/Configuration.php
index ff22473e..f71728bf 100644
--- a/src/Lib/Configuration.php
+++ b/src/Lib/Configuration.php
@@ -24,6 +24,7 @@ public function __construct($config = [], $root = ROOT)
[
'docType' => 'swagger',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\App\\'],
'entities' => ['\App\\'],
@@ -89,6 +90,11 @@ public function getDocType() : string
return strtolower($this->get('docType'));
}
+ public function getExceptionSchema() : string
+ {
+ return $this->get('exceptionSchema');
+ }
+
public function getLayout(?string $doctype = null) : string
{
$doctype = empty($doctype) ? $this->getDocType() : $doctype;
diff --git a/src/Lib/Factory/PathFactory.php b/src/Lib/Factory/PathFactory.php
index fa8b2587..dd33706b 100644
--- a/src/Lib/Factory/PathFactory.php
+++ b/src/Lib/Factory/PathFactory.php
@@ -2,7 +2,6 @@
namespace SwaggerBake\Lib\Factory;
-use Cake\Routing\Route\Route;
use Cake\Utility\Inflector;
use Exception;
use phpDocumentor\Reflection\DocBlock;
@@ -12,9 +11,11 @@
use SwaggerBake\Lib\Configuration;
use SwaggerBake\Lib\Exception\SwaggerBakeRunTimeException;
use SwaggerBake\Lib\ExceptionHandler;
+use SwaggerBake\Lib\Model\ExpressiveRoute;
use SwaggerBake\Lib\OpenApi\OperationExternalDoc;
use SwaggerBake\Lib\OpenApi\Path;
use SwaggerBake\Lib\OpenApi\Parameter;
+use SwaggerBake\Lib\OpenApi\RequestBody;
use SwaggerBake\Lib\OpenApi\Response;
use SwaggerBake\Lib\OpenApi\Schema;
use SwaggerBake\Lib\Utility\AnnotationUtility;
@@ -28,7 +29,7 @@ class PathFactory
private $prefix = '';
private $config;
- public function __construct(Route $route, Configuration $config)
+ public function __construct(ExpressiveRoute $route, Configuration $config)
{
$this->config = $config;
$this->route = $route;
@@ -44,19 +45,21 @@ public function __construct(Route $route, Configuration $config)
public function create() : ?Path
{
$path = new Path();
- $defaults = (array) $this->route->defaults;
- if (empty($defaults['_method'])) {
+ if (empty($this->route->getMethods())) {
return null;
}
- if (!$this->isControllerVisible($defaults['controller'])) {
+ if (!$this->isControllerVisible($this->route->getController())) {
return null;
}
- foreach ((array) $defaults['_method'] as $method) {
+ foreach ($this->route->getMethods() as $method) {
- $methodAnnotations = $this->getMethodAnnotations($defaults['controller'], $defaults['action']);
+ $methodAnnotations = $this->getMethodAnnotations(
+ $this->route->getController(),
+ $this->route->getAction()
+ );
if (!$this->isMethodVisible($methodAnnotations)) {
continue;
@@ -69,7 +72,7 @@ public function create() : ?Path
->setSummary($this->dockBlock ? $this->dockBlock->getSummary() : '')
->setDescription($this->dockBlock ? $this->dockBlock->getDescription() : '')
->setTags([
- Inflector::humanize(Inflector::underscore($defaults['controller']))
+ Inflector::humanize(Inflector::underscore($this->route->getController()))
])
->setParameters($this->getPathParameters())
->setDeprecated($this->isDeprecated())
@@ -92,19 +95,24 @@ function ($piece) {
}
return $piece;
},
- explode('/', $this->route->template)
+ explode('/', $this->route->getTemplate())
);
- $length = strlen($this->prefix);
+ if ($this->prefix == '/') {
+ return implode('/', $pieces);
+ }
- return substr(implode('/', $pieces), $length);
+ return substr(
+ implode('/', $pieces),
+ strlen($this->prefix)
+ );
}
private function getPathParameters() : array
{
$return = [];
- $pieces = explode('/', $this->route->template);
+ $pieces = explode('/', $this->route->getTemplate());
$results = array_filter($pieces, function ($piece) {
return substr($piece, 0, 1) == ':' ? true : null;
});
@@ -171,7 +179,6 @@ private function withResponses(Path $path, array $annotations) : Path
);
}
-
return $path;
}
@@ -181,16 +188,14 @@ private function withRequestBody(Path $path, array $annotations) : Path
return $path;
}
+ $requestBody = new RequestBody();
+
foreach ($annotations as $annotation) {
if ($annotation instanceof SwagAnnotation\SwagRequestBody) {
$requestBody = (new SwagAnnotation\SwagRequestBodyHandler())->getResponse($annotation);
}
}
- if (!isset($requestBody)) {
- return $path;
- }
-
foreach ($annotations as $annotation) {
if ($annotation instanceof SwagAnnotation\SwagRequestBodyContent) {
$requestBody->pushContent(
@@ -208,14 +213,12 @@ private function withRequestBody(Path $path, array $annotations) : Path
private function getDocBlock() : ?DocBlock
{
- $defaults = (array) $this->route->defaults;
-
- if (!isset($defaults['controller'])) {
+ if (empty($this->route->getController())) {
return null;
}
- $className = $defaults['controller'] . 'Controller';
- $methodName = $defaults['action'];
+ $className = $this->route->getController() . 'Controller';
+ $methodName = $this->route->getAction();
$controller = $this->getControllerFromNamespaces($className);
diff --git a/src/Lib/Model/ExpressiveRoute.php b/src/Lib/Model/ExpressiveRoute.php
new file mode 100644
index 00000000..edb80f31
--- /dev/null
+++ b/src/Lib/Model/ExpressiveRoute.php
@@ -0,0 +1,83 @@
+name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getPlugin()
+ {
+ return $this->plugin;
+ }
+
+ public function setPlugin($plugin)
+ {
+ $this->plugin = $plugin;
+ return $this;
+ }
+
+ public function getController()
+ {
+ return $this->controller;
+ }
+
+ public function setController($controller)
+ {
+ $this->controller = $controller;
+ return $this;
+ }
+
+ public function getAction()
+ {
+ return $this->action;
+ }
+
+ public function setAction($action)
+ {
+ $this->action = $action;
+ return $this;
+ }
+
+ public function getMethods(): array
+ {
+ return $this->methods;
+ }
+
+ public function setMethods(array $methods): ExpressiveRoute
+ {
+ $this->methods = $methods;
+ return $this;
+ }
+
+ public function getTemplate()
+ {
+ return $this->template;
+ }
+
+ public function setTemplate($template)
+ {
+ $this->template = $template;
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/src/Lib/OpenApi/Content.php b/src/Lib/OpenApi/Content.php
index fe439407..671e4aee 100644
--- a/src/Lib/OpenApi/Content.php
+++ b/src/Lib/OpenApi/Content.php
@@ -14,6 +14,10 @@ public function toArray() : array
{
$vars = get_object_vars($this);
unset($vars['mimeType']);
+ if (is_string($this->schema)) {
+ unset($vars['schema']);
+ $vars['schema']['$ref'] = $this->schema;
+ }
return $vars;
}
@@ -49,10 +53,12 @@ public function getSchema() : Schema
}
/**
- * @param mixed $schema
+ * Can be either a schema $ref string such as '#/components/schemas/Pet' or a Schema instance.
+ *
+ * @param string|Schema $schema
* @return Content
*/
- public function setSchema(Schema $schema) : Content
+ public function setSchema($schema) : Content
{
$this->schema = $schema;
return $this;
diff --git a/src/Lib/OpenApi/Parameter.php b/src/Lib/OpenApi/Parameter.php
index 7ba49321..e705f0e9 100644
--- a/src/Lib/OpenApi/Parameter.php
+++ b/src/Lib/OpenApi/Parameter.php
@@ -12,12 +12,25 @@
*/
class Parameter implements JsonSerializable
{
+ /** @var string **/
private $name = '';
+
+ /** @var string **/
private $in = '';
+
+ /** @var string **/
private $description = '';
+
+ /** @var bool **/
private $required = false;
+
+ /** @var Schema **/
private $schema;
+
+ /** @var bool **/
private $deprecated = false;
+
+ /** @var bool **/
private $allowEmptyValue = true;
public function toArray() : array
@@ -27,7 +40,11 @@ public function toArray() : array
public function jsonSerialize()
{
- return $this->toArray();
+ $vars = $this->toArray();
+ if (empty($vars['description'])) {
+ unset($vars['description']);
+ }
+ return $vars;
}
/**
diff --git a/src/Lib/OpenApi/Path.php b/src/Lib/OpenApi/Path.php
index dacedce9..058cc948 100644
--- a/src/Lib/OpenApi/Path.php
+++ b/src/Lib/OpenApi/Path.php
@@ -26,13 +26,13 @@ class Path
private $security = [];
private $deprecated = false;
- public function toArray() : array
+ public function toArray(): array
{
$vars = get_object_vars($this);
unset($vars['type']);
unset($vars['path']);
- if (in_array($this->type, ['get','delete'])) {
+ if (in_array($this->type, ['get', 'delete'])) {
unset($vars['requestBody']);
}
if (empty($vars['security'])) {
@@ -45,6 +45,15 @@ public function toArray() : array
return $vars;
}
+ public function hasSuccessResponseCode() : bool
+ {
+ $results = array_filter($this->getResponses(), function ($response) {
+ return ($response->getCode() >= 200 && $response->getCode() < 300);
+ });
+
+ return count($results) > 0;
+ }
+
/**
* @return string
*/
@@ -187,7 +196,7 @@ public function setRequestBody(RequestBody $requestBody) : Path
}
/**
- * @return array
+ * @return Response[]
*/
public function getResponses(): array
{
diff --git a/src/Lib/OpenApi/Schema.php b/src/Lib/OpenApi/Schema.php
index 77d2fa9d..a71c6f81 100644
--- a/src/Lib/OpenApi/Schema.php
+++ b/src/Lib/OpenApi/Schema.php
@@ -7,12 +7,24 @@
class Schema implements JsonSerializable
{
+ /** @var string */
private $name = '';
+
+ /** @var string */
private $description = '';
+
+ /** @var string */
private $type = '';
+
+ /** @var array */
private $required = [];
+
+ /** @var array */
private $properties = [];
+ /** @var array */
+ private $items = [];
+
public function toArray() : array
{
$vars = get_object_vars($this);
@@ -25,6 +37,9 @@ public function toArray() : array
if (empty($vars['properties'])) {
unset($vars['properties']);
}
+ if (empty($vars['items'])) {
+ unset($vars['items']);
+ }
return $vars;
}
@@ -149,4 +164,24 @@ public function setDescription(string $description): Schema
$this->description = $description;
return $this;
}
+
+ /**
+ * @return array
+ */
+ public function getItems(): array
+ {
+ return $this->items;
+ }
+
+ /**
+ * @param array $items
+ * @return Schema
+ */
+ public function setItems(array $items): Schema
+ {
+ $this->items = $items;
+ return $this;
+ }
+
+
}
\ No newline at end of file
diff --git a/src/Lib/OpenApi/SchemaProperty.php b/src/Lib/OpenApi/SchemaProperty.php
index 4bfdef38..ef0cc1d9 100644
--- a/src/Lib/OpenApi/SchemaProperty.php
+++ b/src/Lib/OpenApi/SchemaProperty.php
@@ -7,11 +7,28 @@
class SchemaProperty implements JsonSerializable
{
+ /** @var string */
private $name = '';
+
+ /** @var string */
private $type = '';
+
+ /** @var string */
private $format = '';
+
+ /** @var string */
+ private $example = '';
+
+ /** @var string */
+ private $description = '';
+
+ /** @var bool */
private $readOnly = false;
+
+ /** @var bool */
private $writeOnly = false;
+
+ /** @var bool */
private $required = false;
public function toArray() : array
@@ -19,6 +36,14 @@ public function toArray() : array
$vars = get_object_vars($this);
unset($vars['name']);
unset($vars['required']);
+
+ if (empty($vars['example'])) {
+ unset($vars['example']);
+ }
+ if (empty($vars['description'])) {
+ unset($vars['description']);
+ }
+
return $vars;
}
@@ -134,4 +159,40 @@ public function setRequired(bool $required): SchemaProperty
$this->required = $required;
return $this;
}
+
+ /**
+ * @return string
+ */
+ public function getExample(): string
+ {
+ return $this->example;
+ }
+
+ /**
+ * @param string $example
+ * @return SchemaProperty
+ */
+ public function setExample(string $example): SchemaProperty
+ {
+ $this->example = $example;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+
+ /**
+ * @param string $description
+ * @return SchemaProperty
+ */
+ public function setDescription(string $description): SchemaProperty
+ {
+ $this->description = $description;
+ return $this;
+ }
}
\ No newline at end of file
diff --git a/src/Lib/RequestBodyBuilder.php b/src/Lib/RequestBodyBuilder.php
index cb183b2d..08c89121 100644
--- a/src/Lib/RequestBodyBuilder.php
+++ b/src/Lib/RequestBodyBuilder.php
@@ -3,17 +3,16 @@
namespace SwaggerBake\Lib;
-use Cake\Routing\Route\Route;
use Cake\Utility\Inflector;
+use SwaggerBake\Lib\Model\ExpressiveRoute;
use SwaggerBake\Lib\OpenApi\Content;
use SwaggerBake\Lib\OpenApi\Path;
use SwaggerBake\Lib\OpenApi\RequestBody;
use SwaggerBake\Lib\OpenApi\Schema;
-use SwaggerBake\Lib\OpenApi\SchemaProperty;
class RequestBodyBuilder
{
- public function __construct(Path $path, Swagger $swagger, Route $route)
+ public function __construct(Path $path, Swagger $swagger, ExpressiveRoute $route)
{
$this->path = $path;
$this->route = $route;
@@ -47,13 +46,11 @@ public function build() : ?RequestBody
return null;
}
- $content = new Content();
- $content
+ $content = (new Content())
->setMimeType('application/x-www-form-urlencoded')
->setSchema($schema);
;
-
$requestBody
->pushContent($content)
->setRequired(true)
diff --git a/src/Lib/Security.php b/src/Lib/Security.php
index f0860245..0bf9538a 100644
--- a/src/Lib/Security.php
+++ b/src/Lib/Security.php
@@ -2,7 +2,6 @@
namespace SwaggerBake\Lib;
-
use SwaggerBake\Lib\Annotation as SwagAnnotation;
class Security extends AbstractParameter
diff --git a/src/Lib/Swagger.php b/src/Lib/Swagger.php
index 236a7ca8..dc83085d 100644
--- a/src/Lib/Swagger.php
+++ b/src/Lib/Swagger.php
@@ -2,13 +2,14 @@
namespace SwaggerBake\Lib;
-use Cake\Routing\Route\Route;
use Cake\Utility\Inflector;
use SwaggerBake\Lib\Exception\SwaggerBakeRunTimeException;
use SwaggerBake\Lib\Factory as Factory;
+use SwaggerBake\Lib\Model\ExpressiveRoute;
use SwaggerBake\Lib\OpenApi\Path;
use SwaggerBake\Lib\OpenApi\Response;
use SwaggerBake\Lib\OpenApi\Schema;
+use SwaggerBake\Lib\OpenApi\SchemaProperty;
use Symfony\Component\Yaml\Yaml;
class Swagger
@@ -23,16 +24,7 @@ public function __construct(CakeModel $cakeModel)
$this->cakeModel = $cakeModel;
$this->cakeRoute = $cakeModel->getCakeRoute();
$this->config = $cakeModel->getConfig();
-
- $array = Yaml::parseFile($this->config->getYml());
- if (!isset($array['paths'])) {
- $array['paths'] = [];
- }
- if (!isset($array['components']['schemas'])) {
- $array['components']['schemas'] = [];
- }
-
- $this->array = $array;
+ $this->buildFromDefaults();
}
/**
@@ -59,8 +51,13 @@ public function getArray(): array
}
}
- ksort($this->array['paths']);
- ksort($this->array['components']['schemas']);
+ ksort($this->array['paths'], SORT_STRING);
+ uksort($this->array['components']['schemas'], function ($a, $b) {
+ return strcasecmp(
+ preg_replace('/\s+/', '', $a),
+ preg_replace('/\s+/', '', $b)
+ );
+ });
if (empty($this->array['components']['schemas'])) {
unset($this->array['components']['schemas']);
@@ -170,6 +167,9 @@ public function getConfig() : Configuration
return $this->config;
}
+ /**
+ * Builds schemas from cake models
+ */
private function buildSchemas(): void
{
$schemaFactory = new Factory\SchemaFactory($this->config);
@@ -187,6 +187,9 @@ private function buildSchemas(): void
}
}
+ /**
+ * Builds paths from cake routes
+ */
private function buildPaths(): void
{
$routes = $this->cakeRoute->getRoutes();
@@ -210,13 +213,27 @@ private function buildPaths(): void
}
}
- private function pathWithSecurity(Path $path, Route $route) : Path
+ /**
+ * Sets security on a path
+ *
+ * @param Path $path
+ * @param ExpressiveRoute $route
+ * @return Path
+ */
+ private function pathWithSecurity(Path $path, ExpressiveRoute $route) : Path
{
$path->setSecurity((new Security($route, $this->config))->getPathSecurity());
return $path;
}
- private function pathWithParameters(Path $path, Route $route) : Path
+ /**
+ * Sets header parameters on a path
+ *
+ * @param Path $path
+ * @param ExpressiveRoute $route
+ * @return Path
+ */
+ private function pathWithParameters(Path $path, ExpressiveRoute $route) : Path
{
$headers = (new HeaderParameter($route, $this->config))->getHeaderParameters();
foreach ($headers as $parameter) {
@@ -230,29 +247,73 @@ private function pathWithParameters(Path $path, Route $route) : Path
return $path;
}
+ /**
+ * Sets responses on a path
+ *
+ * @param Path $path
+ * @return Path
+ */
private function pathWithResponses(Path $path) : Path
{
foreach ($path->getTags() as $tag) {
$className = Inflector::classify($tag);
+ if ($path->hasSuccessResponseCode() || !$this->getSchemaByName($className)) {
+ continue;
+ }
- if (!$path->getResponseByCode(200) && $this->getSchemaByName($className)) {
- $response = new Response();
- $response
- ->setSchemaRef('#/components/schemas/' . $className)
+ if ($path->getType() == 'get' && strstr($path->getOperationId(),':index')) {
+ $tags = $path->getTags();
+ $tag = preg_replace('/\s+/', '', reset($tags));
+ $schema = (new Schema())
+ ->setName($tag)
+ ->setType('array')
+ ->setItems(['$ref' => '#/components/schemas/' . $className])
+ ;
+ $this->pushSchema($schema);
+
+ $response = (new Response())
+ ->setSchemaRef('#/components/schemas/' . $tag)
->setCode(200);
$path->pushResponse($response);
+ continue;
}
+
+ $response = (new Response())
+ ->setSchemaRef('#/components/schemas/' . $className)
+ ->setCode(200);
+ $path->pushResponse($response);
}
- if (!$path->getResponseByCode(200)) {
+ if (!$path->hasSuccessResponseCode()) {
$path->pushResponse((new Response())->setCode(200));
}
+ $exceptionSchema = $this->getSchemaByName($this->getConfig()->getExceptionSchema());
+ if (!$exceptionSchema) {
+ return $path;
+ }
+
+ foreach ($path->getResponses() as $response) {
+ if ($response->getCode() < 400) {
+ continue;
+ }
+ $path->pushResponse(
+ $response->setSchemaRef('#/components/schemas/' . $exceptionSchema->getName())
+ );
+ }
+
return $path;
}
- private function pathWithRequestBody(Path $path, Route $route) : Path
+ /**
+ * Sets a request body on a path
+ *
+ * @param Path $path
+ * @param ExpressiveRoute $route
+ * @return Path
+ */
+ private function pathWithRequestBody(Path $path, ExpressiveRoute $route) : Path
{
$requestBody = (new RequestBodyBuilder($path, $this, $route))->build();
if ($requestBody) {
@@ -261,6 +322,44 @@ private function pathWithRequestBody(Path $path, Route $route) : Path
return $path;
}
+ /**
+ * Constructs the primary array used in this class from pre-defined swagger.yml
+ */
+ private function buildFromDefaults() : void
+ {
+ $array = Yaml::parseFile($this->config->getYml());
+ if (!isset($array['paths'])) {
+ $array['paths'] = [];
+ }
+ if (!isset($array['components']['schemas'])) {
+ $array['components']['schemas'] = [];
+ }
+
+ foreach ($array['components']['schemas'] as $schemaName => $schemaVar) {
+
+ $schema = (new Schema())
+ ->setName($schemaName)
+ ->setType($schemaVar['type'])
+ ->setDescription($schemaVar['description'] ?? '');
+
+ $schemaVar['properties'] = $schemaVar['properties'] ?? [];
+
+ foreach ($schemaVar['properties'] as $propertyName => $propertyVar) {
+ $property = (new SchemaProperty())
+ ->setType($propertyVar['type'])
+ ->setName($propertyName)
+ ->setFormat($propertyVar['type'] ?? '')
+ ->setExample($propertyVar['example'] ?? '')
+ ;
+ $schema->pushProperty($property);
+ }
+
+ $array['components']['schemas'][$schemaName] = $schema;
+ }
+
+ $this->array = $array;
+ }
+
public function __toString(): string
{
return $this->toString();
diff --git a/src/Lib/Utility/DataTypeConversion.php b/src/Lib/Utility/DataTypeConversion.php
index 9b5e8362..e5df5398 100644
--- a/src/Lib/Utility/DataTypeConversion.php
+++ b/src/Lib/Utility/DataTypeConversion.php
@@ -15,6 +15,11 @@ public static function convert(string $type) : string
case 'biginteger':
case 'mediuminteger':
return 'integer';
+ case 'decimal':
+ case 'float':
+ return 'number';
+ case 'uuid':
+ case 'text':
case 'varchar':
case 'char':
case 'date':
diff --git a/tests/TestCase/Lib/SwaggerEntityTest.php b/tests/TestCase/Lib/SwaggerEntityTest.php
index 6b6ea3d8..ecd76c49 100644
--- a/tests/TestCase/Lib/SwaggerEntityTest.php
+++ b/tests/TestCase/Lib/SwaggerEntityTest.php
@@ -35,17 +35,13 @@ public function setUp(): void
});
$this->router = $router;
- AnnotationLoader::load();
- }
-
- public function testEntityExists()
- {
- $config = new Configuration([
+ $this->config = new Configuration([
'prefix' => '/api',
'yml' => '/config/swagger-bare-bones.yml',
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\SwaggerBakeTest\App\\'],
'entities' => ['\SwaggerBakeTest\App\\'],
@@ -53,9 +49,14 @@ public function testEntityExists()
]
], SWAGGER_BAKE_TEST_APP);
- $cakeRoute = new CakeRoute($this->router, $config);
+ AnnotationLoader::load();
+ }
+
+ public function testEntityExists()
+ {
+ $cakeRoute = new CakeRoute($this->router, $this->config);
- $swagger = new Swagger(new CakeModel($cakeRoute, $config));
+ $swagger = new Swagger(new CakeModel($cakeRoute, $this->config));
$arr = json_decode($swagger->toString(), true);
@@ -64,22 +65,9 @@ public function testEntityExists()
public function testEntityInvisible()
{
- $config = new Configuration([
- 'prefix' => '/api',
- 'yml' => '/config/swagger-bare-bones.yml',
- 'json' => '/webroot/swagger.json',
- 'webPath' => '/swagger.json',
- 'hotReload' => false,
- 'namespaces' => [
- 'controllers' => ['\SwaggerBakeTest\App\\'],
- 'entities' => ['\SwaggerBakeTest\App\\'],
- 'tables' => ['\SwaggerBakeTest\App\\'],
- ]
- ], SWAGGER_BAKE_TEST_APP);
-
- $cakeRoute = new CakeRoute($this->router, $config);
+ $cakeRoute = new CakeRoute($this->router, $this->config);
- $swagger = new Swagger(new CakeModel($cakeRoute, $config));
+ $swagger = new Swagger(new CakeModel($cakeRoute, $this->config));
$arr = json_decode($swagger->toString(), true);
@@ -88,21 +76,9 @@ public function testEntityInvisible()
public function testEntityAttribute()
{
- $config = new Configuration([
- 'prefix' => '/api',
- 'yml' => '/config/swagger-bare-bones.yml',
- 'json' => '/webroot/swagger.json',
- 'webPath' => '/swagger.json',
- 'hotReload' => false,
- 'namespaces' => [
- 'controllers' => ['\SwaggerBakeTest\App\\'],
- 'entities' => ['\SwaggerBakeTest\App\\']
- ]
- ], SWAGGER_BAKE_TEST_APP);
-
- $cakeRoute = new CakeRoute($this->router, $config);
+ $cakeRoute = new CakeRoute($this->router, $this->config);
- $swagger = new Swagger(new CakeModel($cakeRoute, $config));
+ $swagger = new Swagger(new CakeModel($cakeRoute, $this->config));
$arr = json_decode($swagger->toString(), true);
diff --git a/tests/TestCase/Lib/SwaggerOperationTest.php b/tests/TestCase/Lib/SwaggerOperationTest.php
index 3c7e6eb0..6dc8a426 100644
--- a/tests/TestCase/Lib/SwaggerOperationTest.php
+++ b/tests/TestCase/Lib/SwaggerOperationTest.php
@@ -59,6 +59,7 @@ public function setUp(): void
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\SwaggerBakeTest\App\\'],
'entities' => ['\SwaggerBakeTest\App\\'],
diff --git a/tests/TestCase/Lib/SwaggerPathTest.php b/tests/TestCase/Lib/SwaggerPathTest.php
index 596eea35..5e60cc0f 100644
--- a/tests/TestCase/Lib/SwaggerPathTest.php
+++ b/tests/TestCase/Lib/SwaggerPathTest.php
@@ -46,6 +46,7 @@ public function testPathInvisible()
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\SwaggerBakeTest\App\\'],
'entities' => ['\SwaggerBakeTest\App\\'],
diff --git a/tests/TestCase/Lib/SwaggerSchemaTest.php b/tests/TestCase/Lib/SwaggerSchemaTest.php
index 033a976c..cbc656a5 100644
--- a/tests/TestCase/Lib/SwaggerSchemaTest.php
+++ b/tests/TestCase/Lib/SwaggerSchemaTest.php
@@ -35,6 +35,7 @@ public function setUp(): void
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\SwaggerBakeTest\App\\'],
'entities' => ['\SwaggerBakeTest\App\\'],
diff --git a/tests/TestCase/Lib/SwaggerTest.php b/tests/TestCase/Lib/SwaggerTest.php
index b41b1d2c..a1a29c8b 100644
--- a/tests/TestCase/Lib/SwaggerTest.php
+++ b/tests/TestCase/Lib/SwaggerTest.php
@@ -50,23 +50,26 @@ public function setUp(): void
});
$this->router = $router;
- AnnotationLoader::load();
- }
-
- public function testGetArrayWithExistingPathsAndSchema()
- {
- $config = new Configuration([
+ $this->config = [
'prefix' => '/api',
'yml' => '/config/swagger-with-existing.yml',
'json' => '/webroot/swagger.json',
'webPath' => '/swagger.json',
'hotReload' => false,
+ 'exceptionSchema' => 'Exception',
'namespaces' => [
'controllers' => ['\SwaggerBakeTest\App\\'],
'entities' => ['\SwaggerBakeTest\App\\'],
'tables' => ['\SwaggerBakeTest\App\\'],
]
- ], SWAGGER_BAKE_TEST_APP);
+ ];
+
+ AnnotationLoader::load();
+ }
+
+ public function testGetArrayWithExistingPathsAndSchema()
+ {
+ $config = new Configuration($this->config, SWAGGER_BAKE_TEST_APP);
$cakeRoute = new CakeRoute($this->router, $config);
@@ -80,18 +83,9 @@ public function testGetArrayWithExistingPathsAndSchema()
public function testGetArrayFromBareBones()
{
- $config = new Configuration([
- 'prefix' => '/api',
- 'yml' => '/config/swagger-bare-bones.yml',
- 'json' => '/webroot/swagger.json',
- 'webPath' => '/swagger.json',
- 'hotReload' => false,
- 'namespaces' => [
- 'controllers' => ['\SwaggerBakeTest\App\\'],
- 'entities' => ['\SwaggerBakeTest\App\\'],
- 'tables' => ['\SwaggerBakeTest\App\\'],
- ]
- ], SWAGGER_BAKE_TEST_APP);
+ $vars = $this->config;
+ $vars['yml'] = '/config/swagger-bare-bones.yml';
+ $config = new Configuration($vars, SWAGGER_BAKE_TEST_APP);
$cakeRoute = new CakeRoute($this->router, $config);