diff --git a/composer.lock b/composer.lock index 3220d9f2..d72c2b74 100644 --- a/composer.lock +++ b/composer.lock @@ -9320,16 +9320,16 @@ }, { "name": "ronasit/laravel-helpers", - "version": "3.4.1", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/RonasIT/laravel-helpers.git", - "reference": "997141b533877508e074263a1cf92fa1664816a9" + "reference": "287d5e3a3af61a34ae58efbd69d2780a935c5ab4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RonasIT/laravel-helpers/zipball/997141b533877508e074263a1cf92fa1664816a9", - "reference": "997141b533877508e074263a1cf92fa1664816a9", + "url": "https://api.github.com/repos/RonasIT/laravel-helpers/zipball/287d5e3a3af61a34ae58efbd69d2780a935c5ab4", + "reference": "287d5e3a3af61a34ae58efbd69d2780a935c5ab4", "shasum": "" }, "require": { @@ -9395,9 +9395,9 @@ ], "support": { "issues": "https://github.com/RonasIT/laravel-helpers/issues", - "source": "https://github.com/RonasIT/laravel-helpers/tree/3.4.1" + "source": "https://github.com/RonasIT/laravel-helpers/tree/3.4.2" }, - "time": "2025-04-30T14:00:55+00:00" + "time": "2025-05-26T03:41:09+00:00" }, { "name": "symfony/config", diff --git a/config/auto-doc.php b/config/auto-doc.php index 6a43b1fc..4245ad74 100644 --- a/config/auto-doc.php +++ b/config/auto-doc.php @@ -101,6 +101,15 @@ '204' => 'Operation successfully done', '404' => 'This entity not found', ], + + /* + |-------------------------------------------------------------------------- + | Error Template + |-------------------------------------------------------------------------- + | + | You can use your custom description view for errors. + */ + 'error' => 'auto-doc::error', ], /* @@ -211,5 +220,5 @@ ], ], - 'config_version' => '2.9', + 'config_version' => '2.10', ]; diff --git a/resources/views/error.blade.php b/resources/views/error.blade.php new file mode 100644 index 00000000..0b9291cb --- /dev/null +++ b/resources/views/error.blade.php @@ -0,0 +1 @@ +{{ $message }} \ No newline at end of file diff --git a/src/AutoDocServiceProvider.php b/src/AutoDocServiceProvider.php index 0e6d435b..fafd6bcb 100644 --- a/src/AutoDocServiceProvider.php +++ b/src/AutoDocServiceProvider.php @@ -17,6 +17,7 @@ public function boot() $this->publishes([ __DIR__ . '/../resources/views/swagger-description.blade.php' => resource_path('views/vendor/auto-doc/swagger-description.blade.php'), + __DIR__ . '/../resources/views/error.blade.php' => resource_path('views/vendor/auto-doc/error.blade.php'), ], 'view'); if (!$this->app->routesAreCached()) { diff --git a/src/Drivers/LocalDriver.php b/src/Drivers/LocalDriver.php index ab0c233a..b5d6288e 100755 --- a/src/Drivers/LocalDriver.php +++ b/src/Drivers/LocalDriver.php @@ -2,7 +2,7 @@ namespace RonasIT\AutoDoc\Drivers; -use Illuminate\Contracts\Filesystem\FileNotFoundException; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; use RonasIT\AutoDoc\Exceptions\MissedProductionFilePathException; class LocalDriver extends BaseDriver @@ -30,7 +30,7 @@ public function saveData(): void public function getDocumentation(): array { if (!file_exists($this->prodFilePath)) { - throw new FileNotFoundException(); + throw new FileNotFoundException($this->prodFilePath); } $fileContent = file_get_contents($this->prodFilePath); diff --git a/src/Drivers/RemoteDriver.php b/src/Drivers/RemoteDriver.php index 0baa6601..34792410 100755 --- a/src/Drivers/RemoteDriver.php +++ b/src/Drivers/RemoteDriver.php @@ -2,7 +2,7 @@ namespace RonasIT\AutoDoc\Drivers; -use Illuminate\Contracts\Filesystem\FileNotFoundException; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; use RonasIT\AutoDoc\Exceptions\MissedRemoteDocumentationUrlException; class RemoteDriver extends BaseDriver diff --git a/src/Drivers/StorageDriver.php b/src/Drivers/StorageDriver.php index 4dbdbdf9..71cd95d6 100755 --- a/src/Drivers/StorageDriver.php +++ b/src/Drivers/StorageDriver.php @@ -2,7 +2,7 @@ namespace RonasIT\AutoDoc\Drivers; -use Illuminate\Contracts\Filesystem\FileNotFoundException; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Facades\Storage; use RonasIT\AutoDoc\Exceptions\MissedProductionFilePathException; @@ -34,7 +34,7 @@ public function saveData(): void public function getDocumentation(): array { if (!$this->disk->exists($this->prodFilePath)) { - throw new FileNotFoundException(); + throw new FileNotFoundException($this->prodFilePath); } $fileContent = $this->disk->get($this->prodFilePath); diff --git a/src/Exceptions/FileNotFoundException.php b/src/Exceptions/FileNotFoundException.php new file mode 100644 index 00000000..84a896c5 --- /dev/null +++ b/src/Exceptions/FileNotFoundException.php @@ -0,0 +1,13 @@ +config['info'])) { + $view = $this->config['info']['description']; + } + $data = [ 'openapi' => self::OPEN_API_VERSION, 'servers' => [ @@ -148,7 +153,7 @@ protected function generateEmptyData(): array 'components' => [ 'schemas' => $this->config['definitions'], ], - 'info' => $this->prepareInfo($this->config['info']) + 'info' => $this->prepareInfo($view, $viewData, $license), ]; $securityDefinitions = $this->generateSecurityDefinition(); @@ -260,7 +265,7 @@ protected function generatePathDescription(string $key): string foreach ($exploded as $value) { if (!preg_match('/^[a-zA-Z0-9\.]+$/', $value)) { - return "regexp: {$expression}"; + return "regexp: {$expression}"; } } @@ -596,8 +601,13 @@ protected function saveParameterType(&$data, $parameter, $parameterType) ]; } - protected function saveParameterDescription(&$data, $parameter, array $rulesArray, array $attributes, array $annotations) - { + protected function saveParameterDescription( + array &$data, + string $parameter, + array $rulesArray, + array $attributes, + array $annotations + ) { $description = Arr::get($annotations, $parameter); if (empty($description)) { @@ -803,7 +813,7 @@ public function saveProductionData() if (ParallelTesting::token()) { $this->driver->appendProcessDataToTmpFile(function (array $sharedTmpData) { $resultDocContent = (empty($sharedTmpData)) - ? $this->generateEmptyData() + ? $this->generateEmptyData($this->config['info']['description']) : $sharedTmpData; $this->mergeOpenAPIDocs($resultDocContent, $this->data); @@ -817,9 +827,13 @@ public function saveProductionData() public function getDocFileContent() { - $documentation = $this->driver->getDocumentation(); + try { + $documentation = $this->driver->getDocumentation(); - $this->openAPIValidator->validate($documentation); + $this->openAPIValidator->validate($documentation); + } catch (Exception $exception) { + return $this->generateEmptyData($this->config['defaults']['error'], ['message' => $exception->getMessage()]); + } $additionalDocs = config('auto-doc.additional_paths', []); @@ -946,27 +960,21 @@ protected function getDefaultValueByType($type) return $values[$type]; } - protected function prepareInfo(array $info): array + protected function prepareInfo(?string $view = null, array $viewData = [], array $license = []): array { - if (empty($info)) { - return $info; - } + $info = []; - foreach ($info['license'] as $key => $value) { - if (empty($value)) { - unset($info['license'][$key]); - } - } + $license = array_filter($license); - if (empty($info['license'])) { - unset($info['license']); + if (!empty($license)) { + $info['license'] = $license; } - if (!empty($info['description'])) { - $info['description'] = view($info['description'])->render(); + if (!empty($view)) { + $info['description'] = view($view, $viewData)->render(); } - - return $info; + + return array_merge($this->config['info'], $info); } protected function getOpenAPIFileContent(string $filePath): array diff --git a/tests/AutoDocControllerTest.php b/tests/AutoDocControllerTest.php index ae21d3e1..cf9141d8 100644 --- a/tests/AutoDocControllerTest.php +++ b/tests/AutoDocControllerTest.php @@ -4,11 +4,9 @@ use Illuminate\Http\Response; use phpmock\phpunit\PHPMock; -use RonasIT\Support\Traits\MockTrait; class AutoDocControllerTest extends TestCase { - use MockTrait; use PHPMock; protected static array $documentation; diff --git a/tests/LocalDriverTest.php b/tests/LocalDriverTest.php index 07c183b1..bd599fcd 100755 --- a/tests/LocalDriverTest.php +++ b/tests/LocalDriverTest.php @@ -3,7 +3,7 @@ namespace RonasIT\AutoDoc\Tests; use RonasIT\AutoDoc\Drivers\LocalDriver; -use Illuminate\Contracts\Filesystem\FileNotFoundException; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; use RonasIT\AutoDoc\Exceptions\MissedProductionFilePathException; class LocalDriverTest extends TestCase @@ -126,7 +126,7 @@ public function testGetDocumentation() public function testGetDocumentationFileNotExists() { - $this->expectException(FileNotFoundException::class); + $this->assertExceptionThrew(FileNotFoundException::class, 'Documentation file not found not_exists_file'); config(['auto-doc.drivers.local.production_path' => 'not_exists_file']); diff --git a/tests/RemoteDriverTest.php b/tests/RemoteDriverTest.php index 2acea917..374ec6ca 100755 --- a/tests/RemoteDriverTest.php +++ b/tests/RemoteDriverTest.php @@ -4,13 +4,10 @@ use RonasIT\AutoDoc\Drivers\RemoteDriver; use RonasIT\AutoDoc\Exceptions\MissedRemoteDocumentationUrlException; -use Illuminate\Contracts\Filesystem\FileNotFoundException; -use RonasIT\Support\Traits\MockTrait; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; class RemoteDriverTest extends TestCase { - use MockTrait; - protected static array $tmpData; protected static RemoteDriver $remoteDriverClass; protected static string $tmpDocumentationFilePath; @@ -151,7 +148,7 @@ public function testGetDocumentation() public function testGetDocumentationNoFile() { - $this->expectException(FileNotFoundException::class); + $this->assertExceptionThrew(FileNotFoundException::class, 'Documentation file not found '); config(['auto-doc.drivers.remote.key' => 'mocked_key']); config(['auto-doc.drivers.remote.url' => 'mocked_url']); diff --git a/tests/StorageDriverTest.php b/tests/StorageDriverTest.php index 0453b917..1472cd7e 100755 --- a/tests/StorageDriverTest.php +++ b/tests/StorageDriverTest.php @@ -2,7 +2,7 @@ namespace RonasIT\AutoDoc\Tests; -use Illuminate\Contracts\Filesystem\FileNotFoundException; +use RonasIT\AutoDoc\Exceptions\FileNotFoundException; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Facades\Storage; use RonasIT\AutoDoc\Drivers\StorageDriver; @@ -120,7 +120,7 @@ public function testGetDocumentation() public function testGetDocumentationFileNotExists() { - $this->expectException(FileNotFoundException::class); + $this->assertExceptionThrew(FileNotFoundException::class, 'Documentation file not found documentation.json'); self::$storageDriverClass->getDocumentation(); } diff --git a/tests/SwaggerServiceTest.php b/tests/SwaggerServiceTest.php index 51ed48f4..bd6bc03d 100644 --- a/tests/SwaggerServiceTest.php +++ b/tests/SwaggerServiceTest.php @@ -7,20 +7,6 @@ use RonasIT\AutoDoc\Exceptions\EmptyContactEmailException; use RonasIT\AutoDoc\Exceptions\InvalidDriverClassException; use RonasIT\AutoDoc\Exceptions\LegacyConfigException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\DuplicateFieldException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\DuplicateParamException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\DuplicatePathPlaceholderException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\InvalidFieldValueException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\InvalidPathException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\InvalidStatusCodeException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\InvalidSwaggerSpecException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\InvalidSwaggerVersionException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingExternalRefException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingFieldException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingLocalRefException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingPathParamException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingPathPlaceholderException; -use RonasIT\AutoDoc\Exceptions\SpecValidation\MissingRefFileException; use RonasIT\AutoDoc\Exceptions\SwaggerDriverClassNotFoundException; use RonasIT\AutoDoc\Exceptions\UnsupportedDocumentationViewerException; use RonasIT\AutoDoc\Exceptions\WrongSecurityConfigException; @@ -90,216 +76,151 @@ public static function getConstructorInvalidTmpData(): array return [ [ 'tmpDoc' => 'documentation/invalid_version', - 'exception' => InvalidSwaggerVersionException::class, - 'exceptionMessage' => "Unrecognized Swagger version '1.0'. Expected 3.1.0.", + 'fixture' => 'invalid_version.html', ], [ 'tmpDoc' => 'documentation/invalid_format__array_parameter__no_items', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. paths./users.post.parameters.0 is an " - . "array, so it must include an 'items' field.", + 'fixture' => 'invalid_format_array_parameter_no_items.html', ], [ 'tmpDoc' => 'documentation/invalid_format__array_response_body__no_items', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. paths./users.get.responses.200.schema is an array, " - . "so it must include an 'items' field.", + 'fixture' => 'invalid_format_array_response_body_no_items.html', ], [ 'tmpDoc' => 'documentation/invalid_format__array_response_header__no_items', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. paths./users.get.responses.default.headers." - . "Last-Modified is an array, so it must include an 'items' field.", + 'fixture' => 'invalid_format_array_response_header_no_items.html', ], [ 'tmpDoc' => 'documentation/invalid_format__body_and_form_params', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}.post' " - . "has body and formData parameters. Only one or the other is allowed.", + 'fixture' => 'invalid_format_body_and_form_params.html', ], [ 'tmpDoc' => 'documentation/invalid_format__duplicate_header_params', - 'exception' => DuplicateParamException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}.get' " - . "has multiple in:header parameters with name:foo.", + 'fixture' => 'invalid_format_duplicate_header_params.html', ], [ 'tmpDoc' => 'documentation/invalid_format__duplicate_path_params', - 'exception' => DuplicateParamException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}.get' has " - . "multiple in:path parameters with name:username", + 'fixture' => 'invalid_format_duplicate_path_params.html', ], [ 'tmpDoc' => 'documentation/invalid_format__duplicate_path_placeholders', - 'exception' => DuplicatePathPlaceholderException::class, - 'exceptionMessage' => "Validation failed. Path '/users/{username}/profile/{username}/image/{img_id}' " - . "has multiple path placeholders with name: username.", + 'fixture' => 'invalid_format_duplicate_path_placeholders.html', ], [ 'tmpDoc' => 'documentation/invalid_format__duplicate_operation_id', - 'exception' => DuplicateFieldException::class, - 'exceptionMessage' => "Validation failed. Found multiple fields 'paths.*.*.operationId' " - . "with values: addPet.", + 'fixture' => 'invalid_format_duplicate_operation_id.html', ], [ 'tmpDoc' => 'documentation/invalid_format__duplicate_tag', - 'exception' => DuplicateFieldException::class, - 'exceptionMessage' => "Validation failed. Found multiple fields 'tags.*.name' with values: user.", + 'fixture' => 'invalid_format_duplicate_tag.html', ], [ 'tmpDoc' => 'documentation/invalid_format__file_invalid_consumes', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}/profile/image.post' " - . "has body and formData parameters. Only one or the other is allowed.", + 'fixture' => 'invalid_format_file_invalid_consumes.html', ], [ 'tmpDoc' => 'documentation/invalid_format__file_no_consumes', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}/profile/image.post' " - . "has body and formData parameters. Only one or the other is allowed.", + 'fixture' => 'invalid_format_file_no_consumes.html', ], [ 'tmpDoc' => 'documentation/invalid_format__multiple_body_params', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}.get' has 2 body " - . "parameters. Only one is allowed.", + 'fixture' => 'invalid_format_multiple_body_params.html', ], [ 'tmpDoc' => 'documentation/invalid_format__no_path_params', - 'exception' => MissingPathParamException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}/{foo}.get' has " - . "no params for placeholders: username, foo.", + 'fixture' => 'invalid_format_no_path_params.html', ], [ 'tmpDoc' => 'documentation/invalid_format__path_param_no_placeholder', - 'exception' => MissingPathPlaceholderException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{username}.post' has no " - . "placeholders for params: foo.", + 'fixture' => 'invalid_format_path_param_no_placeholder.html', ], [ 'tmpDoc' => 'documentation/invalid_format__invalid_value__path', - 'exception' => InvalidPathException::class, - 'exceptionMessage' => "Validation failed. Incorrect 'paths.users'. Paths should only have path " - . "names that starts with `/`.", + 'fixture' => 'invalid_format_invalid_value_path.html', ], [ 'tmpDoc' => 'documentation/invalid_format__invalid_value__status_code', - 'exception' => InvalidStatusCodeException::class, - 'exceptionMessage' => "Validation failed. Operation at 'paths./users.get.responses.8888' should " - . "only have three-digit status codes, `default`, and vendor extensions (`x-*`) as properties.", + 'fixture' => 'invalid_format_invalid_value_status_code.html', ], [ 'tmpDoc' => 'documentation/invalid_format__invalid_value__parameter_in', - 'exception' => InvalidFieldValueException::class, - 'exceptionMessage' => "Validation failed. Field 'paths./auth/login.post.parameters.0.in' " - . "has an invalid value: invalid_in. Allowed values: body, formData, query, path, header.", + 'fixture' => 'invalid_format_invalid_value_parameter_in.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__paths', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. '' should have required fields: paths.", + 'fixture' => 'invalid_format_missing_field_paths.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__operation_responses', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'paths./auth/login.post' should have required " - . "fields: responses.", + 'fixture' => 'invalid_format_missing_field_operation_responses.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__parameter_in', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'paths./auth/login.post.parameters.0' should " - . "have required fields: in.", + 'fixture' => 'invalid_format_missing_field_parameter_in.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__response_description', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'paths./auth/login.post.responses.200' should " - . "have required fields: description.", + 'fixture' => 'invalid_format_missing_field_response_description.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__definition_type', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'components.schemas.authloginObject' should have " - . "required fields: type.", + 'fixture' => 'invalid_format_missing_field_definition_type.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__info_version', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'info' should have required fields: version.", + 'fixture' => 'invalid_format_missing_field_info_version.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__items_type', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'paths./pet/findByStatus.get.parameters.0.schema.items' " - . "should have required fields: type.", + 'fixture' => 'invalid_format_missing_field_items_type.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__header_type', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'paths./user/login.get.responses.200.headers.X-Rate-Limit' " - . "should have required fields: type.", + 'fixture' => 'invalid_format_missing_field_header_type.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_field__tag_name', - 'exception' => MissingFieldException::class, - 'exceptionMessage' => "Validation failed. 'tags.0' should have required fields: name.", + 'fixture' => 'invalid_format_missing_field_tag_name.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_local_ref', - 'exception' => MissingLocalRefException::class, - 'exceptionMessage' => "Validation failed. Ref 'loginObject' is used in \$ref but not defined " - . "in 'definitions' field.", + 'fixture' => 'invalid_format_missing_local_ref.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_external_ref', - 'exception' => MissingExternalRefException::class, - 'exceptionMessage' => "Validation failed. Ref 'authloginObject' is used in \$ref but not defined " - . "in 'tests/fixtures/SwaggerServiceTest/documentation/with_definitions.json' file.", + 'fixture' => 'invalid_format_missing_external_ref.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_ref_file', - 'exception' => MissingRefFileException::class, - 'exceptionMessage' => "Validation failed. Filename 'invalid-filename.json' is used in \$ref but " - . "file doesn't exist.", + 'fixture' => 'invalid_format_missing_ref_file.html', ], [ 'tmpDoc' => 'documentation/invalid_format__invalid_schema_type', - 'exception' => InvalidFieldValueException::class, - 'exceptionMessage' => "Validation failed. Field 'paths./users.get.responses.200.schema.type' " - . "has an invalid value: something. Allowed values: array, boolean, integer, number, " - . "string, object, null, undefined, file.", + 'fixture' => 'invalid_format_invalid_schema_type.html', ], [ 'tmpDoc' => 'documentation/invalid_format__missing_path_parameter', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Path parameters cannot be optional. " - . "Set required=true for the 'username' parameters at operation 'paths./users.get'.", + 'fixture' => 'invalid_format_missing_path_parameter.html', ], [ 'tmpDoc' => 'documentation/invalid_format__security_definition__type', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Field 'securityDefinitions.0.type' has an invalid value: invalid. Allowed values: basic, apiKey, oauth2.", + 'fixture' => 'invalid_format_security_definition_type.html', ], [ 'tmpDoc' => 'documentation/invalid_format__security_definition__flow', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Field 'securityDefinitions.0.flow' has an invalid value: invalid. Allowed values: implicit, password, application, accessCode.", + 'fixture' => 'invalid_format_security_definition_flow.html', ], [ 'tmpDoc' => 'documentation/invalid_format__security_definition__in', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Field 'securityDefinitions.0.in' has an invalid value: invalid. Allowed values: query, header.", + 'fixture' => 'invalid_format_security_definition_in.html', ], [ 'tmpDoc' => 'documentation/invalid_format__request_body__invalid_content', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. Operation 'paths./users/{id}.post' has invalid content types: image/png.", + 'fixture' => 'invalid_format_request_body_invalid_content.html', ], [ 'tmpDoc' => 'documentation/invalid_format__response__invalid_items', - 'exception' => InvalidSwaggerSpecException::class, - 'exceptionMessage' => "Validation failed. 'paths./users/{id}.post.responses.200.schema.items' should have required fields: type.", + 'fixture' => 'invalid_format_response_invalid_items.html', ], ]; } @@ -307,15 +228,13 @@ public static function getConstructorInvalidTmpData(): array #[DataProvider('getConstructorInvalidTmpData')] public function testGetDocFileContentInvalidTmpData( string $tmpDoc, - string $exception, - string $exceptionMessage, + string $fixture, ) { $this->mockDriverGetDocumentation($this->getJsonFixture($tmpDoc)); - $this->expectException($exception); - $this->expectExceptionMessage($exceptionMessage); + $content = app(SwaggerService::class)->getDocFileContent(); - app(SwaggerService::class)->getDocFileContent(); + $this->assertEqualsFixture($fixture, $content['info']['description']); } public function testEmptyContactEmail() diff --git a/tests/TestCase.php b/tests/TestCase.php index 91706921..13242929 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -13,9 +13,12 @@ use RonasIT\AutoDoc\Tests\Support\Mock\TestController; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; use Symfony\Component\HttpFoundation\Response; +use RonasIT\Support\Traits\TestingTrait; class TestCase extends BaseTest { + use TestingTrait; + protected bool $globalExportMode = false; public function setUp(): void diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_array_parameter_no_items.html b/tests/fixtures/SwaggerServiceTest/invalid_format_array_parameter_no_items.html new file mode 100644 index 00000000..5ee5a195 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_array_parameter_no_items.html @@ -0,0 +1 @@ +Validation failed. paths./users.post.parameters.0 is an array, so it must include an 'items' field. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_body_no_items.html b/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_body_no_items.html new file mode 100644 index 00000000..daf4fee1 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_body_no_items.html @@ -0,0 +1 @@ +Validation failed. paths./users.get.responses.200.schema is an array, so it must include an 'items' field. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_header_no_items.html b/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_header_no_items.html new file mode 100644 index 00000000..caf830c0 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_array_response_header_no_items.html @@ -0,0 +1 @@ +Validation failed. paths./users.get.responses.default.headers.Last-Modified is an array, so it must include an 'items' field. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_body_and_form_params.html b/tests/fixtures/SwaggerServiceTest/invalid_format_body_and_form_params.html new file mode 100644 index 00000000..389e03a0 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_body_and_form_params.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}.post' has body and formData parameters. Only one or the other is allowed. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_header_params.html b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_header_params.html new file mode 100644 index 00000000..0a770041 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_header_params.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}.get' has multiple in:header parameters with name:foo. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_operation_id.html b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_operation_id.html new file mode 100644 index 00000000..25dbb9bc --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_operation_id.html @@ -0,0 +1 @@ +Validation failed. Found multiple fields 'paths.*.*.operationId' with values: addPet. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_params.html b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_params.html new file mode 100644 index 00000000..a03ed69e --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_params.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}.get' has multiple in:path parameters with name:username. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_placeholders.html b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_placeholders.html new file mode 100644 index 00000000..5e443501 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_path_placeholders.html @@ -0,0 +1 @@ +Validation failed. Path '/users/{username}/profile/{username}/image/{img_id}' has multiple path placeholders with name: username. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_tag.html b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_tag.html new file mode 100644 index 00000000..99344580 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_duplicate_tag.html @@ -0,0 +1 @@ +Validation failed. Found multiple fields 'tags.*.name' with values: user. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_file_invalid_consumes.html b/tests/fixtures/SwaggerServiceTest/invalid_format_file_invalid_consumes.html new file mode 100644 index 00000000..22b966e5 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_file_invalid_consumes.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}/profile/image.post' has body and formData parameters. Only one or the other is allowed. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_file_no_consumes.html b/tests/fixtures/SwaggerServiceTest/invalid_format_file_no_consumes.html new file mode 100644 index 00000000..22b966e5 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_file_no_consumes.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}/profile/image.post' has body and formData parameters. Only one or the other is allowed. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_schema_type.html b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_schema_type.html new file mode 100644 index 00000000..a6c49ec3 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_schema_type.html @@ -0,0 +1 @@ +Validation failed. Field 'paths./users.get.responses.200.schema.type' has an invalid value: something. Allowed values: array, boolean, integer, number, string, object, null, undefined, file. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_parameter_in.html b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_parameter_in.html new file mode 100644 index 00000000..68a11aac --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_parameter_in.html @@ -0,0 +1 @@ +Validation failed. Field 'paths./auth/login.post.parameters.0.in' has an invalid value: invalid_in. Allowed values: body, formData, query, path, header. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_path.html b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_path.html new file mode 100644 index 00000000..96de275c --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_path.html @@ -0,0 +1 @@ +Validation failed. Incorrect 'paths.users'. Paths should only have path names that starts with `/`. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_status_code.html b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_status_code.html new file mode 100644 index 00000000..07d68cac --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_invalid_value_status_code.html @@ -0,0 +1 @@ +Validation failed. Operation at 'paths./users.get.responses.8888' should only have three-digit status codes, `default`, and vendor extensions (`x-*`) as properties. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_external_ref.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_external_ref.html new file mode 100644 index 00000000..2eace1cf --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_external_ref.html @@ -0,0 +1 @@ +Validation failed. Ref 'authloginObject' is used in $ref but not defined in 'tests/fixtures/SwaggerServiceTest/documentation/with_definitions.json' file. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_definition_type.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_definition_type.html new file mode 100644 index 00000000..e2bd233c --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_definition_type.html @@ -0,0 +1 @@ +Validation failed. 'components.schemas.authloginObject' should have required fields: type. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_header_type.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_header_type.html new file mode 100644 index 00000000..28a5c4ff --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_header_type.html @@ -0,0 +1 @@ +Validation failed. 'paths./user/login.get.responses.200.headers.X-Rate-Limit' should have required fields: type. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_info_version.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_info_version.html new file mode 100644 index 00000000..dc3dac19 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_info_version.html @@ -0,0 +1 @@ +Validation failed. 'info' should have required fields: version. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_items_type.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_items_type.html new file mode 100644 index 00000000..0e470070 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_items_type.html @@ -0,0 +1 @@ +Validation failed. 'paths./pet/findByStatus.get.parameters.0.schema.items' should have required fields: type. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_operation_responses.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_operation_responses.html new file mode 100644 index 00000000..5ebd060b --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_operation_responses.html @@ -0,0 +1 @@ +Validation failed. 'paths./auth/login.post' should have required fields: responses. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_parameter_in.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_parameter_in.html new file mode 100644 index 00000000..996315fa --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_parameter_in.html @@ -0,0 +1 @@ +Validation failed. 'paths./auth/login.post.parameters.0' should have required fields: in. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_paths.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_paths.html new file mode 100644 index 00000000..c68f537e --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_paths.html @@ -0,0 +1 @@ +Validation failed. '' should have required fields: paths. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_response_description.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_response_description.html new file mode 100644 index 00000000..c272c3d5 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_response_description.html @@ -0,0 +1 @@ +Validation failed. 'paths./auth/login.post.responses.200' should have required fields: description. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_tag_name.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_tag_name.html new file mode 100644 index 00000000..54dece06 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_field_tag_name.html @@ -0,0 +1 @@ +Validation failed. 'tags.0' should have required fields: name. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_local_ref.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_local_ref.html new file mode 100644 index 00000000..13d8fc9a --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_local_ref.html @@ -0,0 +1 @@ +Validation failed. Ref 'loginObject' is used in $ref but not defined in 'definitions' field. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_path_parameter.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_path_parameter.html new file mode 100644 index 00000000..46a71416 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_path_parameter.html @@ -0,0 +1 @@ +Validation failed. Path parameters cannot be optional. Set required=true for the 'username' parameters at operation 'paths./users.get'. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_missing_ref_file.html b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_ref_file.html new file mode 100644 index 00000000..a7794cf8 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_missing_ref_file.html @@ -0,0 +1 @@ +Validation failed. Filename 'invalid-filename.json' is used in $ref but file doesn't exist. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_multiple_body_params.html b/tests/fixtures/SwaggerServiceTest/invalid_format_multiple_body_params.html new file mode 100644 index 00000000..3eaab7d4 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_multiple_body_params.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}.get' has 2 body parameters. Only one is allowed. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_no_path_params.html b/tests/fixtures/SwaggerServiceTest/invalid_format_no_path_params.html new file mode 100644 index 00000000..543b42ff --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_no_path_params.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}/{foo}.get' has no params for placeholders: username, foo. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_path_param_no_placeholder.html b/tests/fixtures/SwaggerServiceTest/invalid_format_path_param_no_placeholder.html new file mode 100644 index 00000000..1e350309 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_path_param_no_placeholder.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{username}.post' has no placeholders for params: foo. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_request_body_invalid_content.html b/tests/fixtures/SwaggerServiceTest/invalid_format_request_body_invalid_content.html new file mode 100644 index 00000000..0884fddc --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_request_body_invalid_content.html @@ -0,0 +1 @@ +Validation failed. Operation 'paths./users/{id}.post' has invalid content types: image/png. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_response_invalid_items.html b/tests/fixtures/SwaggerServiceTest/invalid_format_response_invalid_items.html new file mode 100644 index 00000000..8e42aa1f --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_response_invalid_items.html @@ -0,0 +1 @@ +Validation failed. 'paths./users/{id}.post.responses.200.schema.items' should have required fields: type. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_flow.html b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_flow.html new file mode 100644 index 00000000..3e0fc9b6 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_flow.html @@ -0,0 +1 @@ +Validation failed. Field 'securityDefinitions.0.flow' has an invalid value: invalid. Allowed values: implicit, password, application, accessCode. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_in.html b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_in.html new file mode 100644 index 00000000..241f6946 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_in.html @@ -0,0 +1 @@ +Validation failed. Field 'securityDefinitions.0.in' has an invalid value: invalid. Allowed values: query, header. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_type.html b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_type.html new file mode 100644 index 00000000..33a2c0a9 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_format_security_definition_type.html @@ -0,0 +1 @@ +Validation failed. Field 'securityDefinitions.0.type' has an invalid value: invalid. Allowed values: basic, apiKey, oauth2. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/invalid_version.html b/tests/fixtures/SwaggerServiceTest/invalid_version.html new file mode 100644 index 00000000..581fef92 --- /dev/null +++ b/tests/fixtures/SwaggerServiceTest/invalid_version.html @@ -0,0 +1 @@ +Validation failed. Unrecognized Swagger version '1.0'. Expected 3.1.0. \ No newline at end of file diff --git a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_jwt.json b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_jwt.json index 2c994d33..82907a7f 100644 --- a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_jwt.json +++ b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_jwt.json @@ -16,6 +16,10 @@ "termsOfService": "", "contact": { "email": "your@mail.com" + }, + "license": { + "name": "", + "url": "" } }, "securityDefinitions": { diff --git a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_laravel.json b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_laravel.json index 53b5b5a3..010bd96e 100644 --- a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_laravel.json +++ b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_laravel.json @@ -16,6 +16,10 @@ "termsOfService": "", "contact": { "email": "your@mail.com" + }, + "license": { + "name": "", + "url": "" } }, "securityDefinitions": { diff --git a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_query.json b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_query.json index 8b95d9c9..026c3087 100644 --- a/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_query.json +++ b/tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_query.json @@ -16,6 +16,10 @@ "termsOfService": "", "contact": { "email": "your@mail.com" + }, + "license": { + "name": "", + "url": "" } }, "securityDefinitions": {